1bf215546Sopenharmony_ci/**********************************************************
2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person
5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation
6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without
7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy,
8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies
9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is
10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be
13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22bf215546Sopenharmony_ci * SOFTWARE.
23bf215546Sopenharmony_ci *
24bf215546Sopenharmony_ci **********************************************************/
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "util/u_bitmask.h"
27bf215546Sopenharmony_ci#include "util/u_debug.h"
28bf215546Sopenharmony_ci#include "pipe/p_defines.h"
29bf215546Sopenharmony_ci#include "util/u_memory.h"
30bf215546Sopenharmony_ci#include "draw/draw_context.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "svga_context.h"
33bf215546Sopenharmony_ci#include "svga_screen.h"
34bf215546Sopenharmony_ci#include "svga_state.h"
35bf215546Sopenharmony_ci#include "svga_draw.h"
36bf215546Sopenharmony_ci#include "svga_cmd.h"
37bf215546Sopenharmony_ci#include "svga_hw_reg.h"
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci/* This is just enough to decide whether we need to use the draw
40bf215546Sopenharmony_ci * module (swtnl) or not.
41bf215546Sopenharmony_ci */
42bf215546Sopenharmony_cistatic const struct svga_tracked_state *need_swtnl_state[] =
43bf215546Sopenharmony_ci{
44bf215546Sopenharmony_ci   &svga_update_need_swvfetch,
45bf215546Sopenharmony_ci   &svga_update_need_pipeline,
46bf215546Sopenharmony_ci   &svga_update_need_swtnl,
47bf215546Sopenharmony_ci   NULL
48bf215546Sopenharmony_ci};
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci/* Atoms to update hardware state prior to emitting a clear or draw
52bf215546Sopenharmony_ci * packet.
53bf215546Sopenharmony_ci */
54bf215546Sopenharmony_cistatic const struct svga_tracked_state *hw_clear_state[] =
55bf215546Sopenharmony_ci{
56bf215546Sopenharmony_ci   &svga_hw_scissor,
57bf215546Sopenharmony_ci   &svga_hw_viewport,
58bf215546Sopenharmony_ci   &svga_hw_framebuffer,
59bf215546Sopenharmony_ci   NULL
60bf215546Sopenharmony_ci};
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci/**
64bf215546Sopenharmony_ci * Atoms to update hardware state prior to emitting a draw packet
65bf215546Sopenharmony_ci * for VGPU9 device.
66bf215546Sopenharmony_ci */
67bf215546Sopenharmony_cistatic const struct svga_tracked_state *hw_draw_state_vgpu9[] =
68bf215546Sopenharmony_ci{
69bf215546Sopenharmony_ci   &svga_hw_fs,
70bf215546Sopenharmony_ci   &svga_hw_vs,
71bf215546Sopenharmony_ci   &svga_hw_rss,
72bf215546Sopenharmony_ci   &svga_hw_tss,
73bf215546Sopenharmony_ci   &svga_hw_tss_binding,
74bf215546Sopenharmony_ci   &svga_hw_clip_planes,
75bf215546Sopenharmony_ci   &svga_hw_vdecl,
76bf215546Sopenharmony_ci   &svga_hw_fs_constants,
77bf215546Sopenharmony_ci   &svga_hw_vs_constants,
78bf215546Sopenharmony_ci   NULL
79bf215546Sopenharmony_ci};
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci/**
83bf215546Sopenharmony_ci * Atoms to update hardware state prior to emitting a draw packet
84bf215546Sopenharmony_ci * for VGPU10 device.
85bf215546Sopenharmony_ci * Geometry Shader is new to VGPU10.
86bf215546Sopenharmony_ci * TSS and TSS bindings are replaced by sampler and sampler bindings.
87bf215546Sopenharmony_ci */
88bf215546Sopenharmony_cistatic const struct svga_tracked_state *hw_draw_state_vgpu10[] =
89bf215546Sopenharmony_ci{
90bf215546Sopenharmony_ci   &svga_need_tgsi_transform,
91bf215546Sopenharmony_ci   &svga_hw_fs,
92bf215546Sopenharmony_ci   &svga_hw_gs,
93bf215546Sopenharmony_ci   &svga_hw_vs,
94bf215546Sopenharmony_ci   &svga_hw_rss,
95bf215546Sopenharmony_ci   &svga_hw_sampler,
96bf215546Sopenharmony_ci   &svga_hw_sampler_bindings,
97bf215546Sopenharmony_ci   &svga_hw_clip_planes,
98bf215546Sopenharmony_ci   &svga_hw_vdecl,
99bf215546Sopenharmony_ci   &svga_hw_fs_constants,
100bf215546Sopenharmony_ci   &svga_hw_fs_constbufs,
101bf215546Sopenharmony_ci   &svga_hw_gs_constants,
102bf215546Sopenharmony_ci   &svga_hw_gs_constbufs,
103bf215546Sopenharmony_ci   &svga_hw_vs_constants,
104bf215546Sopenharmony_ci   &svga_hw_vs_constbufs,
105bf215546Sopenharmony_ci   NULL
106bf215546Sopenharmony_ci};
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci/**
110bf215546Sopenharmony_ci * Atoms to update hardware state prior to emitting a draw packet
111bf215546Sopenharmony_ci * for SM5 device.
112bf215546Sopenharmony_ci * TCS and TES Shaders are new to SM5 device.
113bf215546Sopenharmony_ci */
114bf215546Sopenharmony_cistatic const struct svga_tracked_state *hw_draw_state_sm5[] =
115bf215546Sopenharmony_ci{
116bf215546Sopenharmony_ci   &svga_need_tgsi_transform,
117bf215546Sopenharmony_ci   &svga_hw_fs,
118bf215546Sopenharmony_ci   &svga_hw_gs,
119bf215546Sopenharmony_ci   &svga_hw_tes,
120bf215546Sopenharmony_ci   &svga_hw_tcs,
121bf215546Sopenharmony_ci   &svga_hw_vs,
122bf215546Sopenharmony_ci   &svga_hw_rss,
123bf215546Sopenharmony_ci   &svga_hw_sampler,
124bf215546Sopenharmony_ci   &svga_hw_sampler_bindings,
125bf215546Sopenharmony_ci   &svga_hw_clip_planes,
126bf215546Sopenharmony_ci   &svga_hw_vdecl,
127bf215546Sopenharmony_ci   &svga_hw_fs_constants,
128bf215546Sopenharmony_ci   &svga_hw_fs_constbufs,
129bf215546Sopenharmony_ci   &svga_hw_gs_constants,
130bf215546Sopenharmony_ci   &svga_hw_gs_constbufs,
131bf215546Sopenharmony_ci   &svga_hw_tes_constants,
132bf215546Sopenharmony_ci   &svga_hw_tes_constbufs,
133bf215546Sopenharmony_ci   &svga_hw_tcs_constants,
134bf215546Sopenharmony_ci   &svga_hw_tcs_constbufs,
135bf215546Sopenharmony_ci   &svga_hw_vs_constants,
136bf215546Sopenharmony_ci   &svga_hw_vs_constbufs,
137bf215546Sopenharmony_ci   NULL
138bf215546Sopenharmony_ci};
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci/**
142bf215546Sopenharmony_ci * Atoms to update hardware state prior to emitting a draw packet
143bf215546Sopenharmony_ci * for GL43 device which includes uav update.
144bf215546Sopenharmony_ci */
145bf215546Sopenharmony_cistatic const struct svga_tracked_state *hw_draw_state_gl43[] =
146bf215546Sopenharmony_ci{
147bf215546Sopenharmony_ci   &svga_need_tgsi_transform,
148bf215546Sopenharmony_ci   &svga_hw_uav,
149bf215546Sopenharmony_ci   &svga_need_rawbuf_srv,
150bf215546Sopenharmony_ci   &svga_hw_fs,
151bf215546Sopenharmony_ci   &svga_hw_gs,
152bf215546Sopenharmony_ci   &svga_hw_tes,
153bf215546Sopenharmony_ci   &svga_hw_tcs,
154bf215546Sopenharmony_ci   &svga_hw_vs,
155bf215546Sopenharmony_ci   &svga_hw_rss,
156bf215546Sopenharmony_ci   &svga_hw_sampler,
157bf215546Sopenharmony_ci   &svga_hw_sampler_bindings,
158bf215546Sopenharmony_ci   &svga_hw_clip_planes,
159bf215546Sopenharmony_ci   &svga_hw_vdecl,
160bf215546Sopenharmony_ci   &svga_hw_fs_constants,
161bf215546Sopenharmony_ci   &svga_hw_fs_constbufs,
162bf215546Sopenharmony_ci   &svga_hw_gs_constants,
163bf215546Sopenharmony_ci   &svga_hw_gs_constbufs,
164bf215546Sopenharmony_ci   &svga_hw_tes_constants,
165bf215546Sopenharmony_ci   &svga_hw_tes_constbufs,
166bf215546Sopenharmony_ci   &svga_hw_tcs_constants,
167bf215546Sopenharmony_ci   &svga_hw_tcs_constbufs,
168bf215546Sopenharmony_ci   &svga_hw_vs_constants,
169bf215546Sopenharmony_ci   &svga_hw_vs_constbufs,
170bf215546Sopenharmony_ci   NULL
171bf215546Sopenharmony_ci};
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_cistatic const struct svga_tracked_state *swtnl_draw_state[] =
175bf215546Sopenharmony_ci{
176bf215546Sopenharmony_ci   &svga_update_swtnl_draw,
177bf215546Sopenharmony_ci   &svga_update_swtnl_vdecl,
178bf215546Sopenharmony_ci   NULL
179bf215546Sopenharmony_ci};
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci
182bf215546Sopenharmony_ci/* Flattens the graph of state dependencies.  Could swap the positions
183bf215546Sopenharmony_ci * of hw_clear_state and need_swtnl_state without breaking anything.
184bf215546Sopenharmony_ci */
185bf215546Sopenharmony_cistatic const struct svga_tracked_state **state_levels[] =
186bf215546Sopenharmony_ci{
187bf215546Sopenharmony_ci   need_swtnl_state,
188bf215546Sopenharmony_ci   hw_clear_state,
189bf215546Sopenharmony_ci   NULL,              /* hw_draw_state, to be set to the right version */
190bf215546Sopenharmony_ci   swtnl_draw_state
191bf215546Sopenharmony_ci};
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_cistatic uint64_t
195bf215546Sopenharmony_cicheck_state(uint64_t a, uint64_t b)
196bf215546Sopenharmony_ci{
197bf215546Sopenharmony_ci   return (a & b);
198bf215546Sopenharmony_ci}
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_cistatic void
201bf215546Sopenharmony_ciaccumulate_state(uint64_t *a, uint64_t b)
202bf215546Sopenharmony_ci{
203bf215546Sopenharmony_ci   *a |= b;
204bf215546Sopenharmony_ci}
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_cistatic void
208bf215546Sopenharmony_cixor_states(uint64_t *result, uint64_t a, uint64_t b)
209bf215546Sopenharmony_ci{
210bf215546Sopenharmony_ci   *result = a ^ b;
211bf215546Sopenharmony_ci}
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_cistatic enum pipe_error
215bf215546Sopenharmony_ciupdate_state(struct svga_context *svga,
216bf215546Sopenharmony_ci             const struct svga_tracked_state *atoms[],
217bf215546Sopenharmony_ci             uint64_t *state)
218bf215546Sopenharmony_ci{
219bf215546Sopenharmony_ci#ifdef DEBUG
220bf215546Sopenharmony_ci   boolean debug = TRUE;
221bf215546Sopenharmony_ci#else
222bf215546Sopenharmony_ci   boolean debug = FALSE;
223bf215546Sopenharmony_ci#endif
224bf215546Sopenharmony_ci   enum pipe_error ret = PIPE_OK;
225bf215546Sopenharmony_ci   unsigned i;
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_ci   ret = svga_hwtnl_flush( svga->hwtnl );
228bf215546Sopenharmony_ci   if (ret != PIPE_OK)
229bf215546Sopenharmony_ci      return ret;
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   if (debug) {
232bf215546Sopenharmony_ci      /* Debug version which enforces various sanity checks on the
233bf215546Sopenharmony_ci       * state flags which are generated and checked to help ensure
234bf215546Sopenharmony_ci       * state atoms are ordered correctly in the list.
235bf215546Sopenharmony_ci       */
236bf215546Sopenharmony_ci      uint64_t examined, prev;
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci      examined = 0;
239bf215546Sopenharmony_ci      prev = *state;
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_ci      for (i = 0; atoms[i] != NULL; i++) {
242bf215546Sopenharmony_ci         uint64_t generated;
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci         assert(atoms[i]->dirty);
245bf215546Sopenharmony_ci         assert(atoms[i]->update);
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci         if (check_state(*state, atoms[i]->dirty)) {
248bf215546Sopenharmony_ci            if (0)
249bf215546Sopenharmony_ci               debug_printf("update: %s\n", atoms[i]->name);
250bf215546Sopenharmony_ci            ret = atoms[i]->update( svga, *state );
251bf215546Sopenharmony_ci            if (ret != PIPE_OK)
252bf215546Sopenharmony_ci               return ret;
253bf215546Sopenharmony_ci         }
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci         /* generated = (prev ^ state)
256bf215546Sopenharmony_ci          * if (examined & generated)
257bf215546Sopenharmony_ci          *     fail;
258bf215546Sopenharmony_ci          */
259bf215546Sopenharmony_ci         xor_states(&generated, prev, *state);
260bf215546Sopenharmony_ci         if (check_state(examined, generated)) {
261bf215546Sopenharmony_ci            debug_printf("state atom %s generated state already examined\n",
262bf215546Sopenharmony_ci                         atoms[i]->name);
263bf215546Sopenharmony_ci            assert(0);
264bf215546Sopenharmony_ci         }
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_ci         prev = *state;
267bf215546Sopenharmony_ci         accumulate_state(&examined, atoms[i]->dirty);
268bf215546Sopenharmony_ci      }
269bf215546Sopenharmony_ci   }
270bf215546Sopenharmony_ci   else {
271bf215546Sopenharmony_ci      for (i = 0; atoms[i] != NULL; i++) {
272bf215546Sopenharmony_ci         if (check_state(*state, atoms[i]->dirty)) {
273bf215546Sopenharmony_ci            ret = atoms[i]->update( svga, *state );
274bf215546Sopenharmony_ci            if (ret != PIPE_OK)
275bf215546Sopenharmony_ci               return ret;
276bf215546Sopenharmony_ci         }
277bf215546Sopenharmony_ci      }
278bf215546Sopenharmony_ci   }
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci   return PIPE_OK;
281bf215546Sopenharmony_ci}
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_cienum pipe_error
285bf215546Sopenharmony_cisvga_update_state(struct svga_context *svga, unsigned max_level)
286bf215546Sopenharmony_ci{
287bf215546Sopenharmony_ci   struct svga_screen *screen = svga_screen(svga->pipe.screen);
288bf215546Sopenharmony_ci   enum pipe_error ret = PIPE_OK;
289bf215546Sopenharmony_ci   unsigned i;
290bf215546Sopenharmony_ci
291bf215546Sopenharmony_ci   SVGA_STATS_TIME_PUSH(screen->sws, SVGA_STATS_TIME_UPDATESTATE);
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci   /* Check for updates to bound textures.  This can't be done in an
294bf215546Sopenharmony_ci    * atom as there is no flag which could provoke this test, and we
295bf215546Sopenharmony_ci    * cannot create one.
296bf215546Sopenharmony_ci    */
297bf215546Sopenharmony_ci   if (svga->state.texture_timestamp != screen->texture_timestamp) {
298bf215546Sopenharmony_ci      svga->state.texture_timestamp = screen->texture_timestamp;
299bf215546Sopenharmony_ci      svga->dirty |= SVGA_NEW_TEXTURE;
300bf215546Sopenharmony_ci   }
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci   for (i = 0; i <= max_level; i++) {
303bf215546Sopenharmony_ci      svga->dirty |= svga->state.dirty[i];
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci      if (svga->dirty) {
306bf215546Sopenharmony_ci         ret = update_state( svga,
307bf215546Sopenharmony_ci                             state_levels[i],
308bf215546Sopenharmony_ci                             &svga->dirty );
309bf215546Sopenharmony_ci         if (ret != PIPE_OK)
310bf215546Sopenharmony_ci            goto done;
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci         svga->state.dirty[i] = 0;
313bf215546Sopenharmony_ci      }
314bf215546Sopenharmony_ci   }
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_ci   for (; i < SVGA_STATE_MAX; i++)
317bf215546Sopenharmony_ci      svga->state.dirty[i] |= svga->dirty;
318bf215546Sopenharmony_ci
319bf215546Sopenharmony_ci   svga->dirty = 0;
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_ci   svga->hud.num_validations++;
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_cidone:
324bf215546Sopenharmony_ci   SVGA_STATS_TIME_POP(screen->sws);
325bf215546Sopenharmony_ci   return ret;
326bf215546Sopenharmony_ci}
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci/**
330bf215546Sopenharmony_ci * Update state.  If the first attempt fails, flush the command buffer
331bf215546Sopenharmony_ci * and retry.
332bf215546Sopenharmony_ci * \return  true if success, false if second attempt fails.
333bf215546Sopenharmony_ci */
334bf215546Sopenharmony_cibool
335bf215546Sopenharmony_cisvga_update_state_retry(struct svga_context *svga, unsigned max_level)
336bf215546Sopenharmony_ci{
337bf215546Sopenharmony_ci   enum pipe_error ret;
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci   SVGA_RETRY_OOM(svga, ret, svga_update_state( svga, max_level ));
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci   return ret == PIPE_OK;
342bf215546Sopenharmony_ci}
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci#define EMIT_RS(_rs, _count, _name, _value)     \
346bf215546Sopenharmony_cido {                                            \
347bf215546Sopenharmony_ci   _rs[_count].state = _name;                   \
348bf215546Sopenharmony_ci   _rs[_count].uintValue = _value;              \
349bf215546Sopenharmony_ci   _count++;                                    \
350bf215546Sopenharmony_ci} while (0)
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_ci/* Setup any hardware state which will be constant through the life of
354bf215546Sopenharmony_ci * a context.
355bf215546Sopenharmony_ci */
356bf215546Sopenharmony_cienum pipe_error
357bf215546Sopenharmony_cisvga_emit_initial_state(struct svga_context *svga)
358bf215546Sopenharmony_ci{
359bf215546Sopenharmony_ci   if (svga_have_vgpu10(svga)) {
360bf215546Sopenharmony_ci      SVGA3dRasterizerStateId id = util_bitmask_add(svga->rast_object_id_bm);
361bf215546Sopenharmony_ci      enum pipe_error ret;
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci      /* XXX preliminary code */
364bf215546Sopenharmony_ci      ret = SVGA3D_vgpu10_DefineRasterizerState(svga->swc,
365bf215546Sopenharmony_ci                                             id,
366bf215546Sopenharmony_ci                                             SVGA3D_FILLMODE_FILL,
367bf215546Sopenharmony_ci                                             SVGA3D_CULL_NONE,
368bf215546Sopenharmony_ci                                             1, /* frontCounterClockwise */
369bf215546Sopenharmony_ci                                             0, /* depthBias */
370bf215546Sopenharmony_ci                                             0.0f, /* depthBiasClamp */
371bf215546Sopenharmony_ci                                             0.0f, /* slopeScaledDepthBiasClamp */
372bf215546Sopenharmony_ci                                             0, /* depthClampEnable */
373bf215546Sopenharmony_ci                                             0, /* scissorEnable */
374bf215546Sopenharmony_ci                                             0, /* multisampleEnable */
375bf215546Sopenharmony_ci                                             0, /* aalineEnable */
376bf215546Sopenharmony_ci                                             1.0f, /* lineWidth */
377bf215546Sopenharmony_ci                                             0, /* lineStippleEnable */
378bf215546Sopenharmony_ci                                             0, /* lineStippleFactor */
379bf215546Sopenharmony_ci                                             0, /* lineStipplePattern */
380bf215546Sopenharmony_ci                                             0); /* provokingVertexLast */
381bf215546Sopenharmony_ci
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci      assert(ret == PIPE_OK);
384bf215546Sopenharmony_ci
385bf215546Sopenharmony_ci      ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, id);
386bf215546Sopenharmony_ci      return ret;
387bf215546Sopenharmony_ci   }
388bf215546Sopenharmony_ci   else {
389bf215546Sopenharmony_ci      SVGA3dRenderState *rs;
390bf215546Sopenharmony_ci      unsigned count = 0;
391bf215546Sopenharmony_ci      const unsigned COUNT = 2;
392bf215546Sopenharmony_ci      enum pipe_error ret;
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ci      ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT );
395bf215546Sopenharmony_ci      if (ret != PIPE_OK)
396bf215546Sopenharmony_ci         return ret;
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_ci      /* Always use D3D style coordinate space as this is the only one
399bf215546Sopenharmony_ci       * which is implemented on all backends.
400bf215546Sopenharmony_ci       */
401bf215546Sopenharmony_ci      EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE,
402bf215546Sopenharmony_ci              SVGA3D_COORDINATE_LEFTHANDED );
403bf215546Sopenharmony_ci      EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW );
404bf215546Sopenharmony_ci
405bf215546Sopenharmony_ci      assert( COUNT == count );
406bf215546Sopenharmony_ci      SVGA_FIFOCommitAll( svga->swc );
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_ci      return PIPE_OK;
409bf215546Sopenharmony_ci   }
410bf215546Sopenharmony_ci}
411bf215546Sopenharmony_ci
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_civoid
414bf215546Sopenharmony_cisvga_init_tracked_state(struct svga_context *svga)
415bf215546Sopenharmony_ci{
416bf215546Sopenharmony_ci   /* Set the hw_draw_state atom list to the one for the particular gpu version.
417bf215546Sopenharmony_ci    */
418bf215546Sopenharmony_ci   state_levels[2] =
419bf215546Sopenharmony_ci      svga_have_gl43(svga) ? hw_draw_state_gl43 :
420bf215546Sopenharmony_ci         (svga_have_sm5(svga) ? hw_draw_state_sm5 :
421bf215546Sopenharmony_ci            ((svga_have_vgpu10(svga) ? hw_draw_state_vgpu10 :
422bf215546Sopenharmony_ci                                       hw_draw_state_vgpu9)));
423bf215546Sopenharmony_ci}
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_cistatic const struct svga_tracked_state *compute_state[] =
427bf215546Sopenharmony_ci{
428bf215546Sopenharmony_ci   &svga_hw_cs_uav,
429bf215546Sopenharmony_ci   &svga_hw_cs_sampler,
430bf215546Sopenharmony_ci   &svga_hw_cs_sampler_bindings,
431bf215546Sopenharmony_ci   &svga_hw_cs,
432bf215546Sopenharmony_ci   &svga_hw_cs_constants,
433bf215546Sopenharmony_ci   &svga_hw_cs_constbufs,
434bf215546Sopenharmony_ci   NULL
435bf215546Sopenharmony_ci};
436bf215546Sopenharmony_ci
437bf215546Sopenharmony_ci/**
438bf215546Sopenharmony_ci * Update compute state.
439bf215546Sopenharmony_ci * If the first attempt fails, flush the command buffer and retry.
440bf215546Sopenharmony_ci * \return  true if success, false if second attempt fails.
441bf215546Sopenharmony_ci */
442bf215546Sopenharmony_cibool
443bf215546Sopenharmony_cisvga_update_compute_state(struct svga_context *svga)
444bf215546Sopenharmony_ci{
445bf215546Sopenharmony_ci   enum pipe_error ret = PIPE_OK;
446bf215546Sopenharmony_ci   uint64_t compute_dirty = svga->dirty;
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_ci   if (compute_dirty) {
449bf215546Sopenharmony_ci      SVGA_RETRY_OOM(svga, ret, update_state(svga, compute_state,
450bf215546Sopenharmony_ci                                             &compute_dirty));
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci      /* Set the dirty flag to the remaining dirty bits which are
453bf215546Sopenharmony_ci       * not processed in the compute pipeline.
454bf215546Sopenharmony_ci       */
455bf215546Sopenharmony_ci      svga->dirty = compute_dirty;
456bf215546Sopenharmony_ci   }
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_ci   return ret == PIPE_OK;
459bf215546Sopenharmony_ci}
460