ilo_state.c revision 9bfa987fb00a4e0471bcdb4948c8f416d7c5b562
1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2013 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Chia-I Wu <olv@lunarg.com>
26 */
27
28#include "core/ilo_builder_3d.h" /* for gen6_3d_translate_pipe_prim() */
29#include "core/ilo_format.h"
30#include "core/ilo_state_3d.h"
31#include "util/u_dual_blend.h"
32#include "util/u_dynarray.h"
33#include "util/u_helpers.h"
34#include "util/u_resource.h"
35#include "util/u_upload_mgr.h"
36
37#include "ilo_context.h"
38#include "ilo_resource.h"
39#include "ilo_shader.h"
40#include "ilo_state.h"
41
42static enum gen_mip_filter
43ilo_translate_mip_filter(unsigned filter)
44{
45   switch (filter) {
46   case PIPE_TEX_MIPFILTER_NEAREST:    return GEN6_MIPFILTER_NEAREST;
47   case PIPE_TEX_MIPFILTER_LINEAR:     return GEN6_MIPFILTER_LINEAR;
48   case PIPE_TEX_MIPFILTER_NONE:       return GEN6_MIPFILTER_NONE;
49   default:
50      assert(!"unknown mipfilter");
51      return GEN6_MIPFILTER_NONE;
52   }
53}
54
55static int
56ilo_translate_img_filter(unsigned filter)
57{
58   switch (filter) {
59   case PIPE_TEX_FILTER_NEAREST:       return GEN6_MAPFILTER_NEAREST;
60   case PIPE_TEX_FILTER_LINEAR:        return GEN6_MAPFILTER_LINEAR;
61   default:
62      assert(!"unknown sampler filter");
63      return GEN6_MAPFILTER_NEAREST;
64   }
65}
66
67static enum gen_texcoord_mode
68ilo_translate_address_wrap(unsigned wrap)
69{
70   switch (wrap) {
71   case PIPE_TEX_WRAP_CLAMP:           return GEN8_TEXCOORDMODE_HALF_BORDER;
72   case PIPE_TEX_WRAP_REPEAT:          return GEN6_TEXCOORDMODE_WRAP;
73   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:   return GEN6_TEXCOORDMODE_CLAMP;
74   case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return GEN6_TEXCOORDMODE_CLAMP_BORDER;
75   case PIPE_TEX_WRAP_MIRROR_REPEAT:   return GEN6_TEXCOORDMODE_MIRROR;
76   case PIPE_TEX_WRAP_MIRROR_CLAMP:
77   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
78   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
79   default:
80      assert(!"unknown sampler wrap mode");
81      return GEN6_TEXCOORDMODE_WRAP;
82   }
83}
84
85static enum gen_aniso_ratio
86ilo_translate_max_anisotropy(unsigned max_anisotropy)
87{
88   switch (max_anisotropy) {
89   case 0: case 1: case 2:             return GEN6_ANISORATIO_2;
90   case 3: case 4:                     return GEN6_ANISORATIO_4;
91   case 5: case 6:                     return GEN6_ANISORATIO_6;
92   case 7: case 8:                     return GEN6_ANISORATIO_8;
93   case 9: case 10:                    return GEN6_ANISORATIO_10;
94   case 11: case 12:                   return GEN6_ANISORATIO_12;
95   case 13: case 14:                   return GEN6_ANISORATIO_14;
96   default:                            return GEN6_ANISORATIO_16;
97   }
98}
99
100static enum gen_prefilter_op
101ilo_translate_shadow_func(unsigned func)
102{
103   /*
104    * For PIPE_FUNC_x, the reference value is on the left-hand side of the
105    * comparison, and 1.0 is returned when the comparison is true.
106    *
107    * For GEN6_PREFILTEROP_x, the reference value is on the right-hand side of
108    * the comparison, and 0.0 is returned when the comparison is true.
109    */
110   switch (func) {
111   case PIPE_FUNC_NEVER:               return GEN6_PREFILTEROP_ALWAYS;
112   case PIPE_FUNC_LESS:                return GEN6_PREFILTEROP_LEQUAL;
113   case PIPE_FUNC_EQUAL:               return GEN6_PREFILTEROP_NOTEQUAL;
114   case PIPE_FUNC_LEQUAL:              return GEN6_PREFILTEROP_LESS;
115   case PIPE_FUNC_GREATER:             return GEN6_PREFILTEROP_GEQUAL;
116   case PIPE_FUNC_NOTEQUAL:            return GEN6_PREFILTEROP_EQUAL;
117   case PIPE_FUNC_GEQUAL:              return GEN6_PREFILTEROP_GREATER;
118   case PIPE_FUNC_ALWAYS:              return GEN6_PREFILTEROP_NEVER;
119   default:
120      assert(!"unknown shadow compare function");
121      return GEN6_PREFILTEROP_NEVER;
122   }
123}
124
125static enum gen_front_winding
126ilo_translate_front_ccw(unsigned front_ccw)
127{
128   return (front_ccw) ? GEN6_FRONTWINDING_CCW : GEN6_FRONTWINDING_CW;
129}
130
131static enum gen_cull_mode
132ilo_translate_cull_face(unsigned cull_face)
133{
134   switch (cull_face) {
135   case PIPE_FACE_NONE:                return GEN6_CULLMODE_NONE;
136   case PIPE_FACE_FRONT:               return GEN6_CULLMODE_FRONT;
137   case PIPE_FACE_BACK:                return GEN6_CULLMODE_BACK;
138   case PIPE_FACE_FRONT_AND_BACK:      return GEN6_CULLMODE_BOTH;
139   default:
140      assert(!"unknown face culling");
141      return GEN6_CULLMODE_NONE;
142   }
143}
144
145static enum gen_fill_mode
146ilo_translate_poly_mode(unsigned poly_mode)
147{
148   switch (poly_mode) {
149   case PIPE_POLYGON_MODE_FILL:        return GEN6_FILLMODE_SOLID;
150   case PIPE_POLYGON_MODE_LINE:        return GEN6_FILLMODE_WIREFRAME;
151   case PIPE_POLYGON_MODE_POINT:       return GEN6_FILLMODE_POINT;
152   default:
153      assert(!"unknown polygon mode");
154      return GEN6_FILLMODE_SOLID;
155   }
156}
157
158static enum gen_pixel_location
159ilo_translate_half_pixel_center(bool half_pixel_center)
160{
161   return (half_pixel_center) ? GEN6_PIXLOC_CENTER : GEN6_PIXLOC_UL_CORNER;
162}
163
164static enum gen_compare_function
165ilo_translate_compare_func(unsigned func)
166{
167   switch (func) {
168   case PIPE_FUNC_NEVER:               return GEN6_COMPAREFUNCTION_NEVER;
169   case PIPE_FUNC_LESS:                return GEN6_COMPAREFUNCTION_LESS;
170   case PIPE_FUNC_EQUAL:               return GEN6_COMPAREFUNCTION_EQUAL;
171   case PIPE_FUNC_LEQUAL:              return GEN6_COMPAREFUNCTION_LEQUAL;
172   case PIPE_FUNC_GREATER:             return GEN6_COMPAREFUNCTION_GREATER;
173   case PIPE_FUNC_NOTEQUAL:            return GEN6_COMPAREFUNCTION_NOTEQUAL;
174   case PIPE_FUNC_GEQUAL:              return GEN6_COMPAREFUNCTION_GEQUAL;
175   case PIPE_FUNC_ALWAYS:              return GEN6_COMPAREFUNCTION_ALWAYS;
176   default:
177      assert(!"unknown compare function");
178      return GEN6_COMPAREFUNCTION_NEVER;
179   }
180}
181
182static enum gen_stencil_op
183ilo_translate_stencil_op(unsigned stencil_op)
184{
185   switch (stencil_op) {
186   case PIPE_STENCIL_OP_KEEP:          return GEN6_STENCILOP_KEEP;
187   case PIPE_STENCIL_OP_ZERO:          return GEN6_STENCILOP_ZERO;
188   case PIPE_STENCIL_OP_REPLACE:       return GEN6_STENCILOP_REPLACE;
189   case PIPE_STENCIL_OP_INCR:          return GEN6_STENCILOP_INCRSAT;
190   case PIPE_STENCIL_OP_DECR:          return GEN6_STENCILOP_DECRSAT;
191   case PIPE_STENCIL_OP_INCR_WRAP:     return GEN6_STENCILOP_INCR;
192   case PIPE_STENCIL_OP_DECR_WRAP:     return GEN6_STENCILOP_DECR;
193   case PIPE_STENCIL_OP_INVERT:        return GEN6_STENCILOP_INVERT;
194   default:
195      assert(!"unknown stencil op");
196      return GEN6_STENCILOP_KEEP;
197   }
198}
199
200static enum gen_logic_op
201ilo_translate_logicop(unsigned logicop)
202{
203   switch (logicop) {
204   case PIPE_LOGICOP_CLEAR:            return GEN6_LOGICOP_CLEAR;
205   case PIPE_LOGICOP_NOR:              return GEN6_LOGICOP_NOR;
206   case PIPE_LOGICOP_AND_INVERTED:     return GEN6_LOGICOP_AND_INVERTED;
207   case PIPE_LOGICOP_COPY_INVERTED:    return GEN6_LOGICOP_COPY_INVERTED;
208   case PIPE_LOGICOP_AND_REVERSE:      return GEN6_LOGICOP_AND_REVERSE;
209   case PIPE_LOGICOP_INVERT:           return GEN6_LOGICOP_INVERT;
210   case PIPE_LOGICOP_XOR:              return GEN6_LOGICOP_XOR;
211   case PIPE_LOGICOP_NAND:             return GEN6_LOGICOP_NAND;
212   case PIPE_LOGICOP_AND:              return GEN6_LOGICOP_AND;
213   case PIPE_LOGICOP_EQUIV:            return GEN6_LOGICOP_EQUIV;
214   case PIPE_LOGICOP_NOOP:             return GEN6_LOGICOP_NOOP;
215   case PIPE_LOGICOP_OR_INVERTED:      return GEN6_LOGICOP_OR_INVERTED;
216   case PIPE_LOGICOP_COPY:             return GEN6_LOGICOP_COPY;
217   case PIPE_LOGICOP_OR_REVERSE:       return GEN6_LOGICOP_OR_REVERSE;
218   case PIPE_LOGICOP_OR:               return GEN6_LOGICOP_OR;
219   case PIPE_LOGICOP_SET:              return GEN6_LOGICOP_SET;
220   default:
221      assert(!"unknown logicop function");
222      return GEN6_LOGICOP_CLEAR;
223   }
224}
225
226static int
227ilo_translate_blend_func(unsigned blend)
228{
229   switch (blend) {
230   case PIPE_BLEND_ADD:                return GEN6_BLENDFUNCTION_ADD;
231   case PIPE_BLEND_SUBTRACT:           return GEN6_BLENDFUNCTION_SUBTRACT;
232   case PIPE_BLEND_REVERSE_SUBTRACT:   return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
233   case PIPE_BLEND_MIN:                return GEN6_BLENDFUNCTION_MIN;
234   case PIPE_BLEND_MAX:                return GEN6_BLENDFUNCTION_MAX;
235   default:
236      assert(!"unknown blend function");
237      return GEN6_BLENDFUNCTION_ADD;
238   }
239}
240
241static int
242ilo_translate_blend_factor(unsigned factor)
243{
244   switch (factor) {
245   case PIPE_BLENDFACTOR_ONE:                return GEN6_BLENDFACTOR_ONE;
246   case PIPE_BLENDFACTOR_SRC_COLOR:          return GEN6_BLENDFACTOR_SRC_COLOR;
247   case PIPE_BLENDFACTOR_SRC_ALPHA:          return GEN6_BLENDFACTOR_SRC_ALPHA;
248   case PIPE_BLENDFACTOR_DST_ALPHA:          return GEN6_BLENDFACTOR_DST_ALPHA;
249   case PIPE_BLENDFACTOR_DST_COLOR:          return GEN6_BLENDFACTOR_DST_COLOR;
250   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
251   case PIPE_BLENDFACTOR_CONST_COLOR:        return GEN6_BLENDFACTOR_CONST_COLOR;
252   case PIPE_BLENDFACTOR_CONST_ALPHA:        return GEN6_BLENDFACTOR_CONST_ALPHA;
253   case PIPE_BLENDFACTOR_SRC1_COLOR:         return GEN6_BLENDFACTOR_SRC1_COLOR;
254   case PIPE_BLENDFACTOR_SRC1_ALPHA:         return GEN6_BLENDFACTOR_SRC1_ALPHA;
255   case PIPE_BLENDFACTOR_ZERO:               return GEN6_BLENDFACTOR_ZERO;
256   case PIPE_BLENDFACTOR_INV_SRC_COLOR:      return GEN6_BLENDFACTOR_INV_SRC_COLOR;
257   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:      return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
258   case PIPE_BLENDFACTOR_INV_DST_ALPHA:      return GEN6_BLENDFACTOR_INV_DST_ALPHA;
259   case PIPE_BLENDFACTOR_INV_DST_COLOR:      return GEN6_BLENDFACTOR_INV_DST_COLOR;
260   case PIPE_BLENDFACTOR_INV_CONST_COLOR:    return GEN6_BLENDFACTOR_INV_CONST_COLOR;
261   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:    return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
262   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:     return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
263   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:     return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
264   default:
265      assert(!"unknown blend factor");
266      return GEN6_BLENDFACTOR_ONE;
267   }
268}
269
270static void
271finalize_shader_states(struct ilo_state_vector *vec)
272{
273   unsigned type;
274
275   for (type = 0; type < PIPE_SHADER_TYPES; type++) {
276      struct ilo_shader_state *shader;
277      uint32_t state;
278
279      switch (type) {
280      case PIPE_SHADER_VERTEX:
281         shader = vec->vs;
282         state = ILO_DIRTY_VS;
283         break;
284      case PIPE_SHADER_GEOMETRY:
285         shader = vec->gs;
286         state = ILO_DIRTY_GS;
287         break;
288      case PIPE_SHADER_FRAGMENT:
289         shader = vec->fs;
290         state = ILO_DIRTY_FS;
291         break;
292      default:
293         shader = NULL;
294         state = 0;
295         break;
296      }
297
298      if (!shader)
299         continue;
300
301      /* compile if the shader or the states it depends on changed */
302      if (vec->dirty & state) {
303         ilo_shader_select_kernel(shader, vec, ILO_DIRTY_ALL);
304      }
305      else if (ilo_shader_select_kernel(shader, vec, vec->dirty)) {
306         /* mark the state dirty if a new kernel is selected */
307         vec->dirty |= state;
308      }
309
310      /* need to setup SBE for FS */
311      if (type == PIPE_SHADER_FRAGMENT && vec->dirty &
312            (state | ILO_DIRTY_GS | ILO_DIRTY_VS | ILO_DIRTY_RASTERIZER)) {
313         if (ilo_shader_select_kernel_routing(shader,
314               (vec->gs) ? vec->gs : vec->vs, vec->rasterizer))
315            vec->dirty |= state;
316      }
317   }
318}
319
320static void
321finalize_cbuf_state(struct ilo_context *ilo,
322                    struct ilo_cbuf_state *cbuf,
323                    const struct ilo_shader_state *sh)
324{
325   uint32_t upload_mask = cbuf->enabled_mask;
326
327   /* skip CBUF0 if the kernel does not need it */
328   upload_mask &=
329      ~ilo_shader_get_kernel_param(sh, ILO_KERNEL_SKIP_CBUF0_UPLOAD);
330
331   while (upload_mask) {
332      unsigned offset, i;
333
334      i = u_bit_scan(&upload_mask);
335      /* no need to upload */
336      if (cbuf->cso[i].resource)
337         continue;
338
339      u_upload_data(ilo->uploader, 0, cbuf->cso[i].info.size,
340            cbuf->cso[i].user_buffer, &offset, &cbuf->cso[i].resource);
341
342      cbuf->cso[i].info.buf = ilo_buffer(cbuf->cso[i].resource);
343      cbuf->cso[i].info.offset = offset;
344
345      memset(&cbuf->cso[i].surface, 0, sizeof(cbuf->cso[i].surface));
346      ilo_state_surface_init_for_buffer(&cbuf->cso[i].surface,
347            ilo->dev, &cbuf->cso[i].info);
348      cbuf->cso[i].surface.bo = cbuf->cso[i].info.buf->bo;
349
350      ilo->state_vector.dirty |= ILO_DIRTY_CBUF;
351   }
352}
353
354static void
355finalize_constant_buffers(struct ilo_context *ilo)
356{
357   struct ilo_state_vector *vec = &ilo->state_vector;
358
359   if (vec->dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_VS))
360      finalize_cbuf_state(ilo, &vec->cbuf[PIPE_SHADER_VERTEX], vec->vs);
361
362   if (ilo->state_vector.dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_FS))
363      finalize_cbuf_state(ilo, &vec->cbuf[PIPE_SHADER_FRAGMENT], vec->fs);
364}
365
366static void
367finalize_index_buffer(struct ilo_context *ilo)
368{
369   struct ilo_state_vector *vec = &ilo->state_vector;
370   const bool need_upload = (vec->draw->indexed &&
371         (vec->ib.user_buffer || vec->ib.offset % vec->ib.index_size));
372   struct pipe_resource *current_hw_res = NULL;
373
374   if (!(vec->dirty & ILO_DIRTY_IB) && !need_upload)
375      return;
376
377   pipe_resource_reference(&current_hw_res, vec->ib.hw_resource);
378
379   if (need_upload) {
380      const unsigned offset = vec->ib.index_size * vec->draw->start;
381      const unsigned size = vec->ib.index_size * vec->draw->count;
382      unsigned hw_offset;
383
384      if (vec->ib.user_buffer) {
385         u_upload_data(ilo->uploader, 0, size,
386               vec->ib.user_buffer + offset, &hw_offset, &vec->ib.hw_resource);
387      }
388      else {
389         u_upload_buffer(ilo->uploader, 0, vec->ib.offset + offset, size,
390               vec->ib.buffer, &hw_offset, &vec->ib.hw_resource);
391      }
392
393      /* the HW offset should be aligned */
394      assert(hw_offset % vec->ib.index_size == 0);
395      vec->ib.draw_start_offset = hw_offset / vec->ib.index_size;
396
397      /*
398       * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
399       * resource
400       */
401      vec->ib.draw_start_offset -= vec->draw->start;
402   }
403   else {
404      pipe_resource_reference(&vec->ib.hw_resource, vec->ib.buffer);
405
406      /* note that index size may be zero when the draw is not indexed */
407      if (vec->draw->indexed)
408         vec->ib.draw_start_offset = vec->ib.offset / vec->ib.index_size;
409      else
410         vec->ib.draw_start_offset = 0;
411   }
412
413   /* treat the IB as clean if the HW states do not change */
414   if (vec->ib.hw_resource == current_hw_res &&
415       vec->ib.hw_index_size == vec->ib.index_size)
416      vec->dirty &= ~ILO_DIRTY_IB;
417   else
418      vec->ib.hw_index_size = vec->ib.index_size;
419
420   pipe_resource_reference(&current_hw_res, NULL);
421}
422
423static void
424finalize_vertex_elements(struct ilo_context *ilo)
425{
426   struct ilo_state_vector *vec = &ilo->state_vector;
427
428   if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS)))
429      return;
430
431   vec->dirty |= ILO_DIRTY_VE;
432
433   vec->ve->last_cso_edgeflag = false;
434   if (vec->ve->count && vec->vs &&
435         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG)) {
436      vec->ve->edgeflag_cso = vec->ve->cso[vec->ve->count - 1];
437      ilo_gpe_set_ve_edgeflag(ilo->dev, &vec->ve->edgeflag_cso);
438      vec->ve->last_cso_edgeflag = true;
439   }
440
441   vec->ve->prepend_nosrc_cso = false;
442   if (vec->vs &&
443       (ilo_shader_get_kernel_param(vec->vs,
444                                    ILO_KERNEL_VS_INPUT_INSTANCEID) ||
445        ilo_shader_get_kernel_param(vec->vs,
446                                    ILO_KERNEL_VS_INPUT_VERTEXID))) {
447      ilo_gpe_init_ve_nosrc(ilo->dev,
448            GEN6_VFCOMP_STORE_VID,
449            GEN6_VFCOMP_STORE_IID,
450            GEN6_VFCOMP_NOSTORE,
451            GEN6_VFCOMP_NOSTORE,
452            &vec->ve->nosrc_cso);
453      vec->ve->prepend_nosrc_cso = true;
454   } else if (!vec->vs) {
455      /* generate VUE header */
456      ilo_gpe_init_ve_nosrc(ilo->dev,
457            GEN6_VFCOMP_STORE_0, /* Reserved */
458            GEN6_VFCOMP_STORE_0, /* Render Target Array Index */
459            GEN6_VFCOMP_STORE_0, /* Viewport Index */
460            GEN6_VFCOMP_STORE_0, /* Point Width */
461            &vec->ve->nosrc_cso);
462      vec->ve->prepend_nosrc_cso = true;
463   } else if (!vec->ve->count) {
464      /*
465       * From the Sandy Bridge PRM, volume 2 part 1, page 92:
466       *
467       *    "SW must ensure that at least one vertex element is defined prior
468       *     to issuing a 3DPRIMTIVE command, or operation is UNDEFINED."
469       */
470      ilo_gpe_init_ve_nosrc(ilo->dev,
471            GEN6_VFCOMP_STORE_0,
472            GEN6_VFCOMP_STORE_0,
473            GEN6_VFCOMP_STORE_0,
474            GEN6_VFCOMP_STORE_1_FP,
475            &vec->ve->nosrc_cso);
476      vec->ve->prepend_nosrc_cso = true;
477   }
478}
479
480static void
481finalize_urb(struct ilo_context *ilo)
482{
483   const uint16_t attr_size = sizeof(uint32_t) * 4;
484   const struct ilo_dev *dev = ilo->dev;
485   struct ilo_state_vector *vec = &ilo->state_vector;
486   struct ilo_state_urb_info info;
487
488   if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS |
489                       ILO_DIRTY_GS | ILO_DIRTY_FS)))
490      return;
491
492   memset(&info, 0, sizeof(info));
493
494   info.ve_entry_size = attr_size *
495      (vec->ve->count + vec->ve->prepend_nosrc_cso);
496
497   if (vec->vs) {
498      info.vs_const_data = (bool)
499         (ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_PCB_CBUF0_SIZE) +
500          ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_PCB_UCP_SIZE));
501      info.vs_entry_size = attr_size *
502         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_OUTPUT_COUNT);
503   }
504
505   if (vec->gs) {
506      info.gs_const_data = (bool)
507         ilo_shader_get_kernel_param(vec->gs, ILO_KERNEL_PCB_CBUF0_SIZE);
508
509      /*
510       * From the Ivy Bridge PRM, volume 2 part 1, page 189:
511       *
512       *     "All outputs of a GS thread will be stored in the single GS
513       *      thread output URB entry."
514       *
515       * TODO
516       */
517      info.gs_entry_size = attr_size *
518         ilo_shader_get_kernel_param(vec->gs, ILO_KERNEL_OUTPUT_COUNT);
519   }
520
521   if (vec->fs) {
522      info.ps_const_data = (bool)
523         ilo_shader_get_kernel_param(vec->fs, ILO_KERNEL_PCB_CBUF0_SIZE);
524   }
525
526   ilo_state_urb_set_info(&vec->urb, dev, &info);
527}
528
529static void
530finalize_viewport(struct ilo_context *ilo)
531{
532   const struct ilo_dev *dev = ilo->dev;
533   struct ilo_state_vector *vec = &ilo->state_vector;
534
535   if (vec->dirty & ILO_DIRTY_VIEWPORT) {
536      ilo_state_viewport_set_params(&vec->viewport.vp,
537            dev, &vec->viewport.params, false);
538   } else if (vec->dirty & ILO_DIRTY_SCISSOR) {
539      ilo_state_viewport_set_params(&vec->viewport.vp,
540            dev, &vec->viewport.params, true);
541      vec->dirty |= ILO_DIRTY_VIEWPORT;
542   }
543}
544
545static bool
546can_enable_gb_test(const struct ilo_rasterizer_state *rasterizer,
547                   const struct ilo_viewport_state *viewport,
548                   const struct ilo_fb_state *fb)
549{
550   unsigned i;
551
552   /*
553    * There are several reasons that guard band test should be disabled
554    *
555    *  - GL wide points (to avoid partially visibie object)
556    *  - GL wide or AA lines (to avoid partially visibie object)
557    *  - missing 2D clipping
558    */
559   if (rasterizer->state.point_size_per_vertex ||
560       rasterizer->state.point_size > 1.0f ||
561       rasterizer->state.line_width > 1.0f ||
562       rasterizer->state.line_smooth)
563      return false;
564
565   for (i = 0; i < viewport->params.count; i++) {
566      const struct ilo_state_viewport_matrix_info *mat =
567         &viewport->matrices[i];
568      float min_x, max_x, min_y, max_y;
569
570      min_x = -1.0f * fabsf(mat->scale[0]) + mat->translate[0];
571      max_x =  1.0f * fabsf(mat->scale[0]) + mat->translate[0];
572      min_y = -1.0f * fabsf(mat->scale[1]) + mat->translate[1];
573      max_y =  1.0f * fabsf(mat->scale[1]) + mat->translate[1];
574
575      if (min_x > 0.0f || max_x < fb->state.width ||
576          min_y > 0.0f || max_y < fb->state.height)
577         return false;
578   }
579
580   return true;
581}
582
583static void
584finalize_rasterizer(struct ilo_context *ilo)
585{
586   const struct ilo_dev *dev = ilo->dev;
587   struct ilo_state_vector *vec = &ilo->state_vector;
588   struct ilo_rasterizer_state *rasterizer = vec->rasterizer;
589   struct ilo_state_raster_info *info = &vec->rasterizer->info;
590   const bool gb_test_enable =
591      can_enable_gb_test(rasterizer, &vec->viewport, &vec->fb);
592   const bool multisample =
593      (rasterizer->state.multisample && vec->fb.num_samples > 1);
594   const uint8_t barycentric_interps = ilo_shader_get_kernel_param(vec->fs,
595         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
596
597   /* check for non-orthogonal states */
598   if (info->clip.viewport_count != vec->viewport.params.count ||
599       info->clip.gb_test_enable != gb_test_enable ||
600       info->setup.msaa_enable != multisample ||
601       info->setup.line_msaa_enable != multisample ||
602       info->tri.depth_offset_format != vec->fb.depth_offset_format ||
603       info->scan.sample_count != vec->fb.num_samples ||
604       info->scan.sample_mask != vec->sample_mask ||
605       info->scan.barycentric_interps != barycentric_interps ||
606       info->params.any_integer_rt != vec->fb.has_integer_rt ||
607       info->params.hiz_enable != vec->fb.has_hiz) {
608      info->clip.viewport_count = vec->viewport.params.count;
609      info->clip.gb_test_enable = gb_test_enable;
610      info->setup.msaa_enable = multisample;
611      info->setup.line_msaa_enable = multisample;
612      info->tri.depth_offset_format = vec->fb.depth_offset_format;
613      info->scan.sample_count = vec->fb.num_samples;
614      info->scan.sample_mask = vec->sample_mask;
615      info->scan.barycentric_interps = barycentric_interps;
616      info->params.any_integer_rt = vec->fb.has_integer_rt;
617      info->params.hiz_enable = vec->fb.has_hiz;
618
619      ilo_state_raster_set_info(&rasterizer->rs, dev, &rasterizer->info);
620
621      vec->dirty |= ILO_DIRTY_RASTERIZER;
622   }
623}
624
625static bool
626finalize_blend_rt(struct ilo_context *ilo)
627{
628   struct ilo_state_vector *vec = &ilo->state_vector;
629   const struct ilo_fb_state *fb = &vec->fb;
630   struct ilo_blend_state *blend = vec->blend;
631   struct ilo_state_cc_blend_info *info = &vec->blend->info.blend;
632   bool changed = false;
633   unsigned i;
634
635   if (!(vec->dirty & (ILO_DIRTY_FB | ILO_DIRTY_BLEND)))
636      return false;
637
638   /* set up one for dummy RT writes */
639   if (!fb->state.nr_cbufs) {
640      if (info->rt != &blend->dummy_rt) {
641         info->rt = &blend->dummy_rt;
642         info->rt_count = 1;
643         changed = true;
644      }
645
646      return changed;
647   }
648
649   if (info->rt != blend->effective_rt ||
650       info->rt_count != fb->state.nr_cbufs) {
651      info->rt = blend->effective_rt;
652      info->rt_count = fb->state.nr_cbufs;
653      changed = true;
654   }
655
656   for (i = 0; i < fb->state.nr_cbufs; i++) {
657      const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
658      struct ilo_state_cc_blend_rt_info *rt = &blend->effective_rt[i];
659      /* ignore logicop when not UNORM */
660      const bool logicop_enable =
661         (blend->rt[i].logicop_enable && caps->is_unorm);
662
663      if (rt->cv_is_unorm != caps->is_unorm ||
664          rt->cv_is_integer != caps->is_integer ||
665          rt->logicop_enable != logicop_enable ||
666          rt->force_dst_alpha_one != caps->force_dst_alpha_one) {
667         rt->cv_is_unorm = caps->is_unorm;
668         rt->cv_is_integer = caps->is_integer;
669         rt->logicop_enable = logicop_enable;
670         rt->force_dst_alpha_one = caps->force_dst_alpha_one;
671
672         changed = true;
673      }
674   }
675
676   return changed;
677}
678
679static void
680finalize_blend(struct ilo_context *ilo)
681{
682   const struct ilo_dev *dev = ilo->dev;
683   struct ilo_state_vector *vec = &ilo->state_vector;
684   struct ilo_blend_state *blend = vec->blend;
685   struct ilo_state_cc_info *info = &blend->info;
686   const bool sample_count_one = (vec->fb.num_samples <= 1);
687   const bool float_source0_alpha =
688      (!vec->fb.state.nr_cbufs || !vec->fb.state.cbufs[0] ||
689       !util_format_is_pure_integer(vec->fb.state.cbufs[0]->format));
690
691   /* check for non-orthogonal states */
692   if (finalize_blend_rt(ilo) ||
693       info->alpha.cv_sample_count_one != sample_count_one ||
694       info->alpha.cv_float_source0_alpha != float_source0_alpha ||
695       info->alpha.test_enable != vec->dsa->alpha_test ||
696       info->alpha.test_func != vec->dsa->alpha_func ||
697       memcmp(&info->stencil, &vec->dsa->stencil, sizeof(info->stencil)) ||
698       memcmp(&info->depth, &vec->dsa->depth, sizeof(info->depth)) ||
699       memcmp(&info->params, &vec->cc_params, sizeof(info->params))) {
700      info->alpha.cv_sample_count_one = sample_count_one;
701      info->alpha.cv_float_source0_alpha = float_source0_alpha;
702      info->alpha.test_enable = vec->dsa->alpha_test;
703      info->alpha.test_func = vec->dsa->alpha_func;
704      info->stencil = vec->dsa->stencil;
705      info->depth = vec->dsa->depth;
706      info->params = vec->cc_params;
707
708      ilo_state_cc_set_info(&blend->cc, dev, info);
709
710      blend->alpha_may_kill = (info->alpha.alpha_to_coverage ||
711                               info->alpha.test_enable);
712
713      vec->dirty |= ILO_DIRTY_BLEND;
714   }
715}
716
717/**
718 * Finalize states.  Some states depend on other states and are
719 * incomplete/invalid until finalized.
720 */
721void
722ilo_finalize_3d_states(struct ilo_context *ilo,
723                       const struct pipe_draw_info *draw)
724{
725   ilo->state_vector.draw = draw;
726
727   finalize_shader_states(&ilo->state_vector);
728   finalize_constant_buffers(ilo);
729   finalize_index_buffer(ilo);
730   finalize_vertex_elements(ilo);
731
732   finalize_urb(ilo);
733   finalize_rasterizer(ilo);
734   finalize_viewport(ilo);
735   finalize_blend(ilo);
736
737   u_upload_unmap(ilo->uploader);
738}
739
740static void
741finalize_global_binding(struct ilo_state_vector *vec)
742{
743   struct ilo_shader_state *cs = vec->cs;
744   int base, count, shift;
745   int i;
746
747   count = ilo_shader_get_kernel_param(cs,
748         ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT);
749   if (!count)
750      return;
751
752   base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE);
753   shift = 32 - util_last_bit(base + count - 1);
754
755   if (count > vec->global_binding.count)
756      count = vec->global_binding.count;
757
758   for (i = 0; i < count; i++) {
759      struct ilo_global_binding_cso *cso =
760         util_dynarray_element(&vec->global_binding.bindings,
761               struct ilo_global_binding_cso, i);
762      const uint32_t offset = *cso->handle & ((1 << shift) - 1);
763
764      *cso->handle = ((base + i) << shift) | offset;
765   }
766}
767
768void
769ilo_finalize_compute_states(struct ilo_context *ilo)
770{
771   finalize_global_binding(&ilo->state_vector);
772}
773
774static void *
775ilo_create_blend_state(struct pipe_context *pipe,
776                       const struct pipe_blend_state *state)
777{
778   const struct ilo_dev *dev = ilo_context(pipe)->dev;
779   struct ilo_state_cc_info *info;
780   struct ilo_blend_state *blend;
781   int i;
782
783   blend = CALLOC_STRUCT(ilo_blend_state);
784   assert(blend);
785
786   info = &blend->info;
787
788   info->alpha.cv_float_source0_alpha = true;
789   info->alpha.cv_sample_count_one = true;
790   info->alpha.alpha_to_one = state->alpha_to_one;
791   info->alpha.alpha_to_coverage = state->alpha_to_coverage;
792   info->alpha.test_enable = false;
793   info->alpha.test_func = GEN6_COMPAREFUNCTION_ALWAYS;
794
795   info->stencil.cv_has_buffer = true;
796   info->depth.cv_has_buffer= true;
797
798   info->blend.rt = blend->effective_rt;
799   info->blend.rt_count = 1;
800   info->blend.dither_enable = state->dither;
801
802   for (i = 0; i < ARRAY_SIZE(blend->rt); i++) {
803      const struct pipe_rt_blend_state *rt = &state->rt[i];
804      struct ilo_state_cc_blend_rt_info *rt_info = &blend->rt[i];
805
806      rt_info->cv_has_buffer = true;
807      rt_info->cv_is_unorm = true;
808      rt_info->cv_is_integer = false;
809
810      /* logic op takes precedence over blending */
811      if (state->logicop_enable) {
812         rt_info->logicop_enable = true;
813         rt_info->logicop_func = ilo_translate_logicop(state->logicop_func);
814      } else if (rt->blend_enable) {
815         rt_info->blend_enable = true;
816
817         rt_info->rgb_src = ilo_translate_blend_factor(rt->rgb_src_factor);
818         rt_info->rgb_dst = ilo_translate_blend_factor(rt->rgb_dst_factor);
819         rt_info->rgb_func = ilo_translate_blend_func(rt->rgb_func);
820
821         rt_info->a_src = ilo_translate_blend_factor(rt->alpha_src_factor);
822         rt_info->a_dst = ilo_translate_blend_factor(rt->alpha_dst_factor);
823         rt_info->a_func = ilo_translate_blend_func(rt->alpha_func);
824      }
825
826      if (!(rt->colormask & PIPE_MASK_A))
827         rt_info->argb_write_disables |= (1 << 3);
828      if (!(rt->colormask & PIPE_MASK_R))
829         rt_info->argb_write_disables |= (1 << 2);
830      if (!(rt->colormask & PIPE_MASK_G))
831         rt_info->argb_write_disables |= (1 << 1);
832      if (!(rt->colormask & PIPE_MASK_B))
833         rt_info->argb_write_disables |= (1 << 0);
834
835      if (!state->independent_blend_enable) {
836         for (i = 1; i < ARRAY_SIZE(blend->rt); i++)
837            blend->rt[i] = *rt_info;
838         break;
839      }
840   }
841
842   memcpy(blend->effective_rt, blend->rt, sizeof(blend->rt));
843
844   blend->dummy_rt.argb_write_disables = 0xf;
845
846   if (!ilo_state_cc_init(&blend->cc, dev, &blend->info)) {
847      FREE(blend);
848      return NULL;
849   }
850
851   blend->dual_blend = util_blend_state_is_dual(state, 0);
852
853   return blend;
854}
855
856static void
857ilo_bind_blend_state(struct pipe_context *pipe, void *state)
858{
859   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
860
861   vec->blend = state;
862
863   vec->dirty |= ILO_DIRTY_BLEND;
864}
865
866static void
867ilo_delete_blend_state(struct pipe_context *pipe, void  *state)
868{
869   FREE(state);
870}
871
872static void *
873ilo_create_sampler_state(struct pipe_context *pipe,
874                         const struct pipe_sampler_state *state)
875{
876   const struct ilo_dev *dev = ilo_context(pipe)->dev;
877   struct ilo_sampler_cso *sampler;
878   struct ilo_state_sampler_info info;
879   struct ilo_state_sampler_border_info border;
880
881   sampler = CALLOC_STRUCT(ilo_sampler_cso);
882   assert(sampler);
883
884   memset(&info, 0, sizeof(info));
885
886   info.non_normalized = !state->normalized_coords;
887   if (state->normalized_coords) {
888      info.lod_bias = state->lod_bias;
889      info.min_lod = state->min_lod;
890      info.max_lod = state->max_lod;
891
892      info.mip_filter = ilo_translate_mip_filter(state->min_mip_filter);
893   } else {
894      /* work around a bug in util_blitter */
895      info.mip_filter = GEN6_MIPFILTER_NONE;
896   }
897
898   if (state->max_anisotropy) {
899      info.min_filter = GEN6_MAPFILTER_ANISOTROPIC;
900      info.mag_filter = GEN6_MAPFILTER_ANISOTROPIC;
901   } else {
902      info.min_filter = ilo_translate_img_filter(state->min_img_filter);
903      info.mag_filter = ilo_translate_img_filter(state->mag_img_filter);
904   }
905
906   info.max_anisotropy = ilo_translate_max_anisotropy(state->max_anisotropy);
907
908   /* use LOD 0 when no mipmapping (see sampler_set_gen6_SAMPLER_STATE()) */
909   if (info.mip_filter == GEN6_MIPFILTER_NONE && info.min_lod > 0.0f) {
910      info.min_lod = 0.0f;
911      info.mag_filter = info.min_filter;
912   }
913
914   if (state->seamless_cube_map) {
915      if (state->min_img_filter == PIPE_TEX_FILTER_NEAREST ||
916          state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) {
917         info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP;
918         info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
919         info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
920      } else {
921         info.tcx_ctrl = GEN6_TEXCOORDMODE_CUBE;
922         info.tcy_ctrl = GEN6_TEXCOORDMODE_CUBE;
923         info.tcz_ctrl = GEN6_TEXCOORDMODE_CUBE;
924      }
925   } else {
926      info.tcx_ctrl = ilo_translate_address_wrap(state->wrap_s);
927      info.tcy_ctrl = ilo_translate_address_wrap(state->wrap_t);
928      info.tcz_ctrl = ilo_translate_address_wrap(state->wrap_r);
929
930      if (ilo_dev_gen(dev) < ILO_GEN(8)) {
931         /*
932          * For nearest filtering, PIPE_TEX_WRAP_CLAMP means
933          * PIPE_TEX_WRAP_CLAMP_TO_EDGE;  for linear filtering,
934          * PIPE_TEX_WRAP_CLAMP means PIPE_TEX_WRAP_CLAMP_TO_BORDER while
935          * additionally clamping the texture coordinates to [0.0, 1.0].
936          *
937          * PIPE_TEX_WRAP_CLAMP is not supported natively until Gen8.  The
938          * clamping has to be taken care of in the shaders.  There are two
939          * filters here, but let the minification one has a say.
940          */
941         const bool clamp_is_to_edge =
942            (state->min_img_filter == PIPE_TEX_FILTER_NEAREST);
943
944         if (clamp_is_to_edge) {
945            if (info.tcx_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
946               info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP;
947            if (info.tcy_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
948               info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
949            if (info.tcz_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
950               info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
951         } else {
952            if (info.tcx_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
953               info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
954               sampler->saturate_s = true;
955            }
956            if (info.tcy_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
957               info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
958               sampler->saturate_t = true;
959            }
960            if (info.tcz_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
961               info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
962               sampler->saturate_r = true;
963            }
964         }
965      }
966   }
967
968   if (state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
969      info.shadow_func = ilo_translate_shadow_func(state->compare_func);
970
971   ilo_state_sampler_init(&sampler->sampler, dev, &info);
972
973   memset(&border, 0, sizeof(border));
974   memcpy(border.rgba.f, state->border_color.f, sizeof(border.rgba.f));
975
976   ilo_state_sampler_border_init(&sampler->border, dev, &border);
977
978   return sampler;
979}
980
981static void
982ilo_bind_sampler_states(struct pipe_context *pipe, unsigned shader,
983                        unsigned start, unsigned count, void **samplers)
984{
985   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
986   struct ilo_sampler_state *dst = &vec->sampler[shader];
987   bool changed = false;
988   unsigned i;
989
990   assert(start + count <= Elements(dst->cso));
991
992   if (samplers) {
993      for (i = 0; i < count; i++) {
994         if (dst->cso[start + i] != samplers[i]) {
995            dst->cso[start + i] = samplers[i];
996
997            /*
998             * This function is sometimes called to reduce the number of bound
999             * samplers.  Do not consider that as a state change (and create a
1000             * new array of SAMPLER_STATE).
1001             */
1002            if (samplers[i])
1003               changed = true;
1004         }
1005      }
1006   }
1007   else {
1008      for (i = 0; i < count; i++)
1009         dst->cso[start + i] = NULL;
1010   }
1011
1012   if (changed) {
1013      switch (shader) {
1014      case PIPE_SHADER_VERTEX:
1015         vec->dirty |= ILO_DIRTY_SAMPLER_VS;
1016         break;
1017      case PIPE_SHADER_GEOMETRY:
1018         vec->dirty |= ILO_DIRTY_SAMPLER_GS;
1019         break;
1020      case PIPE_SHADER_FRAGMENT:
1021         vec->dirty |= ILO_DIRTY_SAMPLER_FS;
1022         break;
1023      case PIPE_SHADER_COMPUTE:
1024         vec->dirty |= ILO_DIRTY_SAMPLER_CS;
1025         break;
1026      }
1027   }
1028}
1029
1030static void
1031ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
1032{
1033   FREE(state);
1034}
1035
1036static void *
1037ilo_create_rasterizer_state(struct pipe_context *pipe,
1038                            const struct pipe_rasterizer_state *state)
1039{
1040   const struct ilo_dev *dev = ilo_context(pipe)->dev;
1041   struct ilo_rasterizer_state *rast;
1042   struct ilo_state_raster_info *info;
1043
1044   rast = CALLOC_STRUCT(ilo_rasterizer_state);
1045   assert(rast);
1046
1047   rast->state = *state;
1048
1049   info = &rast->info;
1050
1051   info->clip.clip_enable = true;
1052   info->clip.stats_enable = true;
1053   info->clip.viewport_count = 1;
1054   info->clip.force_rtaindex_zero = true;
1055   info->clip.user_clip_enables = state->clip_plane_enable;
1056   info->clip.gb_test_enable = true;
1057   info->clip.xy_test_enable = true;
1058   info->clip.z_far_enable = state->depth_clip;
1059   info->clip.z_near_enable = state->depth_clip;
1060   info->clip.z_near_zero = state->clip_halfz;
1061
1062   info->setup.first_vertex_provoking = state->flatshade_first;
1063   info->setup.viewport_transform = true;
1064   info->setup.scissor_enable = state->scissor;
1065   info->setup.msaa_enable = false;
1066   info->setup.line_msaa_enable = false;
1067   info->point.aa_enable = state->point_smooth;
1068   info->point.programmable_width = state->point_size_per_vertex;
1069   info->line.aa_enable = state->line_smooth;
1070   info->line.stipple_enable = state->line_stipple_enable;
1071   info->line.giq_enable = true;
1072   info->line.giq_last_pixel = state->line_last_pixel;
1073   info->tri.front_winding = ilo_translate_front_ccw(state->front_ccw);
1074   info->tri.cull_mode = ilo_translate_cull_face(state->cull_face);
1075   info->tri.fill_mode_front = ilo_translate_poly_mode(state->fill_front);
1076   info->tri.fill_mode_back = ilo_translate_poly_mode(state->fill_back);
1077   info->tri.depth_offset_format = GEN6_ZFORMAT_D24_UNORM_X8_UINT;
1078   info->tri.depth_offset_solid = state->offset_tri;
1079   info->tri.depth_offset_wireframe = state->offset_line;
1080   info->tri.depth_offset_point = state->offset_point;
1081   info->tri.poly_stipple_enable = state->poly_stipple_enable;
1082
1083   info->scan.stats_enable = true;
1084   info->scan.sample_count = 1;
1085   info->scan.pixloc =
1086      ilo_translate_half_pixel_center(state->half_pixel_center);
1087   info->scan.sample_mask = ~0u;
1088   info->scan.zw_interp = GEN6_ZW_INTERP_PIXEL;
1089   info->scan.barycentric_interps = GEN6_INTERP_PERSPECTIVE_PIXEL;
1090   info->scan.earlyz_control = GEN7_EDSC_NORMAL;
1091   info->scan.earlyz_op = ILO_STATE_RASTER_EARLYZ_NORMAL;
1092   info->scan.earlyz_stencil_clear = false;
1093
1094   info->params.any_integer_rt = false;
1095   info->params.hiz_enable = true;
1096   info->params.point_width =
1097      (state->point_size == 0.0f) ? 1.0f : state->point_size;
1098   info->params.line_width =
1099      (state->line_width == 0.0f) ? 1.0f : state->line_width;
1100
1101   info->params.depth_offset_scale = state->offset_scale;
1102   /*
1103    * Scale the constant term.  The minimum representable value used by the HW
1104    * is not large enouch to be the minimum resolvable difference.
1105    */
1106   info->params.depth_offset_const = state->offset_units * 2.0f;
1107   info->params.depth_offset_clamp = state->offset_clamp;
1108
1109   ilo_state_raster_init(&rast->rs, dev, info);
1110
1111   return rast;
1112}
1113
1114static void
1115ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state)
1116{
1117   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1118
1119   vec->rasterizer = state;
1120
1121   vec->dirty |= ILO_DIRTY_RASTERIZER;
1122}
1123
1124static void
1125ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
1126{
1127   FREE(state);
1128}
1129
1130static void *
1131ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
1132                                     const struct pipe_depth_stencil_alpha_state *state)
1133{
1134   struct ilo_dsa_state *dsa;
1135   int i;
1136
1137   dsa = CALLOC_STRUCT(ilo_dsa_state);
1138   assert(dsa);
1139
1140   dsa->depth.cv_has_buffer = true;
1141   dsa->depth.test_enable = state->depth.enabled;
1142   dsa->depth.write_enable = state->depth.writemask;
1143   dsa->depth.test_func = ilo_translate_compare_func(state->depth.func);
1144
1145   dsa->stencil.cv_has_buffer = true;
1146   for (i = 0; i < ARRAY_SIZE(state->stencil); i++) {
1147      const struct pipe_stencil_state *stencil = &state->stencil[i];
1148      struct ilo_state_cc_stencil_op_info *op;
1149
1150      if (!stencil->enabled)
1151         break;
1152
1153      if (i == 0) {
1154         dsa->stencil.test_enable = true;
1155         dsa->stencil_front.test_mask = stencil->valuemask;
1156         dsa->stencil_front.write_mask = stencil->writemask;
1157
1158         op = &dsa->stencil.front;
1159      } else {
1160         dsa->stencil.twosided_enable = true;
1161         dsa->stencil_back.test_mask = stencil->valuemask;
1162         dsa->stencil_back.write_mask = stencil->writemask;
1163
1164         op = &dsa->stencil.back;
1165      }
1166
1167      op->test_func = ilo_translate_compare_func(stencil->func);
1168      op->fail_op = ilo_translate_stencil_op(stencil->fail_op);
1169      op->zfail_op = ilo_translate_stencil_op(stencil->zfail_op);
1170      op->zpass_op = ilo_translate_stencil_op(stencil->zpass_op);
1171   }
1172
1173   dsa->alpha_test = state->alpha.enabled;
1174   dsa->alpha_ref = state->alpha.ref_value;
1175   dsa->alpha_func = ilo_translate_compare_func(state->alpha.func);
1176
1177   return dsa;
1178}
1179
1180static void
1181ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
1182{
1183   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1184
1185   vec->dsa = state;
1186   if (vec->dsa) {
1187      vec->cc_params.alpha_ref = vec->dsa->alpha_ref;
1188      vec->cc_params.stencil_front.test_mask =
1189         vec->dsa->stencil_front.test_mask;
1190      vec->cc_params.stencil_front.write_mask =
1191         vec->dsa->stencil_front.write_mask;
1192      vec->cc_params.stencil_back.test_mask =
1193         vec->dsa->stencil_back.test_mask;
1194      vec->cc_params.stencil_back.write_mask =
1195         vec->dsa->stencil_back.write_mask;
1196   }
1197
1198   vec->dirty |= ILO_DIRTY_DSA;
1199}
1200
1201static void
1202ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
1203{
1204   FREE(state);
1205}
1206
1207static void *
1208ilo_create_fs_state(struct pipe_context *pipe,
1209                    const struct pipe_shader_state *state)
1210{
1211   struct ilo_context *ilo = ilo_context(pipe);
1212   struct ilo_shader_state *shader;
1213
1214   shader = ilo_shader_create_fs(ilo->dev, state, &ilo->state_vector);
1215   assert(shader);
1216
1217   ilo_shader_cache_add(ilo->shader_cache, shader);
1218
1219   return shader;
1220}
1221
1222static void
1223ilo_bind_fs_state(struct pipe_context *pipe, void *state)
1224{
1225   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1226
1227   vec->fs = state;
1228
1229   vec->dirty |= ILO_DIRTY_FS;
1230}
1231
1232static void
1233ilo_delete_fs_state(struct pipe_context *pipe, void *state)
1234{
1235   struct ilo_context *ilo = ilo_context(pipe);
1236   struct ilo_shader_state *fs = (struct ilo_shader_state *) state;
1237
1238   ilo_shader_cache_remove(ilo->shader_cache, fs);
1239   ilo_shader_destroy(fs);
1240}
1241
1242static void *
1243ilo_create_vs_state(struct pipe_context *pipe,
1244                    const struct pipe_shader_state *state)
1245{
1246   struct ilo_context *ilo = ilo_context(pipe);
1247   struct ilo_shader_state *shader;
1248
1249   shader = ilo_shader_create_vs(ilo->dev, state, &ilo->state_vector);
1250   assert(shader);
1251
1252   ilo_shader_cache_add(ilo->shader_cache, shader);
1253
1254   return shader;
1255}
1256
1257static void
1258ilo_bind_vs_state(struct pipe_context *pipe, void *state)
1259{
1260   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1261
1262   vec->vs = state;
1263
1264   vec->dirty |= ILO_DIRTY_VS;
1265}
1266
1267static void
1268ilo_delete_vs_state(struct pipe_context *pipe, void *state)
1269{
1270   struct ilo_context *ilo = ilo_context(pipe);
1271   struct ilo_shader_state *vs = (struct ilo_shader_state *) state;
1272
1273   ilo_shader_cache_remove(ilo->shader_cache, vs);
1274   ilo_shader_destroy(vs);
1275}
1276
1277static void *
1278ilo_create_gs_state(struct pipe_context *pipe,
1279                    const struct pipe_shader_state *state)
1280{
1281   struct ilo_context *ilo = ilo_context(pipe);
1282   struct ilo_shader_state *shader;
1283
1284   shader = ilo_shader_create_gs(ilo->dev, state, &ilo->state_vector);
1285   assert(shader);
1286
1287   ilo_shader_cache_add(ilo->shader_cache, shader);
1288
1289   return shader;
1290}
1291
1292static void
1293ilo_bind_gs_state(struct pipe_context *pipe, void *state)
1294{
1295   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1296
1297   /* util_blitter may set this unnecessarily */
1298   if (vec->gs == state)
1299      return;
1300
1301   vec->gs = state;
1302
1303   vec->dirty |= ILO_DIRTY_GS;
1304}
1305
1306static void
1307ilo_delete_gs_state(struct pipe_context *pipe, void *state)
1308{
1309   struct ilo_context *ilo = ilo_context(pipe);
1310   struct ilo_shader_state *gs = (struct ilo_shader_state *) state;
1311
1312   ilo_shader_cache_remove(ilo->shader_cache, gs);
1313   ilo_shader_destroy(gs);
1314}
1315
1316static void *
1317ilo_create_vertex_elements_state(struct pipe_context *pipe,
1318                                 unsigned num_elements,
1319                                 const struct pipe_vertex_element *elements)
1320{
1321   const struct ilo_dev *dev = ilo_context(pipe)->dev;
1322   struct ilo_ve_state *ve;
1323
1324   ve = MALLOC_STRUCT(ilo_ve_state);
1325   assert(ve);
1326
1327   ilo_gpe_init_ve(dev, num_elements, elements, ve);
1328
1329   return ve;
1330}
1331
1332static void
1333ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
1334{
1335   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1336
1337   vec->ve = state;
1338
1339   vec->dirty |= ILO_DIRTY_VE;
1340}
1341
1342static void
1343ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
1344{
1345   struct ilo_ve_state *ve = state;
1346
1347   FREE(ve);
1348}
1349
1350static void
1351ilo_set_blend_color(struct pipe_context *pipe,
1352                    const struct pipe_blend_color *state)
1353{
1354   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1355
1356   memcpy(vec->cc_params.blend_rgba, state->color, sizeof(state->color));
1357
1358   vec->dirty |= ILO_DIRTY_BLEND_COLOR;
1359}
1360
1361static void
1362ilo_set_stencil_ref(struct pipe_context *pipe,
1363                    const struct pipe_stencil_ref *state)
1364{
1365   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1366
1367   /* util_blitter may set this unnecessarily */
1368   if (!memcmp(&vec->stencil_ref, state, sizeof(*state)))
1369      return;
1370
1371   vec->stencil_ref = *state;
1372
1373   vec->cc_params.stencil_front.test_ref = state->ref_value[0];
1374   vec->cc_params.stencil_back.test_ref = state->ref_value[1];
1375
1376   vec->dirty |= ILO_DIRTY_STENCIL_REF;
1377}
1378
1379static void
1380ilo_set_sample_mask(struct pipe_context *pipe,
1381                    unsigned sample_mask)
1382{
1383   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1384
1385   /* util_blitter may set this unnecessarily */
1386   if (vec->sample_mask == sample_mask)
1387      return;
1388
1389   vec->sample_mask = sample_mask;
1390
1391   vec->dirty |= ILO_DIRTY_SAMPLE_MASK;
1392}
1393
1394static void
1395ilo_set_clip_state(struct pipe_context *pipe,
1396                   const struct pipe_clip_state *state)
1397{
1398   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1399
1400   vec->clip = *state;
1401
1402   vec->dirty |= ILO_DIRTY_CLIP;
1403}
1404
1405static void
1406ilo_set_constant_buffer(struct pipe_context *pipe,
1407                        uint shader, uint index,
1408                        struct pipe_constant_buffer *buf)
1409{
1410   const struct ilo_dev *dev = ilo_context(pipe)->dev;
1411   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1412   struct ilo_cbuf_state *cbuf = &vec->cbuf[shader];
1413   const unsigned count = 1;
1414   unsigned i;
1415
1416   assert(shader < Elements(vec->cbuf));
1417   assert(index + count <= Elements(vec->cbuf[shader].cso));
1418
1419   if (buf) {
1420      for (i = 0; i < count; i++) {
1421         struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
1422
1423         pipe_resource_reference(&cso->resource, buf[i].buffer);
1424
1425         cso->info.access = ILO_STATE_SURFACE_ACCESS_DP_DATA;
1426         cso->info.format = GEN6_FORMAT_R32G32B32A32_FLOAT;
1427         cso->info.format_size = 16;
1428         cso->info.struct_size = 16;
1429         cso->info.readonly = true;
1430         cso->info.size = buf[i].buffer_size;
1431
1432         if (buf[i].buffer) {
1433            cso->info.buf = ilo_buffer(buf[i].buffer);
1434            cso->info.offset = buf[i].buffer_offset;
1435
1436            memset(&cso->surface, 0, sizeof(cso->surface));
1437            ilo_state_surface_init_for_buffer(&cso->surface, dev, &cso->info);
1438            cso->surface.bo = cso->info.buf->bo;
1439
1440            cso->user_buffer = NULL;
1441
1442            cbuf->enabled_mask |= 1 << (index + i);
1443         } else if (buf[i].user_buffer) {
1444            cso->info.buf = NULL;
1445            /* buffer_offset does not apply for user buffer */
1446            cso->user_buffer = buf[i].user_buffer;
1447
1448            cbuf->enabled_mask |= 1 << (index + i);
1449         } else {
1450            cso->info.buf = NULL;
1451            cso->info.size = 0;
1452            cso->user_buffer = NULL;
1453
1454            cbuf->enabled_mask &= ~(1 << (index + i));
1455         }
1456      }
1457   } else {
1458      for (i = 0; i < count; i++) {
1459         struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
1460
1461         pipe_resource_reference(&cso->resource, NULL);
1462
1463         cso->info.buf = NULL;
1464         cso->info.size = 0;
1465         cso->user_buffer = NULL;
1466
1467         cbuf->enabled_mask &= ~(1 << (index + i));
1468      }
1469   }
1470
1471   vec->dirty |= ILO_DIRTY_CBUF;
1472}
1473
1474static void
1475ilo_set_framebuffer_state(struct pipe_context *pipe,
1476                          const struct pipe_framebuffer_state *state)
1477{
1478   const struct ilo_dev *dev = ilo_context(pipe)->dev;
1479   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1480
1481   ilo_gpe_set_fb(dev, state, &vec->fb);
1482
1483   vec->dirty |= ILO_DIRTY_FB;
1484}
1485
1486static void
1487ilo_set_polygon_stipple(struct pipe_context *pipe,
1488                        const struct pipe_poly_stipple *state)
1489{
1490   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1491
1492   vec->poly_stipple = *state;
1493
1494   vec->dirty |= ILO_DIRTY_POLY_STIPPLE;
1495}
1496
1497static void
1498ilo_set_scissor_states(struct pipe_context *pipe,
1499                       unsigned start_slot,
1500                       unsigned num_scissors,
1501                       const struct pipe_scissor_state *scissors)
1502{
1503   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1504   unsigned i;
1505
1506   for (i = 0; i < num_scissors; i++) {
1507      struct ilo_state_viewport_scissor_info *info =
1508         &vec->viewport.scissors[start_slot + i];
1509
1510      if (scissors[i].minx < scissors[i].maxx &&
1511          scissors[i].miny < scissors[i].maxy) {
1512         info->min_x = scissors[i].minx;
1513         info->min_y = scissors[i].miny;
1514         info->max_x = scissors[i].maxx - 1;
1515         info->max_y = scissors[i].maxy - 1;
1516      } else {
1517         info->min_x = 1;
1518         info->min_y = 1;
1519         info->max_x = 0;
1520         info->max_y = 0;
1521      }
1522   }
1523
1524   vec->dirty |= ILO_DIRTY_SCISSOR;
1525}
1526
1527static void
1528ilo_set_viewport_states(struct pipe_context *pipe,
1529                        unsigned start_slot,
1530                        unsigned num_viewports,
1531                        const struct pipe_viewport_state *viewports)
1532{
1533   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1534
1535   if (viewports) {
1536      unsigned i;
1537
1538      for (i = 0; i < num_viewports; i++) {
1539         struct ilo_state_viewport_matrix_info *info =
1540            &vec->viewport.matrices[start_slot + i];
1541
1542         memcpy(info->scale, viewports[i].scale, sizeof(info->scale));
1543         memcpy(info->translate, viewports[i].translate,
1544               sizeof(info->translate));
1545      }
1546
1547      if (vec->viewport.params.count < start_slot + num_viewports)
1548         vec->viewport.params.count = start_slot + num_viewports;
1549
1550      /* need to save viewport 0 for util_blitter */
1551      if (!start_slot && num_viewports)
1552         vec->viewport.viewport0 = viewports[0];
1553   }
1554   else {
1555      if (vec->viewport.params.count <= start_slot + num_viewports &&
1556          vec->viewport.params.count > start_slot)
1557         vec->viewport.params.count = start_slot;
1558   }
1559
1560   vec->dirty |= ILO_DIRTY_VIEWPORT;
1561}
1562
1563static void
1564ilo_set_sampler_views(struct pipe_context *pipe, unsigned shader,
1565                      unsigned start, unsigned count,
1566                      struct pipe_sampler_view **views)
1567{
1568   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1569   struct ilo_view_state *dst = &vec->view[shader];
1570   unsigned i;
1571
1572   assert(start + count <= Elements(dst->states));
1573
1574   if (views) {
1575      for (i = 0; i < count; i++)
1576         pipe_sampler_view_reference(&dst->states[start + i], views[i]);
1577   }
1578   else {
1579      for (i = 0; i < count; i++)
1580         pipe_sampler_view_reference(&dst->states[start + i], NULL);
1581   }
1582
1583   if (dst->count <= start + count) {
1584      if (views)
1585         count += start;
1586      else
1587         count = start;
1588
1589      while (count > 0 && !dst->states[count - 1])
1590         count--;
1591
1592      dst->count = count;
1593   }
1594
1595   switch (shader) {
1596   case PIPE_SHADER_VERTEX:
1597      vec->dirty |= ILO_DIRTY_VIEW_VS;
1598      break;
1599   case PIPE_SHADER_GEOMETRY:
1600      vec->dirty |= ILO_DIRTY_VIEW_GS;
1601      break;
1602   case PIPE_SHADER_FRAGMENT:
1603      vec->dirty |= ILO_DIRTY_VIEW_FS;
1604      break;
1605   case PIPE_SHADER_COMPUTE:
1606      vec->dirty |= ILO_DIRTY_VIEW_CS;
1607      break;
1608   }
1609}
1610
1611static void
1612ilo_set_shader_resources(struct pipe_context *pipe,
1613                         unsigned start, unsigned count,
1614                         struct pipe_surface **surfaces)
1615{
1616   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1617   struct ilo_resource_state *dst = &vec->resource;
1618   unsigned i;
1619
1620   assert(start + count <= Elements(dst->states));
1621
1622   if (surfaces) {
1623      for (i = 0; i < count; i++)
1624         pipe_surface_reference(&dst->states[start + i], surfaces[i]);
1625   }
1626   else {
1627      for (i = 0; i < count; i++)
1628         pipe_surface_reference(&dst->states[start + i], NULL);
1629   }
1630
1631   if (dst->count <= start + count) {
1632      if (surfaces)
1633         count += start;
1634      else
1635         count = start;
1636
1637      while (count > 0 && !dst->states[count - 1])
1638         count--;
1639
1640      dst->count = count;
1641   }
1642
1643   vec->dirty |= ILO_DIRTY_RESOURCE;
1644}
1645
1646static void
1647ilo_set_vertex_buffers(struct pipe_context *pipe,
1648                       unsigned start_slot, unsigned num_buffers,
1649                       const struct pipe_vertex_buffer *buffers)
1650{
1651   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1652   unsigned i;
1653
1654   /* no PIPE_CAP_USER_VERTEX_BUFFERS */
1655   if (buffers) {
1656      for (i = 0; i < num_buffers; i++)
1657         assert(!buffers[i].user_buffer);
1658   }
1659
1660   util_set_vertex_buffers_mask(vec->vb.states,
1661         &vec->vb.enabled_mask, buffers, start_slot, num_buffers);
1662
1663   vec->dirty |= ILO_DIRTY_VB;
1664}
1665
1666static void
1667ilo_set_index_buffer(struct pipe_context *pipe,
1668                     const struct pipe_index_buffer *state)
1669{
1670   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1671
1672   if (state) {
1673      pipe_resource_reference(&vec->ib.buffer, state->buffer);
1674      vec->ib.user_buffer = state->user_buffer;
1675      vec->ib.offset = state->offset;
1676      vec->ib.index_size = state->index_size;
1677   }
1678   else {
1679      pipe_resource_reference(&vec->ib.buffer, NULL);
1680      vec->ib.user_buffer = NULL;
1681      vec->ib.offset = 0;
1682      vec->ib.index_size = 0;
1683   }
1684
1685   vec->dirty |= ILO_DIRTY_IB;
1686}
1687
1688static struct pipe_stream_output_target *
1689ilo_create_stream_output_target(struct pipe_context *pipe,
1690                                struct pipe_resource *res,
1691                                unsigned buffer_offset,
1692                                unsigned buffer_size)
1693{
1694   struct pipe_stream_output_target *target;
1695
1696   target = MALLOC_STRUCT(pipe_stream_output_target);
1697   assert(target);
1698
1699   pipe_reference_init(&target->reference, 1);
1700   target->buffer = NULL;
1701   pipe_resource_reference(&target->buffer, res);
1702   target->context = pipe;
1703   target->buffer_offset = buffer_offset;
1704   target->buffer_size = buffer_size;
1705
1706   return target;
1707}
1708
1709static void
1710ilo_set_stream_output_targets(struct pipe_context *pipe,
1711                              unsigned num_targets,
1712                              struct pipe_stream_output_target **targets,
1713                              const unsigned *offset)
1714{
1715   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1716   unsigned i;
1717   unsigned append_bitmask = 0;
1718
1719   if (!targets)
1720      num_targets = 0;
1721
1722   /* util_blitter may set this unnecessarily */
1723   if (!vec->so.count && !num_targets)
1724      return;
1725
1726   for (i = 0; i < num_targets; i++) {
1727      pipe_so_target_reference(&vec->so.states[i], targets[i]);
1728      if (offset[i] == (unsigned)-1)
1729         append_bitmask |= 1 << i;
1730   }
1731
1732   for (; i < vec->so.count; i++)
1733      pipe_so_target_reference(&vec->so.states[i], NULL);
1734
1735   vec->so.count = num_targets;
1736   vec->so.append_bitmask = append_bitmask;
1737
1738   vec->so.enabled = (vec->so.count > 0);
1739
1740   vec->dirty |= ILO_DIRTY_SO;
1741}
1742
1743static void
1744ilo_stream_output_target_destroy(struct pipe_context *pipe,
1745                                 struct pipe_stream_output_target *target)
1746{
1747   pipe_resource_reference(&target->buffer, NULL);
1748   FREE(target);
1749}
1750
1751static struct pipe_sampler_view *
1752ilo_create_sampler_view(struct pipe_context *pipe,
1753                        struct pipe_resource *res,
1754                        const struct pipe_sampler_view *templ)
1755{
1756   const struct ilo_dev *dev = ilo_context(pipe)->dev;
1757   struct ilo_view_cso *view;
1758
1759   view = CALLOC_STRUCT(ilo_view_cso);
1760   assert(view);
1761
1762   view->base = *templ;
1763   pipe_reference_init(&view->base.reference, 1);
1764   view->base.texture = NULL;
1765   pipe_resource_reference(&view->base.texture, res);
1766   view->base.context = pipe;
1767
1768   if (res->target == PIPE_BUFFER) {
1769      struct ilo_state_surface_buffer_info info;
1770
1771      memset(&info, 0, sizeof(info));
1772      info.buf = ilo_buffer(res);
1773      info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
1774      info.format = ilo_format_translate_color(dev, templ->format);
1775      info.format_size = util_format_get_blocksize(templ->format);
1776      info.struct_size = info.format_size;
1777      info.readonly = true;
1778      info.offset = templ->u.buf.first_element * info.struct_size;
1779      info.size = (templ->u.buf.last_element -
1780            templ->u.buf.first_element + 1) * info.struct_size;
1781
1782      ilo_state_surface_init_for_buffer(&view->surface, dev, &info);
1783      view->surface.bo = info.buf->bo;
1784   } else {
1785      struct ilo_texture *tex = ilo_texture(res);
1786      struct ilo_state_surface_image_info info;
1787
1788      /* warn about degraded performance because of a missing binding flag */
1789      if (tex->image.tiling == GEN6_TILING_NONE &&
1790          !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) {
1791         ilo_warn("creating sampler view for a resource "
1792                  "not created for sampling\n");
1793      }
1794
1795      memset(&info, 0, sizeof(info));
1796      info.img = &tex->image;
1797
1798      info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
1799
1800      if (templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
1801          tex->image.separate_stencil) {
1802         info.format = ilo_format_translate_texture(dev,
1803               PIPE_FORMAT_Z32_FLOAT);
1804      } else {
1805         info.format = ilo_format_translate_texture(dev, templ->format);
1806      }
1807
1808      info.is_cube_map = (tex->image.target == PIPE_TEXTURE_CUBE ||
1809                          tex->image.target == PIPE_TEXTURE_CUBE_ARRAY);
1810      info.is_array = util_resource_is_array_texture(&tex->base);
1811      info.readonly = true;
1812
1813      info.level_base = templ->u.tex.first_level;
1814      info.level_count = templ->u.tex.last_level -
1815         templ->u.tex.first_level + 1;
1816      info.slice_base = templ->u.tex.first_layer;
1817      info.slice_count = templ->u.tex.last_layer -
1818         templ->u.tex.first_layer + 1;
1819
1820      ilo_state_surface_init_for_image(&view->surface, dev, &info);
1821      view->surface.bo = info.img->bo;
1822   }
1823
1824   return &view->base;
1825}
1826
1827static void
1828ilo_sampler_view_destroy(struct pipe_context *pipe,
1829                         struct pipe_sampler_view *view)
1830{
1831   pipe_resource_reference(&view->texture, NULL);
1832   FREE(view);
1833}
1834
1835static struct pipe_surface *
1836ilo_create_surface(struct pipe_context *pipe,
1837                   struct pipe_resource *res,
1838                   const struct pipe_surface *templ)
1839{
1840   const struct ilo_dev *dev = ilo_context(pipe)->dev;
1841   struct ilo_texture *tex = ilo_texture(res);
1842   struct ilo_surface_cso *surf;
1843
1844   surf = CALLOC_STRUCT(ilo_surface_cso);
1845   assert(surf);
1846
1847   surf->base = *templ;
1848   pipe_reference_init(&surf->base.reference, 1);
1849   surf->base.texture = NULL;
1850   pipe_resource_reference(&surf->base.texture, &tex->base);
1851
1852   surf->base.context = pipe;
1853   surf->base.width = u_minify(tex->base.width0, templ->u.tex.level);
1854   surf->base.height = u_minify(tex->base.height0, templ->u.tex.level);
1855
1856   surf->is_rt = !util_format_is_depth_or_stencil(templ->format);
1857
1858   if (surf->is_rt) {
1859      struct ilo_state_surface_image_info info;
1860
1861      /* relax this? */
1862      assert(tex->base.target != PIPE_BUFFER);
1863
1864      memset(&info, 0, sizeof(info));
1865      info.img = &tex->image;
1866      info.access = ILO_STATE_SURFACE_ACCESS_DP_RENDER;
1867      info.format = ilo_format_translate_render(dev, templ->format);
1868      info.is_array = util_resource_is_array_texture(&tex->base);
1869      info.level_base = templ->u.tex.level;
1870      info.level_count = 1;
1871      info.slice_base = templ->u.tex.first_layer;
1872      info.slice_count = templ->u.tex.last_layer -
1873         templ->u.tex.first_layer + 1;
1874
1875      ilo_state_surface_init_for_image(&surf->u.rt, dev, &info);
1876      surf->u.rt.bo = info.img->bo;
1877   } else {
1878      struct ilo_state_zs_info info;
1879
1880      assert(res->target != PIPE_BUFFER);
1881
1882      memset(&info, 0, sizeof(info));
1883
1884      if (templ->format == PIPE_FORMAT_S8_UINT) {
1885         info.s_img = &tex->image;
1886      } else {
1887         info.z_img = &tex->image;
1888         info.s_img = (tex->separate_s8) ? &tex->separate_s8->image : NULL;
1889
1890         info.hiz_enable =
1891            ilo_image_can_enable_aux(&tex->image, templ->u.tex.level);
1892      }
1893
1894      info.level = templ->u.tex.level;
1895      info.slice_base = templ->u.tex.first_layer;
1896      info.slice_count = templ->u.tex.last_layer -
1897         templ->u.tex.first_layer + 1;
1898
1899      ilo_state_zs_init(&surf->u.zs, dev, &info);
1900
1901      if (info.z_img) {
1902         surf->u.zs.depth_bo = info.z_img->bo;
1903         if (info.hiz_enable)
1904            surf->u.zs.hiz_bo = info.z_img->aux.bo;
1905      }
1906
1907      if (info.s_img)
1908         surf->u.zs.stencil_bo = info.s_img->bo;
1909   }
1910
1911   return &surf->base;
1912}
1913
1914static void
1915ilo_surface_destroy(struct pipe_context *pipe,
1916                    struct pipe_surface *surface)
1917{
1918   pipe_resource_reference(&surface->texture, NULL);
1919   FREE(surface);
1920}
1921
1922static void *
1923ilo_create_compute_state(struct pipe_context *pipe,
1924                         const struct pipe_compute_state *state)
1925{
1926   struct ilo_context *ilo = ilo_context(pipe);
1927   struct ilo_shader_state *shader;
1928
1929   shader = ilo_shader_create_cs(ilo->dev, state, &ilo->state_vector);
1930   assert(shader);
1931
1932   ilo_shader_cache_add(ilo->shader_cache, shader);
1933
1934   return shader;
1935}
1936
1937static void
1938ilo_bind_compute_state(struct pipe_context *pipe, void *state)
1939{
1940   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1941
1942   vec->cs = state;
1943
1944   vec->dirty |= ILO_DIRTY_CS;
1945}
1946
1947static void
1948ilo_delete_compute_state(struct pipe_context *pipe, void *state)
1949{
1950   struct ilo_context *ilo = ilo_context(pipe);
1951   struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
1952
1953   ilo_shader_cache_remove(ilo->shader_cache, cs);
1954   ilo_shader_destroy(cs);
1955}
1956
1957static void
1958ilo_set_compute_resources(struct pipe_context *pipe,
1959                          unsigned start, unsigned count,
1960                          struct pipe_surface **surfaces)
1961{
1962   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1963   struct ilo_resource_state *dst = &vec->cs_resource;
1964   unsigned i;
1965
1966   assert(start + count <= Elements(dst->states));
1967
1968   if (surfaces) {
1969      for (i = 0; i < count; i++)
1970         pipe_surface_reference(&dst->states[start + i], surfaces[i]);
1971   }
1972   else {
1973      for (i = 0; i < count; i++)
1974         pipe_surface_reference(&dst->states[start + i], NULL);
1975   }
1976
1977   if (dst->count <= start + count) {
1978      if (surfaces)
1979         count += start;
1980      else
1981         count = start;
1982
1983      while (count > 0 && !dst->states[count - 1])
1984         count--;
1985
1986      dst->count = count;
1987   }
1988
1989   vec->dirty |= ILO_DIRTY_CS_RESOURCE;
1990}
1991
1992static void
1993ilo_set_global_binding(struct pipe_context *pipe,
1994                       unsigned start, unsigned count,
1995                       struct pipe_resource **resources,
1996                       uint32_t **handles)
1997{
1998   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1999   struct ilo_global_binding_cso *dst;
2000   unsigned i;
2001
2002   /* make room */
2003   if (vec->global_binding.count < start + count) {
2004      if (resources) {
2005         const unsigned old_size = vec->global_binding.bindings.size;
2006         const unsigned new_size = sizeof(*dst) * (start + count);
2007
2008         if (old_size < new_size) {
2009            util_dynarray_resize(&vec->global_binding.bindings, new_size);
2010            memset(vec->global_binding.bindings.data + old_size, 0,
2011                  new_size - old_size);
2012         }
2013      } else {
2014         count = vec->global_binding.count - start;
2015      }
2016   }
2017
2018   dst = util_dynarray_element(&vec->global_binding.bindings,
2019         struct ilo_global_binding_cso, start);
2020
2021   if (resources) {
2022      for (i = 0; i < count; i++) {
2023         pipe_resource_reference(&dst[i].resource, resources[i]);
2024         dst[i].handle = handles[i];
2025      }
2026   } else {
2027      for (i = 0; i < count; i++) {
2028         pipe_resource_reference(&dst[i].resource, NULL);
2029         dst[i].handle = NULL;
2030      }
2031   }
2032
2033   if (vec->global_binding.count <= start + count) {
2034      dst = util_dynarray_begin(&vec->global_binding.bindings);
2035
2036      if (resources)
2037         count += start;
2038      else
2039         count = start;
2040
2041      while (count > 0 && !dst[count - 1].resource)
2042         count--;
2043
2044      vec->global_binding.count = count;
2045   }
2046
2047   vec->dirty |= ILO_DIRTY_GLOBAL_BINDING;
2048}
2049
2050/**
2051 * Initialize state-related functions.
2052 */
2053void
2054ilo_init_state_functions(struct ilo_context *ilo)
2055{
2056   STATIC_ASSERT(ILO_STATE_COUNT <= 32);
2057
2058   ilo->base.create_blend_state = ilo_create_blend_state;
2059   ilo->base.bind_blend_state = ilo_bind_blend_state;
2060   ilo->base.delete_blend_state = ilo_delete_blend_state;
2061   ilo->base.create_sampler_state = ilo_create_sampler_state;
2062   ilo->base.bind_sampler_states = ilo_bind_sampler_states;
2063   ilo->base.delete_sampler_state = ilo_delete_sampler_state;
2064   ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
2065   ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
2066   ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
2067   ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
2068   ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
2069   ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
2070   ilo->base.create_fs_state = ilo_create_fs_state;
2071   ilo->base.bind_fs_state = ilo_bind_fs_state;
2072   ilo->base.delete_fs_state = ilo_delete_fs_state;
2073   ilo->base.create_vs_state = ilo_create_vs_state;
2074   ilo->base.bind_vs_state = ilo_bind_vs_state;
2075   ilo->base.delete_vs_state = ilo_delete_vs_state;
2076   ilo->base.create_gs_state = ilo_create_gs_state;
2077   ilo->base.bind_gs_state = ilo_bind_gs_state;
2078   ilo->base.delete_gs_state = ilo_delete_gs_state;
2079   ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
2080   ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
2081   ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
2082
2083   ilo->base.set_blend_color = ilo_set_blend_color;
2084   ilo->base.set_stencil_ref = ilo_set_stencil_ref;
2085   ilo->base.set_sample_mask = ilo_set_sample_mask;
2086   ilo->base.set_clip_state = ilo_set_clip_state;
2087   ilo->base.set_constant_buffer = ilo_set_constant_buffer;
2088   ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
2089   ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
2090   ilo->base.set_scissor_states = ilo_set_scissor_states;
2091   ilo->base.set_viewport_states = ilo_set_viewport_states;
2092   ilo->base.set_sampler_views = ilo_set_sampler_views;
2093   ilo->base.set_shader_resources = ilo_set_shader_resources;
2094   ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
2095   ilo->base.set_index_buffer = ilo_set_index_buffer;
2096
2097   ilo->base.create_stream_output_target = ilo_create_stream_output_target;
2098   ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
2099   ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
2100
2101   ilo->base.create_sampler_view = ilo_create_sampler_view;
2102   ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
2103
2104   ilo->base.create_surface = ilo_create_surface;
2105   ilo->base.surface_destroy = ilo_surface_destroy;
2106
2107   ilo->base.create_compute_state = ilo_create_compute_state;
2108   ilo->base.bind_compute_state = ilo_bind_compute_state;
2109   ilo->base.delete_compute_state = ilo_delete_compute_state;
2110   ilo->base.set_compute_resources = ilo_set_compute_resources;
2111   ilo->base.set_global_binding = ilo_set_global_binding;
2112}
2113
2114void
2115ilo_state_vector_init(const struct ilo_dev *dev,
2116                      struct ilo_state_vector *vec)
2117{
2118   struct ilo_state_urb_info urb_info;
2119
2120   vec->sample_mask = ~0u;
2121
2122   ilo_state_viewport_init_data_only(&vec->viewport.vp, dev,
2123         vec->viewport.vp_data, sizeof(vec->viewport.vp_data));
2124   assert(vec->viewport.vp.array_size >= ILO_MAX_VIEWPORTS);
2125
2126   vec->viewport.params.matrices = vec->viewport.matrices;
2127   vec->viewport.params.scissors = vec->viewport.scissors;
2128
2129   ilo_state_surface_init_for_null(&vec->fb.null_rt, dev);
2130   ilo_state_zs_init_for_null(&vec->fb.null_zs, dev);
2131
2132   ilo_state_sampler_init_disabled(&vec->disabled_sampler, dev);
2133
2134   memset(&urb_info, 0, sizeof(urb_info));
2135   ilo_state_urb_init(&vec->urb, dev, &urb_info);
2136
2137   util_dynarray_init(&vec->global_binding.bindings);
2138
2139   vec->dirty = ILO_DIRTY_ALL;
2140}
2141
2142void
2143ilo_state_vector_cleanup(struct ilo_state_vector *vec)
2144{
2145   unsigned i, sh;
2146
2147   for (i = 0; i < Elements(vec->vb.states); i++) {
2148      if (vec->vb.enabled_mask & (1 << i))
2149         pipe_resource_reference(&vec->vb.states[i].buffer, NULL);
2150   }
2151
2152   pipe_resource_reference(&vec->ib.buffer, NULL);
2153   pipe_resource_reference(&vec->ib.hw_resource, NULL);
2154
2155   for (i = 0; i < vec->so.count; i++)
2156      pipe_so_target_reference(&vec->so.states[i], NULL);
2157
2158   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
2159      for (i = 0; i < vec->view[sh].count; i++) {
2160         struct pipe_sampler_view *view = vec->view[sh].states[i];
2161         pipe_sampler_view_reference(&view, NULL);
2162      }
2163
2164      for (i = 0; i < Elements(vec->cbuf[sh].cso); i++) {
2165         struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
2166         pipe_resource_reference(&cbuf->resource, NULL);
2167      }
2168   }
2169
2170   for (i = 0; i < vec->resource.count; i++)
2171      pipe_surface_reference(&vec->resource.states[i], NULL);
2172
2173   for (i = 0; i < vec->fb.state.nr_cbufs; i++)
2174      pipe_surface_reference(&vec->fb.state.cbufs[i], NULL);
2175
2176   if (vec->fb.state.zsbuf)
2177      pipe_surface_reference(&vec->fb.state.zsbuf, NULL);
2178
2179   for (i = 0; i < vec->cs_resource.count; i++)
2180      pipe_surface_reference(&vec->cs_resource.states[i], NULL);
2181
2182   for (i = 0; i < vec->global_binding.count; i++) {
2183      struct ilo_global_binding_cso *cso =
2184         util_dynarray_element(&vec->global_binding.bindings,
2185               struct ilo_global_binding_cso, i);
2186      pipe_resource_reference(&cso->resource, NULL);
2187   }
2188
2189   util_dynarray_fini(&vec->global_binding.bindings);
2190}
2191
2192/**
2193 * Mark all states that have the resource dirty.
2194 */
2195void
2196ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
2197                                  struct pipe_resource *res)
2198{
2199   struct intel_bo *bo = ilo_resource_get_bo(res);
2200   uint32_t states = 0;
2201   unsigned sh, i;
2202
2203   if (res->target == PIPE_BUFFER) {
2204      uint32_t vb_mask = vec->vb.enabled_mask;
2205
2206      while (vb_mask) {
2207         const unsigned idx = u_bit_scan(&vb_mask);
2208
2209         if (vec->vb.states[idx].buffer == res) {
2210            states |= ILO_DIRTY_VB;
2211            break;
2212         }
2213      }
2214
2215      if (vec->ib.buffer == res) {
2216         states |= ILO_DIRTY_IB;
2217
2218         /*
2219          * finalize_index_buffer() has an optimization that clears
2220          * ILO_DIRTY_IB when the HW states do not change.  However, it fails
2221          * to flush the VF cache when the HW states do not change, but the
2222          * contents of the IB has changed.  Here, we set the index size to an
2223          * invalid value to avoid the optimization.
2224          */
2225         vec->ib.hw_index_size = 0;
2226      }
2227
2228      for (i = 0; i < vec->so.count; i++) {
2229         if (vec->so.states[i]->buffer == res) {
2230            states |= ILO_DIRTY_SO;
2231            break;
2232         }
2233      }
2234   }
2235
2236   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
2237      for (i = 0; i < vec->view[sh].count; i++) {
2238         struct ilo_view_cso *cso = (struct ilo_view_cso *) vec->view[sh].states[i];
2239
2240         if (cso->base.texture == res) {
2241            static const unsigned view_dirty_bits[PIPE_SHADER_TYPES] = {
2242               [PIPE_SHADER_VERTEX]    = ILO_DIRTY_VIEW_VS,
2243               [PIPE_SHADER_FRAGMENT]  = ILO_DIRTY_VIEW_FS,
2244               [PIPE_SHADER_GEOMETRY]  = ILO_DIRTY_VIEW_GS,
2245               [PIPE_SHADER_COMPUTE]   = ILO_DIRTY_VIEW_CS,
2246            };
2247            cso->surface.bo = bo;
2248
2249            states |= view_dirty_bits[sh];
2250            break;
2251         }
2252      }
2253
2254      if (res->target == PIPE_BUFFER) {
2255         for (i = 0; i < Elements(vec->cbuf[sh].cso); i++) {
2256            struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
2257
2258            if (cbuf->resource == res) {
2259               cbuf->surface.bo = bo;
2260               states |= ILO_DIRTY_CBUF;
2261               break;
2262            }
2263         }
2264      }
2265   }
2266
2267   for (i = 0; i < vec->resource.count; i++) {
2268      struct ilo_surface_cso *cso =
2269         (struct ilo_surface_cso *) vec->resource.states[i];
2270
2271      if (cso->base.texture == res) {
2272         cso->u.rt.bo = bo;
2273         states |= ILO_DIRTY_RESOURCE;
2274         break;
2275      }
2276   }
2277
2278   /* for now? */
2279   if (res->target != PIPE_BUFFER) {
2280      for (i = 0; i < vec->fb.state.nr_cbufs; i++) {
2281         struct ilo_surface_cso *cso =
2282            (struct ilo_surface_cso *) vec->fb.state.cbufs[i];
2283         if (cso && cso->base.texture == res) {
2284            cso->u.rt.bo = bo;
2285            states |= ILO_DIRTY_FB;
2286            break;
2287         }
2288      }
2289
2290      if (vec->fb.state.zsbuf && vec->fb.state.zsbuf->texture == res) {
2291         struct ilo_surface_cso *cso =
2292            (struct ilo_surface_cso *) vec->fb.state.zsbuf;
2293
2294         cso->u.zs.depth_bo = bo;
2295
2296         states |= ILO_DIRTY_FB;
2297      }
2298   }
2299
2300   for (i = 0; i < vec->cs_resource.count; i++) {
2301      struct ilo_surface_cso *cso =
2302         (struct ilo_surface_cso *) vec->cs_resource.states[i];
2303      if (cso->base.texture == res) {
2304         cso->u.rt.bo = bo;
2305         states |= ILO_DIRTY_CS_RESOURCE;
2306         break;
2307      }
2308   }
2309
2310   for (i = 0; i < vec->global_binding.count; i++) {
2311      struct ilo_global_binding_cso *cso =
2312         util_dynarray_element(&vec->global_binding.bindings,
2313               struct ilo_global_binding_cso, i);
2314
2315      if (cso->resource == res) {
2316         states |= ILO_DIRTY_GLOBAL_BINDING;
2317         break;
2318      }
2319   }
2320
2321   vec->dirty |= states;
2322}
2323
2324void
2325ilo_state_vector_dump_dirty(const struct ilo_state_vector *vec)
2326{
2327   static const char *state_names[ILO_STATE_COUNT] = {
2328      [ILO_STATE_VB]              = "VB",
2329      [ILO_STATE_VE]              = "VE",
2330      [ILO_STATE_IB]              = "IB",
2331      [ILO_STATE_VS]              = "VS",
2332      [ILO_STATE_GS]              = "GS",
2333      [ILO_STATE_SO]              = "SO",
2334      [ILO_STATE_CLIP]            = "CLIP",
2335      [ILO_STATE_VIEWPORT]        = "VIEWPORT",
2336      [ILO_STATE_SCISSOR]         = "SCISSOR",
2337      [ILO_STATE_RASTERIZER]      = "RASTERIZER",
2338      [ILO_STATE_POLY_STIPPLE]    = "POLY_STIPPLE",
2339      [ILO_STATE_SAMPLE_MASK]     = "SAMPLE_MASK",
2340      [ILO_STATE_FS]              = "FS",
2341      [ILO_STATE_DSA]             = "DSA",
2342      [ILO_STATE_STENCIL_REF]     = "STENCIL_REF",
2343      [ILO_STATE_BLEND]           = "BLEND",
2344      [ILO_STATE_BLEND_COLOR]     = "BLEND_COLOR",
2345      [ILO_STATE_FB]              = "FB",
2346      [ILO_STATE_SAMPLER_VS]      = "SAMPLER_VS",
2347      [ILO_STATE_SAMPLER_GS]      = "SAMPLER_GS",
2348      [ILO_STATE_SAMPLER_FS]      = "SAMPLER_FS",
2349      [ILO_STATE_SAMPLER_CS]      = "SAMPLER_CS",
2350      [ILO_STATE_VIEW_VS]         = "VIEW_VS",
2351      [ILO_STATE_VIEW_GS]         = "VIEW_GS",
2352      [ILO_STATE_VIEW_FS]         = "VIEW_FS",
2353      [ILO_STATE_VIEW_CS]         = "VIEW_CS",
2354      [ILO_STATE_CBUF]            = "CBUF",
2355      [ILO_STATE_RESOURCE]        = "RESOURCE",
2356      [ILO_STATE_CS]              = "CS",
2357      [ILO_STATE_CS_RESOURCE]     = "CS_RESOURCE",
2358      [ILO_STATE_GLOBAL_BINDING]  = "GLOBAL_BINDING",
2359   };
2360   uint32_t dirty = vec->dirty;
2361
2362   if (!dirty) {
2363      ilo_printf("no state is dirty\n");
2364      return;
2365   }
2366
2367   dirty &= (1U << ILO_STATE_COUNT) - 1;
2368
2369   ilo_printf("%2d states are dirty:", util_bitcount(dirty));
2370   while (dirty) {
2371      const enum ilo_state state = u_bit_scan(&dirty);
2372      ilo_printf(" %s", state_names[state]);
2373   }
2374   ilo_printf("\n");
2375}
2376