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