1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 **********************************************************/
25
26 #include "util/u_bitmask.h"
27 #include "util/u_debug.h"
28 #include "pipe/p_defines.h"
29 #include "util/u_memory.h"
30 #include "draw/draw_context.h"
31
32 #include "svga_context.h"
33 #include "svga_screen.h"
34 #include "svga_state.h"
35 #include "svga_draw.h"
36 #include "svga_cmd.h"
37 #include "svga_hw_reg.h"
38
39 /* This is just enough to decide whether we need to use the draw
40 * module (swtnl) or not.
41 */
42 static const struct svga_tracked_state *need_swtnl_state[] =
43 {
44 &svga_update_need_swvfetch,
45 &svga_update_need_pipeline,
46 &svga_update_need_swtnl,
47 NULL
48 };
49
50
51 /* Atoms to update hardware state prior to emitting a clear or draw
52 * packet.
53 */
54 static const struct svga_tracked_state *hw_clear_state[] =
55 {
56 &svga_hw_scissor,
57 &svga_hw_viewport,
58 &svga_hw_framebuffer,
59 NULL
60 };
61
62
63 /**
64 * Atoms to update hardware state prior to emitting a draw packet
65 * for VGPU9 device.
66 */
67 static const struct svga_tracked_state *hw_draw_state_vgpu9[] =
68 {
69 &svga_hw_fs,
70 &svga_hw_vs,
71 &svga_hw_rss,
72 &svga_hw_tss,
73 &svga_hw_tss_binding,
74 &svga_hw_clip_planes,
75 &svga_hw_vdecl,
76 &svga_hw_fs_constants,
77 &svga_hw_vs_constants,
78 NULL
79 };
80
81
82 /**
83 * Atoms to update hardware state prior to emitting a draw packet
84 * for VGPU10 device.
85 * Geometry Shader is new to VGPU10.
86 * TSS and TSS bindings are replaced by sampler and sampler bindings.
87 */
88 static const struct svga_tracked_state *hw_draw_state_vgpu10[] =
89 {
90 &svga_need_tgsi_transform,
91 &svga_hw_fs,
92 &svga_hw_gs,
93 &svga_hw_vs,
94 &svga_hw_rss,
95 &svga_hw_sampler,
96 &svga_hw_sampler_bindings,
97 &svga_hw_clip_planes,
98 &svga_hw_vdecl,
99 &svga_hw_fs_constants,
100 &svga_hw_fs_constbufs,
101 &svga_hw_gs_constants,
102 &svga_hw_gs_constbufs,
103 &svga_hw_vs_constants,
104 &svga_hw_vs_constbufs,
105 NULL
106 };
107
108
109 /**
110 * Atoms to update hardware state prior to emitting a draw packet
111 * for SM5 device.
112 * TCS and TES Shaders are new to SM5 device.
113 */
114 static const struct svga_tracked_state *hw_draw_state_sm5[] =
115 {
116 &svga_need_tgsi_transform,
117 &svga_hw_fs,
118 &svga_hw_gs,
119 &svga_hw_tes,
120 &svga_hw_tcs,
121 &svga_hw_vs,
122 &svga_hw_rss,
123 &svga_hw_sampler,
124 &svga_hw_sampler_bindings,
125 &svga_hw_clip_planes,
126 &svga_hw_vdecl,
127 &svga_hw_fs_constants,
128 &svga_hw_fs_constbufs,
129 &svga_hw_gs_constants,
130 &svga_hw_gs_constbufs,
131 &svga_hw_tes_constants,
132 &svga_hw_tes_constbufs,
133 &svga_hw_tcs_constants,
134 &svga_hw_tcs_constbufs,
135 &svga_hw_vs_constants,
136 &svga_hw_vs_constbufs,
137 NULL
138 };
139
140
141 /**
142 * Atoms to update hardware state prior to emitting a draw packet
143 * for GL43 device which includes uav update.
144 */
145 static const struct svga_tracked_state *hw_draw_state_gl43[] =
146 {
147 &svga_need_tgsi_transform,
148 &svga_hw_uav,
149 &svga_need_rawbuf_srv,
150 &svga_hw_fs,
151 &svga_hw_gs,
152 &svga_hw_tes,
153 &svga_hw_tcs,
154 &svga_hw_vs,
155 &svga_hw_rss,
156 &svga_hw_sampler,
157 &svga_hw_sampler_bindings,
158 &svga_hw_clip_planes,
159 &svga_hw_vdecl,
160 &svga_hw_fs_constants,
161 &svga_hw_fs_constbufs,
162 &svga_hw_gs_constants,
163 &svga_hw_gs_constbufs,
164 &svga_hw_tes_constants,
165 &svga_hw_tes_constbufs,
166 &svga_hw_tcs_constants,
167 &svga_hw_tcs_constbufs,
168 &svga_hw_vs_constants,
169 &svga_hw_vs_constbufs,
170 NULL
171 };
172
173
174 static const struct svga_tracked_state *swtnl_draw_state[] =
175 {
176 &svga_update_swtnl_draw,
177 &svga_update_swtnl_vdecl,
178 NULL
179 };
180
181
182 /* Flattens the graph of state dependencies. Could swap the positions
183 * of hw_clear_state and need_swtnl_state without breaking anything.
184 */
185 static const struct svga_tracked_state **state_levels[] =
186 {
187 need_swtnl_state,
188 hw_clear_state,
189 NULL, /* hw_draw_state, to be set to the right version */
190 swtnl_draw_state
191 };
192
193
194 static uint64_t
check_state(uint64_t a,uint64_t b)195 check_state(uint64_t a, uint64_t b)
196 {
197 return (a & b);
198 }
199
200 static void
accumulate_state(uint64_t * a,uint64_t b)201 accumulate_state(uint64_t *a, uint64_t b)
202 {
203 *a |= b;
204 }
205
206
207 static void
xor_states(uint64_t * result,uint64_t a,uint64_t b)208 xor_states(uint64_t *result, uint64_t a, uint64_t b)
209 {
210 *result = a ^ b;
211 }
212
213
214 static enum pipe_error
update_state(struct svga_context * svga,const struct svga_tracked_state * atoms[],uint64_t * state)215 update_state(struct svga_context *svga,
216 const struct svga_tracked_state *atoms[],
217 uint64_t *state)
218 {
219 #ifdef DEBUG
220 boolean debug = TRUE;
221 #else
222 boolean debug = FALSE;
223 #endif
224 enum pipe_error ret = PIPE_OK;
225 unsigned i;
226
227 ret = svga_hwtnl_flush( svga->hwtnl );
228 if (ret != PIPE_OK)
229 return ret;
230
231 if (debug) {
232 /* Debug version which enforces various sanity checks on the
233 * state flags which are generated and checked to help ensure
234 * state atoms are ordered correctly in the list.
235 */
236 uint64_t examined, prev;
237
238 examined = 0;
239 prev = *state;
240
241 for (i = 0; atoms[i] != NULL; i++) {
242 uint64_t generated;
243
244 assert(atoms[i]->dirty);
245 assert(atoms[i]->update);
246
247 if (check_state(*state, atoms[i]->dirty)) {
248 if (0)
249 debug_printf("update: %s\n", atoms[i]->name);
250 ret = atoms[i]->update( svga, *state );
251 if (ret != PIPE_OK)
252 return ret;
253 }
254
255 /* generated = (prev ^ state)
256 * if (examined & generated)
257 * fail;
258 */
259 xor_states(&generated, prev, *state);
260 if (check_state(examined, generated)) {
261 debug_printf("state atom %s generated state already examined\n",
262 atoms[i]->name);
263 assert(0);
264 }
265
266 prev = *state;
267 accumulate_state(&examined, atoms[i]->dirty);
268 }
269 }
270 else {
271 for (i = 0; atoms[i] != NULL; i++) {
272 if (check_state(*state, atoms[i]->dirty)) {
273 ret = atoms[i]->update( svga, *state );
274 if (ret != PIPE_OK)
275 return ret;
276 }
277 }
278 }
279
280 return PIPE_OK;
281 }
282
283
284 enum pipe_error
svga_update_state(struct svga_context * svga,unsigned max_level)285 svga_update_state(struct svga_context *svga, unsigned max_level)
286 {
287 struct svga_screen *screen = svga_screen(svga->pipe.screen);
288 enum pipe_error ret = PIPE_OK;
289 unsigned i;
290
291 SVGA_STATS_TIME_PUSH(screen->sws, SVGA_STATS_TIME_UPDATESTATE);
292
293 /* Check for updates to bound textures. This can't be done in an
294 * atom as there is no flag which could provoke this test, and we
295 * cannot create one.
296 */
297 if (svga->state.texture_timestamp != screen->texture_timestamp) {
298 svga->state.texture_timestamp = screen->texture_timestamp;
299 svga->dirty |= SVGA_NEW_TEXTURE;
300 }
301
302 for (i = 0; i <= max_level; i++) {
303 svga->dirty |= svga->state.dirty[i];
304
305 if (svga->dirty) {
306 ret = update_state( svga,
307 state_levels[i],
308 &svga->dirty );
309 if (ret != PIPE_OK)
310 goto done;
311
312 svga->state.dirty[i] = 0;
313 }
314 }
315
316 for (; i < SVGA_STATE_MAX; i++)
317 svga->state.dirty[i] |= svga->dirty;
318
319 svga->dirty = 0;
320
321 svga->hud.num_validations++;
322
323 done:
324 SVGA_STATS_TIME_POP(screen->sws);
325 return ret;
326 }
327
328
329 /**
330 * Update state. If the first attempt fails, flush the command buffer
331 * and retry.
332 * \return true if success, false if second attempt fails.
333 */
334 bool
svga_update_state_retry(struct svga_context * svga,unsigned max_level)335 svga_update_state_retry(struct svga_context *svga, unsigned max_level)
336 {
337 enum pipe_error ret;
338
339 SVGA_RETRY_OOM(svga, ret, svga_update_state( svga, max_level ));
340
341 return ret == PIPE_OK;
342 }
343
344
345 #define EMIT_RS(_rs, _count, _name, _value) \
346 do { \
347 _rs[_count].state = _name; \
348 _rs[_count].uintValue = _value; \
349 _count++; \
350 } while (0)
351
352
353 /* Setup any hardware state which will be constant through the life of
354 * a context.
355 */
356 enum pipe_error
svga_emit_initial_state(struct svga_context * svga)357 svga_emit_initial_state(struct svga_context *svga)
358 {
359 if (svga_have_vgpu10(svga)) {
360 SVGA3dRasterizerStateId id = util_bitmask_add(svga->rast_object_id_bm);
361 enum pipe_error ret;
362
363 /* XXX preliminary code */
364 ret = SVGA3D_vgpu10_DefineRasterizerState(svga->swc,
365 id,
366 SVGA3D_FILLMODE_FILL,
367 SVGA3D_CULL_NONE,
368 1, /* frontCounterClockwise */
369 0, /* depthBias */
370 0.0f, /* depthBiasClamp */
371 0.0f, /* slopeScaledDepthBiasClamp */
372 0, /* depthClampEnable */
373 0, /* scissorEnable */
374 0, /* multisampleEnable */
375 0, /* aalineEnable */
376 1.0f, /* lineWidth */
377 0, /* lineStippleEnable */
378 0, /* lineStippleFactor */
379 0, /* lineStipplePattern */
380 0); /* provokingVertexLast */
381
382
383 assert(ret == PIPE_OK);
384
385 ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, id);
386 return ret;
387 }
388 else {
389 SVGA3dRenderState *rs;
390 unsigned count = 0;
391 const unsigned COUNT = 2;
392 enum pipe_error ret;
393
394 ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT );
395 if (ret != PIPE_OK)
396 return ret;
397
398 /* Always use D3D style coordinate space as this is the only one
399 * which is implemented on all backends.
400 */
401 EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE,
402 SVGA3D_COORDINATE_LEFTHANDED );
403 EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW );
404
405 assert( COUNT == count );
406 SVGA_FIFOCommitAll( svga->swc );
407
408 return PIPE_OK;
409 }
410 }
411
412
413 void
svga_init_tracked_state(struct svga_context * svga)414 svga_init_tracked_state(struct svga_context *svga)
415 {
416 /* Set the hw_draw_state atom list to the one for the particular gpu version.
417 */
418 state_levels[2] =
419 svga_have_gl43(svga) ? hw_draw_state_gl43 :
420 (svga_have_sm5(svga) ? hw_draw_state_sm5 :
421 ((svga_have_vgpu10(svga) ? hw_draw_state_vgpu10 :
422 hw_draw_state_vgpu9)));
423 }
424
425
426 static const struct svga_tracked_state *compute_state[] =
427 {
428 &svga_hw_cs_uav,
429 &svga_hw_cs_sampler,
430 &svga_hw_cs_sampler_bindings,
431 &svga_hw_cs,
432 &svga_hw_cs_constants,
433 &svga_hw_cs_constbufs,
434 NULL
435 };
436
437 /**
438 * Update compute state.
439 * If the first attempt fails, flush the command buffer and retry.
440 * \return true if success, false if second attempt fails.
441 */
442 bool
svga_update_compute_state(struct svga_context * svga)443 svga_update_compute_state(struct svga_context *svga)
444 {
445 enum pipe_error ret = PIPE_OK;
446 uint64_t compute_dirty = svga->dirty;
447
448 if (compute_dirty) {
449 SVGA_RETRY_OOM(svga, ret, update_state(svga, compute_state,
450 &compute_dirty));
451
452 /* Set the dirty flag to the remaining dirty bits which are
453 * not processed in the compute pipeline.
454 */
455 svga->dirty = compute_dirty;
456 }
457
458 return ret == PIPE_OK;
459 }
460