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