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 static const struct svga_tracked_state *swtnl_draw_state[] =
142 {
143 &svga_update_swtnl_draw,
144 &svga_update_swtnl_vdecl,
145 NULL
146 };
147
148
149 /* Flattens the graph of state dependencies. Could swap the positions
150 * of hw_clear_state and need_swtnl_state without breaking anything.
151 */
152 static const struct svga_tracked_state **state_levels[] =
153 {
154 need_swtnl_state,
155 hw_clear_state,
156 NULL, /* hw_draw_state, to be set to the right version */
157 swtnl_draw_state
158 };
159
160
161 static uint64_t
check_state(uint64_t a,uint64_t b)162 check_state(uint64_t a, uint64_t b)
163 {
164 return (a & b);
165 }
166
167 static void
accumulate_state(uint64_t * a,uint64_t b)168 accumulate_state(uint64_t *a, uint64_t b)
169 {
170 *a |= b;
171 }
172
173
174 static void
xor_states(uint64_t * result,uint64_t a,uint64_t b)175 xor_states(uint64_t *result, uint64_t a, uint64_t b)
176 {
177 *result = a ^ b;
178 }
179
180
181 static enum pipe_error
update_state(struct svga_context * svga,const struct svga_tracked_state * atoms[],uint64_t * state)182 update_state(struct svga_context *svga,
183 const struct svga_tracked_state *atoms[],
184 uint64_t *state)
185 {
186 #ifdef DEBUG
187 boolean debug = TRUE;
188 #else
189 boolean debug = FALSE;
190 #endif
191 enum pipe_error ret = PIPE_OK;
192 unsigned i;
193
194 ret = svga_hwtnl_flush( svga->hwtnl );
195 if (ret != PIPE_OK)
196 return ret;
197
198 if (debug) {
199 /* Debug version which enforces various sanity checks on the
200 * state flags which are generated and checked to help ensure
201 * state atoms are ordered correctly in the list.
202 */
203 uint64_t examined, prev;
204
205 examined = 0;
206 prev = *state;
207
208 for (i = 0; atoms[i] != NULL; i++) {
209 uint64_t generated;
210
211 assert(atoms[i]->dirty);
212 assert(atoms[i]->update);
213
214 if (check_state(*state, atoms[i]->dirty)) {
215 if (0)
216 debug_printf("update: %s\n", atoms[i]->name);
217 ret = atoms[i]->update( svga, *state );
218 if (ret != PIPE_OK)
219 return ret;
220 }
221
222 /* generated = (prev ^ state)
223 * if (examined & generated)
224 * fail;
225 */
226 xor_states(&generated, prev, *state);
227 if (check_state(examined, generated)) {
228 debug_printf("state atom %s generated state already examined\n",
229 atoms[i]->name);
230 assert(0);
231 }
232
233 prev = *state;
234 accumulate_state(&examined, atoms[i]->dirty);
235 }
236 }
237 else {
238 for (i = 0; atoms[i] != NULL; i++) {
239 if (check_state(*state, atoms[i]->dirty)) {
240 ret = atoms[i]->update( svga, *state );
241 if (ret != PIPE_OK)
242 return ret;
243 }
244 }
245 }
246
247 return PIPE_OK;
248 }
249
250
251 enum pipe_error
svga_update_state(struct svga_context * svga,unsigned max_level)252 svga_update_state(struct svga_context *svga, unsigned max_level)
253 {
254 struct svga_screen *screen = svga_screen(svga->pipe.screen);
255 enum pipe_error ret = PIPE_OK;
256 unsigned i;
257
258 SVGA_STATS_TIME_PUSH(screen->sws, SVGA_STATS_TIME_UPDATESTATE);
259
260 /* Check for updates to bound textures. This can't be done in an
261 * atom as there is no flag which could provoke this test, and we
262 * cannot create one.
263 */
264 if (svga->state.texture_timestamp != screen->texture_timestamp) {
265 svga->state.texture_timestamp = screen->texture_timestamp;
266 svga->dirty |= SVGA_NEW_TEXTURE;
267 }
268
269 for (i = 0; i <= max_level; i++) {
270 svga->dirty |= svga->state.dirty[i];
271
272 if (svga->dirty) {
273 ret = update_state( svga,
274 state_levels[i],
275 &svga->dirty );
276 if (ret != PIPE_OK)
277 goto done;
278
279 svga->state.dirty[i] = 0;
280 }
281 }
282
283 for (; i < SVGA_STATE_MAX; i++)
284 svga->state.dirty[i] |= svga->dirty;
285
286 svga->dirty = 0;
287
288 svga->hud.num_validations++;
289
290 done:
291 SVGA_STATS_TIME_POP(screen->sws);
292 return ret;
293 }
294
295
296 /**
297 * Update state. If the first attempt fails, flush the command buffer
298 * and retry.
299 * \return true if success, false if second attempt fails.
300 */
301 bool
svga_update_state_retry(struct svga_context * svga,unsigned max_level)302 svga_update_state_retry(struct svga_context *svga, unsigned max_level)
303 {
304 enum pipe_error ret;
305
306 SVGA_RETRY_OOM(svga, ret, svga_update_state( svga, max_level ));
307
308 return ret == PIPE_OK;
309 }
310
311
312
313 #define EMIT_RS(_rs, _count, _name, _value) \
314 do { \
315 _rs[_count].state = _name; \
316 _rs[_count].uintValue = _value; \
317 _count++; \
318 } while (0)
319
320
321 /* Setup any hardware state which will be constant through the life of
322 * a context.
323 */
324 enum pipe_error
svga_emit_initial_state(struct svga_context * svga)325 svga_emit_initial_state(struct svga_context *svga)
326 {
327 if (svga_have_vgpu10(svga)) {
328 SVGA3dRasterizerStateId id = util_bitmask_add(svga->rast_object_id_bm);
329 enum pipe_error ret;
330
331 /* XXX preliminary code */
332 ret = SVGA3D_vgpu10_DefineRasterizerState(svga->swc,
333 id,
334 SVGA3D_FILLMODE_FILL,
335 SVGA3D_CULL_NONE,
336 1, /* frontCounterClockwise */
337 0, /* depthBias */
338 0.0f, /* depthBiasClamp */
339 0.0f, /* slopeScaledDepthBiasClamp */
340 0, /* depthClampEnable */
341 0, /* scissorEnable */
342 0, /* multisampleEnable */
343 0, /* aalineEnable */
344 1.0f, /* lineWidth */
345 0, /* lineStippleEnable */
346 0, /* lineStippleFactor */
347 0, /* lineStipplePattern */
348 0); /* provokingVertexLast */
349
350
351 assert(ret == PIPE_OK);
352
353 ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, id);
354 return ret;
355 }
356 else {
357 SVGA3dRenderState *rs;
358 unsigned count = 0;
359 const unsigned COUNT = 2;
360 enum pipe_error ret;
361
362 ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT );
363 if (ret != PIPE_OK)
364 return ret;
365
366 /* Always use D3D style coordinate space as this is the only one
367 * which is implemented on all backends.
368 */
369 EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE,
370 SVGA3D_COORDINATE_LEFTHANDED );
371 EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW );
372
373 assert( COUNT == count );
374 SVGA_FIFOCommitAll( svga->swc );
375
376 return PIPE_OK;
377 }
378 }
379
380
381 void
svga_init_tracked_state(struct svga_context * svga)382 svga_init_tracked_state(struct svga_context *svga)
383 {
384 /* Set the hw_draw_state atom list to the one for the particular gpu version.
385 */
386 state_levels[2] = svga_have_sm5(svga) ? hw_draw_state_sm5 :
387 (svga_have_vgpu10(svga) ? hw_draw_state_vgpu10 :
388 hw_draw_state_vgpu9);
389 }
390