• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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