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