• 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 /* Atoms to update hardware state prior to emitting a draw packet.
64  */
65 static const struct svga_tracked_state *hw_draw_state[] =
66 {
67    &svga_need_tgsi_transform,
68    &svga_hw_fs,
69    &svga_hw_gs,
70    &svga_hw_vs,
71    &svga_hw_rss,
72    &svga_hw_sampler,           /* VGPU10 */
73    &svga_hw_sampler_bindings,  /* VGPU10 */
74    &svga_hw_tss,               /* pre-VGPU10 */
75    &svga_hw_tss_binding,       /* pre-VGPU10 */
76    &svga_hw_clip_planes,
77    &svga_hw_vdecl,
78    &svga_hw_fs_constants,
79    &svga_hw_gs_constants,
80    &svga_hw_vs_constants,
81    NULL
82 };
83 
84 
85 static const struct svga_tracked_state *swtnl_draw_state[] =
86 {
87    &svga_update_swtnl_draw,
88    &svga_update_swtnl_vdecl,
89    NULL
90 };
91 
92 /* Flattens the graph of state dependencies.  Could swap the positions
93  * of hw_clear_state and need_swtnl_state without breaking anything.
94  */
95 static const struct svga_tracked_state **state_levels[] =
96 {
97    need_swtnl_state,
98    hw_clear_state,
99    hw_draw_state,
100    swtnl_draw_state
101 };
102 
103 
104 
105 static unsigned
check_state(unsigned a,unsigned b)106 check_state(unsigned a, unsigned b)
107 {
108    return (a & b);
109 }
110 
111 static void
accumulate_state(unsigned * a,unsigned b)112 accumulate_state(unsigned *a, unsigned b)
113 {
114    *a |= b;
115 }
116 
117 
118 static void
xor_states(unsigned * result,unsigned a,unsigned b)119 xor_states(unsigned *result, unsigned a, unsigned b)
120 {
121    *result = a ^ b;
122 }
123 
124 
125 static enum pipe_error
update_state(struct svga_context * svga,const struct svga_tracked_state * atoms[],unsigned * state)126 update_state(struct svga_context *svga,
127              const struct svga_tracked_state *atoms[],
128              unsigned *state)
129 {
130 #ifdef DEBUG
131    boolean debug = TRUE;
132 #else
133    boolean debug = FALSE;
134 #endif
135    enum pipe_error ret = PIPE_OK;
136    unsigned i;
137 
138    ret = svga_hwtnl_flush( svga->hwtnl );
139    if (ret != PIPE_OK)
140       return ret;
141 
142    if (debug) {
143       /* Debug version which enforces various sanity checks on the
144        * state flags which are generated and checked to help ensure
145        * state atoms are ordered correctly in the list.
146        */
147       unsigned examined, prev;
148 
149       examined = 0;
150       prev = *state;
151 
152       for (i = 0; atoms[i] != NULL; i++) {
153          unsigned generated;
154 
155          assert(atoms[i]->dirty);
156          assert(atoms[i]->update);
157 
158          if (check_state(*state, atoms[i]->dirty)) {
159             if (0)
160                debug_printf("update: %s\n", atoms[i]->name);
161             ret = atoms[i]->update( svga, *state );
162             if (ret != PIPE_OK)
163                return ret;
164          }
165 
166          /* generated = (prev ^ state)
167           * if (examined & generated)
168           *     fail;
169           */
170          xor_states(&generated, prev, *state);
171          if (check_state(examined, generated)) {
172             debug_printf("state atom %s generated state already examined\n",
173                          atoms[i]->name);
174             assert(0);
175          }
176 
177          prev = *state;
178          accumulate_state(&examined, atoms[i]->dirty);
179       }
180    }
181    else {
182       for (i = 0; atoms[i] != NULL; i++) {
183          if (check_state(*state, atoms[i]->dirty)) {
184             ret = atoms[i]->update( svga, *state );
185             if (ret != PIPE_OK)
186                return ret;
187          }
188       }
189    }
190 
191    return PIPE_OK;
192 }
193 
194 
195 enum pipe_error
svga_update_state(struct svga_context * svga,unsigned max_level)196 svga_update_state(struct svga_context *svga, unsigned max_level)
197 {
198    struct svga_screen *screen = svga_screen(svga->pipe.screen);
199    enum pipe_error ret = PIPE_OK;
200    unsigned i;
201 
202    SVGA_STATS_TIME_PUSH(screen->sws, SVGA_STATS_TIME_UPDATESTATE);
203 
204    /* Check for updates to bound textures.  This can't be done in an
205     * atom as there is no flag which could provoke this test, and we
206     * cannot create one.
207     */
208    if (svga->state.texture_timestamp != screen->texture_timestamp) {
209       svga->state.texture_timestamp = screen->texture_timestamp;
210       svga->dirty |= SVGA_NEW_TEXTURE;
211    }
212 
213    for (i = 0; i <= max_level; i++) {
214       svga->dirty |= svga->state.dirty[i];
215 
216       if (svga->dirty) {
217          ret = update_state( svga,
218                              state_levels[i],
219                              &svga->dirty );
220          if (ret != PIPE_OK)
221             goto done;
222 
223          svga->state.dirty[i] = 0;
224       }
225    }
226 
227    for (; i < SVGA_STATE_MAX; i++)
228       svga->state.dirty[i] |= svga->dirty;
229 
230    svga->dirty = 0;
231 
232    svga->hud.num_validations++;
233 
234 done:
235    SVGA_STATS_TIME_POP(screen->sws);
236    return ret;
237 }
238 
239 
240 void
svga_update_state_retry(struct svga_context * svga,unsigned max_level)241 svga_update_state_retry(struct svga_context *svga, unsigned max_level)
242 {
243    enum pipe_error ret;
244 
245    ret = svga_update_state( svga, max_level );
246 
247    if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
248       svga_context_flush(svga, NULL);
249       ret = svga_update_state( svga, max_level );
250    }
251 
252    assert( ret == PIPE_OK );
253 }
254 
255 
256 
257 #define EMIT_RS(_rs, _count, _name, _value)     \
258 do {                                            \
259    _rs[_count].state = _name;                   \
260    _rs[_count].uintValue = _value;              \
261    _count++;                                    \
262 } while (0)
263 
264 
265 /* Setup any hardware state which will be constant through the life of
266  * a context.
267  */
268 enum pipe_error
svga_emit_initial_state(struct svga_context * svga)269 svga_emit_initial_state(struct svga_context *svga)
270 {
271    if (svga_have_vgpu10(svga)) {
272       SVGA3dRasterizerStateId id = util_bitmask_add(svga->rast_object_id_bm);
273       enum pipe_error ret;
274 
275       /* XXX preliminary code */
276       ret = SVGA3D_vgpu10_DefineRasterizerState(svga->swc,
277                                              id,
278                                              SVGA3D_FILLMODE_FILL,
279                                              SVGA3D_CULL_NONE,
280                                              1, /* frontCounterClockwise */
281                                              0, /* depthBias */
282                                              0.0f, /* depthBiasClamp */
283                                              0.0f, /* slopeScaledDepthBiasClamp */
284                                              0, /* depthClampEnable */
285                                              0, /* scissorEnable */
286                                              0, /* multisampleEnable */
287                                              0, /* aalineEnable */
288                                              1.0f, /* lineWidth */
289                                              0, /* lineStippleEnable */
290                                              0, /* lineStippleFactor */
291                                              0, /* lineStipplePattern */
292                                              0); /* provokingVertexLast */
293 
294 
295       assert(ret == PIPE_OK);
296 
297       ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, id);
298       return ret;
299    }
300    else {
301       SVGA3dRenderState *rs;
302       unsigned count = 0;
303       const unsigned COUNT = 2;
304       enum pipe_error ret;
305 
306       ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT );
307       if (ret != PIPE_OK)
308          return ret;
309 
310       /* Always use D3D style coordinate space as this is the only one
311        * which is implemented on all backends.
312        */
313       EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE,
314               SVGA3D_COORDINATE_LEFTHANDED );
315       EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW );
316 
317       assert( COUNT == count );
318       SVGA_FIFOCommitAll( svga->swc );
319 
320       return PIPE_OK;
321    }
322 }
323