• 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 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