ilo_state.c revision 9e24c49e6443c076ad892e6004e04956560e446a
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_state_3d.h"
29#include "util/u_dynarray.h"
30#include "util/u_helpers.h"
31#include "util/u_upload_mgr.h"
32
33#include "ilo_context.h"
34#include "ilo_resource.h"
35#include "ilo_shader.h"
36#include "ilo_state.h"
37
38static void
39finalize_shader_states(struct ilo_state_vector *vec)
40{
41   unsigned type;
42
43   for (type = 0; type < PIPE_SHADER_TYPES; type++) {
44      struct ilo_shader_state *shader;
45      uint32_t state;
46
47      switch (type) {
48      case PIPE_SHADER_VERTEX:
49         shader = vec->vs;
50         state = ILO_DIRTY_VS;
51         break;
52      case PIPE_SHADER_GEOMETRY:
53         shader = vec->gs;
54         state = ILO_DIRTY_GS;
55         break;
56      case PIPE_SHADER_FRAGMENT:
57         shader = vec->fs;
58         state = ILO_DIRTY_FS;
59         break;
60      default:
61         shader = NULL;
62         state = 0;
63         break;
64      }
65
66      if (!shader)
67         continue;
68
69      /* compile if the shader or the states it depends on changed */
70      if (vec->dirty & state) {
71         ilo_shader_select_kernel(shader, vec, ILO_DIRTY_ALL);
72      }
73      else if (ilo_shader_select_kernel(shader, vec, vec->dirty)) {
74         /* mark the state dirty if a new kernel is selected */
75         vec->dirty |= state;
76      }
77
78      /* need to setup SBE for FS */
79      if (type == PIPE_SHADER_FRAGMENT && vec->dirty &
80            (state | ILO_DIRTY_GS | ILO_DIRTY_VS | ILO_DIRTY_RASTERIZER)) {
81         if (ilo_shader_select_kernel_routing(shader,
82               (vec->gs) ? vec->gs : vec->vs, vec->rasterizer))
83            vec->dirty |= state;
84      }
85   }
86}
87
88static void
89finalize_cbuf_state(struct ilo_context *ilo,
90                    struct ilo_cbuf_state *cbuf,
91                    const struct ilo_shader_state *sh)
92{
93   uint32_t upload_mask = cbuf->enabled_mask;
94
95   /* skip CBUF0 if the kernel does not need it */
96   upload_mask &=
97      ~ilo_shader_get_kernel_param(sh, ILO_KERNEL_SKIP_CBUF0_UPLOAD);
98
99   while (upload_mask) {
100      const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
101      unsigned offset, i;
102
103      i = u_bit_scan(&upload_mask);
104      /* no need to upload */
105      if (cbuf->cso[i].resource)
106         continue;
107
108      u_upload_data(ilo->uploader, 0, cbuf->cso[i].user_buffer_size,
109            cbuf->cso[i].user_buffer, &offset, &cbuf->cso[i].resource);
110
111      ilo_gpe_init_view_surface_for_buffer(ilo->dev,
112            ilo_buffer(cbuf->cso[i].resource),
113            offset, cbuf->cso[i].user_buffer_size,
114            util_format_get_blocksize(elem_format), elem_format,
115            false, false, &cbuf->cso[i].surface);
116
117      ilo->state_vector.dirty |= ILO_DIRTY_CBUF;
118   }
119}
120
121static void
122finalize_constant_buffers(struct ilo_context *ilo)
123{
124   struct ilo_state_vector *vec = &ilo->state_vector;
125
126   if (vec->dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_VS))
127      finalize_cbuf_state(ilo, &vec->cbuf[PIPE_SHADER_VERTEX], vec->vs);
128
129   if (ilo->state_vector.dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_FS))
130      finalize_cbuf_state(ilo, &vec->cbuf[PIPE_SHADER_FRAGMENT], vec->fs);
131}
132
133static void
134finalize_index_buffer(struct ilo_context *ilo)
135{
136   struct ilo_state_vector *vec = &ilo->state_vector;
137   const bool need_upload = (vec->draw->indexed &&
138         (vec->ib.user_buffer || vec->ib.offset % vec->ib.index_size));
139   struct pipe_resource *current_hw_res = NULL;
140
141   if (!(vec->dirty & ILO_DIRTY_IB) && !need_upload)
142      return;
143
144   pipe_resource_reference(&current_hw_res, vec->ib.hw_resource);
145
146   if (need_upload) {
147      const unsigned offset = vec->ib.index_size * vec->draw->start;
148      const unsigned size = vec->ib.index_size * vec->draw->count;
149      unsigned hw_offset;
150
151      if (vec->ib.user_buffer) {
152         u_upload_data(ilo->uploader, 0, size,
153               vec->ib.user_buffer + offset, &hw_offset, &vec->ib.hw_resource);
154      }
155      else {
156         u_upload_buffer(ilo->uploader, 0, vec->ib.offset + offset, size,
157               vec->ib.buffer, &hw_offset, &vec->ib.hw_resource);
158      }
159
160      /* the HW offset should be aligned */
161      assert(hw_offset % vec->ib.index_size == 0);
162      vec->ib.draw_start_offset = hw_offset / vec->ib.index_size;
163
164      /*
165       * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
166       * resource
167       */
168      vec->ib.draw_start_offset -= vec->draw->start;
169   }
170   else {
171      pipe_resource_reference(&vec->ib.hw_resource, vec->ib.buffer);
172
173      /* note that index size may be zero when the draw is not indexed */
174      if (vec->draw->indexed)
175         vec->ib.draw_start_offset = vec->ib.offset / vec->ib.index_size;
176      else
177         vec->ib.draw_start_offset = 0;
178   }
179
180   /* treat the IB as clean if the HW states do not change */
181   if (vec->ib.hw_resource == current_hw_res &&
182       vec->ib.hw_index_size == vec->ib.index_size)
183      vec->dirty &= ~ILO_DIRTY_IB;
184   else
185      vec->ib.hw_index_size = vec->ib.index_size;
186
187   pipe_resource_reference(&current_hw_res, NULL);
188}
189
190static void
191finalize_vertex_elements(struct ilo_context *ilo)
192{
193   struct ilo_state_vector *vec = &ilo->state_vector;
194
195   if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS)))
196      return;
197
198   vec->dirty |= ILO_DIRTY_VE;
199
200   vec->ve->last_cso_edgeflag = false;
201   if (vec->ve->count && vec->vs &&
202         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG)) {
203      vec->ve->edgeflag_cso = vec->ve->cso[vec->ve->count - 1];
204      ilo_gpe_set_ve_edgeflag(ilo->dev, &vec->ve->edgeflag_cso);
205      vec->ve->last_cso_edgeflag = true;
206   }
207
208   vec->ve->prepend_nosrc_cso = false;
209   if (vec->vs &&
210       (ilo_shader_get_kernel_param(vec->vs,
211                                    ILO_KERNEL_VS_INPUT_INSTANCEID) ||
212        ilo_shader_get_kernel_param(vec->vs,
213                                    ILO_KERNEL_VS_INPUT_VERTEXID))) {
214      ilo_gpe_init_ve_nosrc(ilo->dev,
215            GEN6_VFCOMP_STORE_VID,
216            GEN6_VFCOMP_STORE_IID,
217            GEN6_VFCOMP_NOSTORE,
218            GEN6_VFCOMP_NOSTORE,
219            &vec->ve->nosrc_cso);
220      vec->ve->prepend_nosrc_cso = true;
221   } else if (!vec->vs) {
222      /* generate VUE header */
223      ilo_gpe_init_ve_nosrc(ilo->dev,
224            GEN6_VFCOMP_STORE_0, /* Reserved */
225            GEN6_VFCOMP_STORE_0, /* Render Target Array Index */
226            GEN6_VFCOMP_STORE_0, /* Viewport Index */
227            GEN6_VFCOMP_STORE_0, /* Point Width */
228            &vec->ve->nosrc_cso);
229      vec->ve->prepend_nosrc_cso = true;
230   } else if (!vec->ve->count) {
231      /*
232       * From the Sandy Bridge PRM, volume 2 part 1, page 92:
233       *
234       *    "SW must ensure that at least one vertex element is defined prior
235       *     to issuing a 3DPRIMTIVE command, or operation is UNDEFINED."
236       */
237      ilo_gpe_init_ve_nosrc(ilo->dev,
238            GEN6_VFCOMP_STORE_0,
239            GEN6_VFCOMP_STORE_0,
240            GEN6_VFCOMP_STORE_0,
241            GEN6_VFCOMP_STORE_1_FP,
242            &vec->ve->nosrc_cso);
243      vec->ve->prepend_nosrc_cso = true;
244   }
245}
246
247/**
248 * Finalize states.  Some states depend on other states and are
249 * incomplete/invalid until finalized.
250 */
251void
252ilo_finalize_3d_states(struct ilo_context *ilo,
253                       const struct pipe_draw_info *draw)
254{
255   ilo->state_vector.draw = draw;
256
257   finalize_shader_states(&ilo->state_vector);
258   finalize_constant_buffers(ilo);
259   finalize_index_buffer(ilo);
260   finalize_vertex_elements(ilo);
261
262   u_upload_unmap(ilo->uploader);
263}
264
265static void
266finalize_global_binding(struct ilo_state_vector *vec)
267{
268   struct ilo_shader_state *cs = vec->cs;
269   int base, count, shift;
270   int i;
271
272   count = ilo_shader_get_kernel_param(cs,
273         ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT);
274   if (!count)
275      return;
276
277   base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE);
278   shift = 32 - util_last_bit(base + count - 1);
279
280   if (count > vec->global_binding.count)
281      count = vec->global_binding.count;
282
283   for (i = 0; i < count; i++) {
284      struct ilo_global_binding_cso *cso =
285         util_dynarray_element(&vec->global_binding.bindings,
286               struct ilo_global_binding_cso, i);
287      const uint32_t offset = *cso->handle & ((1 << shift) - 1);
288
289      *cso->handle = ((base + i) << shift) | offset;
290   }
291}
292
293void
294ilo_finalize_compute_states(struct ilo_context *ilo)
295{
296   finalize_global_binding(&ilo->state_vector);
297}
298
299static void *
300ilo_create_blend_state(struct pipe_context *pipe,
301                       const struct pipe_blend_state *state)
302{
303   const struct ilo_dev *dev = ilo_context(pipe)->dev;
304   struct ilo_blend_state *blend;
305
306   blend = MALLOC_STRUCT(ilo_blend_state);
307   assert(blend);
308
309   ilo_gpe_init_blend(dev, state, blend);
310
311   return blend;
312}
313
314static void
315ilo_bind_blend_state(struct pipe_context *pipe, void *state)
316{
317   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
318
319   vec->blend = state;
320
321   vec->dirty |= ILO_DIRTY_BLEND;
322}
323
324static void
325ilo_delete_blend_state(struct pipe_context *pipe, void  *state)
326{
327   FREE(state);
328}
329
330static void *
331ilo_create_sampler_state(struct pipe_context *pipe,
332                         const struct pipe_sampler_state *state)
333{
334   const struct ilo_dev *dev = ilo_context(pipe)->dev;
335   struct ilo_sampler_cso *sampler;
336
337   sampler = MALLOC_STRUCT(ilo_sampler_cso);
338   assert(sampler);
339
340   ilo_gpe_init_sampler_cso(dev, state, sampler);
341
342   return sampler;
343}
344
345static void
346ilo_bind_sampler_states(struct pipe_context *pipe, unsigned shader,
347                        unsigned start, unsigned count, void **samplers)
348{
349   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
350   struct ilo_sampler_state *dst = &vec->sampler[shader];
351   bool changed = false;
352   unsigned i;
353
354   assert(start + count <= Elements(dst->cso));
355
356   if (samplers) {
357      for (i = 0; i < count; i++) {
358         if (dst->cso[start + i] != samplers[i]) {
359            dst->cso[start + i] = samplers[i];
360
361            /*
362             * This function is sometimes called to reduce the number of bound
363             * samplers.  Do not consider that as a state change (and create a
364             * new array of SAMPLER_STATE).
365             */
366            if (samplers[i])
367               changed = true;
368         }
369      }
370   }
371   else {
372      for (i = 0; i < count; i++)
373         dst->cso[start + i] = NULL;
374   }
375
376   if (changed) {
377      switch (shader) {
378      case PIPE_SHADER_VERTEX:
379         vec->dirty |= ILO_DIRTY_SAMPLER_VS;
380         break;
381      case PIPE_SHADER_GEOMETRY:
382         vec->dirty |= ILO_DIRTY_SAMPLER_GS;
383         break;
384      case PIPE_SHADER_FRAGMENT:
385         vec->dirty |= ILO_DIRTY_SAMPLER_FS;
386         break;
387      case PIPE_SHADER_COMPUTE:
388         vec->dirty |= ILO_DIRTY_SAMPLER_CS;
389         break;
390      }
391   }
392}
393
394static void
395ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
396{
397   FREE(state);
398}
399
400static void *
401ilo_create_rasterizer_state(struct pipe_context *pipe,
402                            const struct pipe_rasterizer_state *state)
403{
404   const struct ilo_dev *dev = ilo_context(pipe)->dev;
405   struct ilo_rasterizer_state *rast;
406
407   rast = MALLOC_STRUCT(ilo_rasterizer_state);
408   assert(rast);
409
410   rast->state = *state;
411   ilo_gpe_init_rasterizer(dev, state, rast);
412
413   return rast;
414}
415
416static void
417ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state)
418{
419   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
420
421   vec->rasterizer = state;
422
423   vec->dirty |= ILO_DIRTY_RASTERIZER;
424}
425
426static void
427ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
428{
429   FREE(state);
430}
431
432static void *
433ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
434                                     const struct pipe_depth_stencil_alpha_state *state)
435{
436   const struct ilo_dev *dev = ilo_context(pipe)->dev;
437   struct ilo_dsa_state *dsa;
438
439   dsa = MALLOC_STRUCT(ilo_dsa_state);
440   assert(dsa);
441
442   ilo_gpe_init_dsa(dev, state, dsa);
443
444   return dsa;
445}
446
447static void
448ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
449{
450   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
451
452   vec->dsa = state;
453
454   vec->dirty |= ILO_DIRTY_DSA;
455}
456
457static void
458ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
459{
460   FREE(state);
461}
462
463static void *
464ilo_create_fs_state(struct pipe_context *pipe,
465                    const struct pipe_shader_state *state)
466{
467   struct ilo_context *ilo = ilo_context(pipe);
468   struct ilo_shader_state *shader;
469
470   shader = ilo_shader_create_fs(ilo->dev, state, &ilo->state_vector);
471   assert(shader);
472
473   ilo_shader_cache_add(ilo->shader_cache, shader);
474
475   return shader;
476}
477
478static void
479ilo_bind_fs_state(struct pipe_context *pipe, void *state)
480{
481   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
482
483   vec->fs = state;
484
485   vec->dirty |= ILO_DIRTY_FS;
486}
487
488static void
489ilo_delete_fs_state(struct pipe_context *pipe, void *state)
490{
491   struct ilo_context *ilo = ilo_context(pipe);
492   struct ilo_shader_state *fs = (struct ilo_shader_state *) state;
493
494   ilo_shader_cache_remove(ilo->shader_cache, fs);
495   ilo_shader_destroy(fs);
496}
497
498static void *
499ilo_create_vs_state(struct pipe_context *pipe,
500                    const struct pipe_shader_state *state)
501{
502   struct ilo_context *ilo = ilo_context(pipe);
503   struct ilo_shader_state *shader;
504
505   shader = ilo_shader_create_vs(ilo->dev, state, &ilo->state_vector);
506   assert(shader);
507
508   ilo_shader_cache_add(ilo->shader_cache, shader);
509
510   return shader;
511}
512
513static void
514ilo_bind_vs_state(struct pipe_context *pipe, void *state)
515{
516   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
517
518   vec->vs = state;
519
520   vec->dirty |= ILO_DIRTY_VS;
521}
522
523static void
524ilo_delete_vs_state(struct pipe_context *pipe, void *state)
525{
526   struct ilo_context *ilo = ilo_context(pipe);
527   struct ilo_shader_state *vs = (struct ilo_shader_state *) state;
528
529   ilo_shader_cache_remove(ilo->shader_cache, vs);
530   ilo_shader_destroy(vs);
531}
532
533static void *
534ilo_create_gs_state(struct pipe_context *pipe,
535                    const struct pipe_shader_state *state)
536{
537   struct ilo_context *ilo = ilo_context(pipe);
538   struct ilo_shader_state *shader;
539
540   shader = ilo_shader_create_gs(ilo->dev, state, &ilo->state_vector);
541   assert(shader);
542
543   ilo_shader_cache_add(ilo->shader_cache, shader);
544
545   return shader;
546}
547
548static void
549ilo_bind_gs_state(struct pipe_context *pipe, void *state)
550{
551   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
552
553   /* util_blitter may set this unnecessarily */
554   if (vec->gs == state)
555      return;
556
557   vec->gs = state;
558
559   vec->dirty |= ILO_DIRTY_GS;
560}
561
562static void
563ilo_delete_gs_state(struct pipe_context *pipe, void *state)
564{
565   struct ilo_context *ilo = ilo_context(pipe);
566   struct ilo_shader_state *gs = (struct ilo_shader_state *) state;
567
568   ilo_shader_cache_remove(ilo->shader_cache, gs);
569   ilo_shader_destroy(gs);
570}
571
572static void *
573ilo_create_vertex_elements_state(struct pipe_context *pipe,
574                                 unsigned num_elements,
575                                 const struct pipe_vertex_element *elements)
576{
577   const struct ilo_dev *dev = ilo_context(pipe)->dev;
578   struct ilo_ve_state *ve;
579
580   ve = MALLOC_STRUCT(ilo_ve_state);
581   assert(ve);
582
583   ilo_gpe_init_ve(dev, num_elements, elements, ve);
584
585   return ve;
586}
587
588static void
589ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
590{
591   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
592
593   vec->ve = state;
594
595   vec->dirty |= ILO_DIRTY_VE;
596}
597
598static void
599ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
600{
601   struct ilo_ve_state *ve = state;
602
603   FREE(ve);
604}
605
606static void
607ilo_set_blend_color(struct pipe_context *pipe,
608                    const struct pipe_blend_color *state)
609{
610   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
611
612   vec->blend_color = *state;
613
614   vec->dirty |= ILO_DIRTY_BLEND_COLOR;
615}
616
617static void
618ilo_set_stencil_ref(struct pipe_context *pipe,
619                    const struct pipe_stencil_ref *state)
620{
621   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
622
623   /* util_blitter may set this unnecessarily */
624   if (!memcmp(&vec->stencil_ref, state, sizeof(*state)))
625      return;
626
627   vec->stencil_ref = *state;
628
629   vec->dirty |= ILO_DIRTY_STENCIL_REF;
630}
631
632static void
633ilo_set_sample_mask(struct pipe_context *pipe,
634                    unsigned sample_mask)
635{
636   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
637
638   /* util_blitter may set this unnecessarily */
639   if (vec->sample_mask == sample_mask)
640      return;
641
642   vec->sample_mask = sample_mask;
643
644   vec->dirty |= ILO_DIRTY_SAMPLE_MASK;
645}
646
647static void
648ilo_set_clip_state(struct pipe_context *pipe,
649                   const struct pipe_clip_state *state)
650{
651   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
652
653   vec->clip = *state;
654
655   vec->dirty |= ILO_DIRTY_CLIP;
656}
657
658static void
659ilo_set_constant_buffer(struct pipe_context *pipe,
660                        uint shader, uint index,
661                        struct pipe_constant_buffer *buf)
662{
663   const struct ilo_dev *dev = ilo_context(pipe)->dev;
664   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
665   struct ilo_cbuf_state *cbuf = &vec->cbuf[shader];
666   const unsigned count = 1;
667   unsigned i;
668
669   assert(shader < Elements(vec->cbuf));
670   assert(index + count <= Elements(vec->cbuf[shader].cso));
671
672   if (buf) {
673      for (i = 0; i < count; i++) {
674         struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
675
676         pipe_resource_reference(&cso->resource, buf[i].buffer);
677
678         if (buf[i].buffer) {
679            const enum pipe_format elem_format =
680               PIPE_FORMAT_R32G32B32A32_FLOAT;
681
682            ilo_gpe_init_view_surface_for_buffer(dev,
683                  ilo_buffer(buf[i].buffer),
684                  buf[i].buffer_offset, buf[i].buffer_size,
685                  util_format_get_blocksize(elem_format), elem_format,
686                  false, false, &cso->surface);
687
688            cso->user_buffer = NULL;
689            cso->user_buffer_size = 0;
690
691            cbuf->enabled_mask |= 1 << (index + i);
692         }
693         else if (buf[i].user_buffer) {
694            cso->surface.bo = NULL;
695
696            /* buffer_offset does not apply for user buffer */
697            cso->user_buffer = buf[i].user_buffer;
698            cso->user_buffer_size = buf[i].buffer_size;
699
700            cbuf->enabled_mask |= 1 << (index + i);
701         }
702         else {
703            cso->surface.bo = NULL;
704            cso->user_buffer = NULL;
705            cso->user_buffer_size = 0;
706
707            cbuf->enabled_mask &= ~(1 << (index + i));
708         }
709      }
710   }
711   else {
712      for (i = 0; i < count; i++) {
713         struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
714
715         pipe_resource_reference(&cso->resource, NULL);
716         cso->surface.bo = NULL;
717         cso->user_buffer = NULL;
718         cso->user_buffer_size = 0;
719
720         cbuf->enabled_mask &= ~(1 << (index + i));
721      }
722   }
723
724   vec->dirty |= ILO_DIRTY_CBUF;
725}
726
727static void
728ilo_set_framebuffer_state(struct pipe_context *pipe,
729                          const struct pipe_framebuffer_state *state)
730{
731   const struct ilo_dev *dev = ilo_context(pipe)->dev;
732   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
733
734   ilo_gpe_set_fb(dev, state, &vec->fb);
735
736   vec->dirty |= ILO_DIRTY_FB;
737}
738
739static void
740ilo_set_polygon_stipple(struct pipe_context *pipe,
741                        const struct pipe_poly_stipple *state)
742{
743   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
744
745   vec->poly_stipple = *state;
746
747   vec->dirty |= ILO_DIRTY_POLY_STIPPLE;
748}
749
750static void
751ilo_set_scissor_states(struct pipe_context *pipe,
752                       unsigned start_slot,
753                       unsigned num_scissors,
754                       const struct pipe_scissor_state *scissors)
755{
756   const struct ilo_dev *dev = ilo_context(pipe)->dev;
757   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
758
759   ilo_gpe_set_scissor(dev, start_slot, num_scissors,
760         scissors, &vec->scissor);
761
762   vec->dirty |= ILO_DIRTY_SCISSOR;
763}
764
765static void
766ilo_set_viewport_states(struct pipe_context *pipe,
767                        unsigned start_slot,
768                        unsigned num_viewports,
769                        const struct pipe_viewport_state *viewports)
770{
771   const struct ilo_dev *dev = ilo_context(pipe)->dev;
772   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
773
774   if (viewports) {
775      unsigned i;
776
777      for (i = 0; i < num_viewports; i++) {
778         ilo_gpe_set_viewport_cso(dev, &viewports[i],
779               &vec->viewport.cso[start_slot + i]);
780      }
781
782      if (vec->viewport.count < start_slot + num_viewports)
783         vec->viewport.count = start_slot + num_viewports;
784
785      /* need to save viewport 0 for util_blitter */
786      if (!start_slot && num_viewports)
787         vec->viewport.viewport0 = viewports[0];
788   }
789   else {
790      if (vec->viewport.count <= start_slot + num_viewports &&
791          vec->viewport.count > start_slot)
792         vec->viewport.count = start_slot;
793   }
794
795   vec->dirty |= ILO_DIRTY_VIEWPORT;
796}
797
798static void
799ilo_set_sampler_views(struct pipe_context *pipe, unsigned shader,
800                      unsigned start, unsigned count,
801                      struct pipe_sampler_view **views)
802{
803   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
804   struct ilo_view_state *dst = &vec->view[shader];
805   unsigned i;
806
807   assert(start + count <= Elements(dst->states));
808
809   if (views) {
810      for (i = 0; i < count; i++)
811         pipe_sampler_view_reference(&dst->states[start + i], views[i]);
812   }
813   else {
814      for (i = 0; i < count; i++)
815         pipe_sampler_view_reference(&dst->states[start + i], NULL);
816   }
817
818   if (dst->count <= start + count) {
819      if (views)
820         count += start;
821      else
822         count = start;
823
824      while (count > 0 && !dst->states[count - 1])
825         count--;
826
827      dst->count = count;
828   }
829
830   switch (shader) {
831   case PIPE_SHADER_VERTEX:
832      vec->dirty |= ILO_DIRTY_VIEW_VS;
833      break;
834   case PIPE_SHADER_GEOMETRY:
835      vec->dirty |= ILO_DIRTY_VIEW_GS;
836      break;
837   case PIPE_SHADER_FRAGMENT:
838      vec->dirty |= ILO_DIRTY_VIEW_FS;
839      break;
840   case PIPE_SHADER_COMPUTE:
841      vec->dirty |= ILO_DIRTY_VIEW_CS;
842      break;
843   }
844}
845
846static void
847ilo_set_shader_resources(struct pipe_context *pipe,
848                         unsigned start, unsigned count,
849                         struct pipe_surface **surfaces)
850{
851   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
852   struct ilo_resource_state *dst = &vec->resource;
853   unsigned i;
854
855   assert(start + count <= Elements(dst->states));
856
857   if (surfaces) {
858      for (i = 0; i < count; i++)
859         pipe_surface_reference(&dst->states[start + i], surfaces[i]);
860   }
861   else {
862      for (i = 0; i < count; i++)
863         pipe_surface_reference(&dst->states[start + i], NULL);
864   }
865
866   if (dst->count <= start + count) {
867      if (surfaces)
868         count += start;
869      else
870         count = start;
871
872      while (count > 0 && !dst->states[count - 1])
873         count--;
874
875      dst->count = count;
876   }
877
878   vec->dirty |= ILO_DIRTY_RESOURCE;
879}
880
881static void
882ilo_set_vertex_buffers(struct pipe_context *pipe,
883                       unsigned start_slot, unsigned num_buffers,
884                       const struct pipe_vertex_buffer *buffers)
885{
886   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
887   unsigned i;
888
889   /* no PIPE_CAP_USER_VERTEX_BUFFERS */
890   if (buffers) {
891      for (i = 0; i < num_buffers; i++)
892         assert(!buffers[i].user_buffer);
893   }
894
895   util_set_vertex_buffers_mask(vec->vb.states,
896         &vec->vb.enabled_mask, buffers, start_slot, num_buffers);
897
898   vec->dirty |= ILO_DIRTY_VB;
899}
900
901static void
902ilo_set_index_buffer(struct pipe_context *pipe,
903                     const struct pipe_index_buffer *state)
904{
905   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
906
907   if (state) {
908      pipe_resource_reference(&vec->ib.buffer, state->buffer);
909      vec->ib.user_buffer = state->user_buffer;
910      vec->ib.offset = state->offset;
911      vec->ib.index_size = state->index_size;
912   }
913   else {
914      pipe_resource_reference(&vec->ib.buffer, NULL);
915      vec->ib.user_buffer = NULL;
916      vec->ib.offset = 0;
917      vec->ib.index_size = 0;
918   }
919
920   vec->dirty |= ILO_DIRTY_IB;
921}
922
923static struct pipe_stream_output_target *
924ilo_create_stream_output_target(struct pipe_context *pipe,
925                                struct pipe_resource *res,
926                                unsigned buffer_offset,
927                                unsigned buffer_size)
928{
929   struct pipe_stream_output_target *target;
930
931   target = MALLOC_STRUCT(pipe_stream_output_target);
932   assert(target);
933
934   pipe_reference_init(&target->reference, 1);
935   target->buffer = NULL;
936   pipe_resource_reference(&target->buffer, res);
937   target->context = pipe;
938   target->buffer_offset = buffer_offset;
939   target->buffer_size = buffer_size;
940
941   return target;
942}
943
944static void
945ilo_set_stream_output_targets(struct pipe_context *pipe,
946                              unsigned num_targets,
947                              struct pipe_stream_output_target **targets,
948                              const unsigned *offset)
949{
950   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
951   unsigned i;
952   unsigned append_bitmask = 0;
953
954   if (!targets)
955      num_targets = 0;
956
957   /* util_blitter may set this unnecessarily */
958   if (!vec->so.count && !num_targets)
959      return;
960
961   for (i = 0; i < num_targets; i++) {
962      pipe_so_target_reference(&vec->so.states[i], targets[i]);
963      if (offset[i] == (unsigned)-1)
964         append_bitmask |= 1 << i;
965   }
966
967   for (; i < vec->so.count; i++)
968      pipe_so_target_reference(&vec->so.states[i], NULL);
969
970   vec->so.count = num_targets;
971   vec->so.append_bitmask = append_bitmask;
972
973   vec->so.enabled = (vec->so.count > 0);
974
975   vec->dirty |= ILO_DIRTY_SO;
976}
977
978static void
979ilo_stream_output_target_destroy(struct pipe_context *pipe,
980                                 struct pipe_stream_output_target *target)
981{
982   pipe_resource_reference(&target->buffer, NULL);
983   FREE(target);
984}
985
986static struct pipe_sampler_view *
987ilo_create_sampler_view(struct pipe_context *pipe,
988                        struct pipe_resource *res,
989                        const struct pipe_sampler_view *templ)
990{
991   const struct ilo_dev *dev = ilo_context(pipe)->dev;
992   struct ilo_view_cso *view;
993
994   view = MALLOC_STRUCT(ilo_view_cso);
995   assert(view);
996
997   view->base = *templ;
998   pipe_reference_init(&view->base.reference, 1);
999   view->base.texture = NULL;
1000   pipe_resource_reference(&view->base.texture, res);
1001   view->base.context = pipe;
1002
1003   if (res->target == PIPE_BUFFER) {
1004      const unsigned elem_size = util_format_get_blocksize(templ->format);
1005      const unsigned first_elem = templ->u.buf.first_element;
1006      const unsigned num_elems = templ->u.buf.last_element - first_elem + 1;
1007
1008      ilo_gpe_init_view_surface_for_buffer(dev, ilo_buffer(res),
1009            first_elem * elem_size, num_elems * elem_size,
1010            elem_size, templ->format, false, false, &view->surface);
1011   }
1012   else {
1013      struct ilo_texture *tex = ilo_texture(res);
1014
1015      /* warn about degraded performance because of a missing binding flag */
1016      if (tex->image.tiling == GEN6_TILING_NONE &&
1017          !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) {
1018         ilo_warn("creating sampler view for a resource "
1019                  "not created for sampling\n");
1020      }
1021
1022      ilo_gpe_init_view_surface_for_texture(dev, tex,
1023            templ->format,
1024            templ->u.tex.first_level,
1025            templ->u.tex.last_level - templ->u.tex.first_level + 1,
1026            templ->u.tex.first_layer,
1027            templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
1028            false, &view->surface);
1029   }
1030
1031   return &view->base;
1032}
1033
1034static void
1035ilo_sampler_view_destroy(struct pipe_context *pipe,
1036                         struct pipe_sampler_view *view)
1037{
1038   pipe_resource_reference(&view->texture, NULL);
1039   FREE(view);
1040}
1041
1042static struct pipe_surface *
1043ilo_create_surface(struct pipe_context *pipe,
1044                   struct pipe_resource *res,
1045                   const struct pipe_surface *templ)
1046{
1047   const struct ilo_dev *dev = ilo_context(pipe)->dev;
1048   struct ilo_surface_cso *surf;
1049
1050   surf = MALLOC_STRUCT(ilo_surface_cso);
1051   assert(surf);
1052
1053   surf->base = *templ;
1054   pipe_reference_init(&surf->base.reference, 1);
1055   surf->base.texture = NULL;
1056   pipe_resource_reference(&surf->base.texture, res);
1057
1058   surf->base.context = pipe;
1059   surf->base.width = u_minify(res->width0, templ->u.tex.level);
1060   surf->base.height = u_minify(res->height0, templ->u.tex.level);
1061
1062   surf->is_rt = !util_format_is_depth_or_stencil(templ->format);
1063
1064   if (surf->is_rt) {
1065      /* relax this? */
1066      assert(res->target != PIPE_BUFFER);
1067
1068      /*
1069       * classic i965 sets render_cache_rw for constant buffers and sol
1070       * surfaces but not render buffers.  Why?
1071       */
1072      ilo_gpe_init_view_surface_for_texture(dev, ilo_texture(res),
1073            templ->format, templ->u.tex.level, 1,
1074            templ->u.tex.first_layer,
1075            templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
1076            true, &surf->u.rt);
1077   }
1078   else {
1079      assert(res->target != PIPE_BUFFER);
1080
1081      ilo_gpe_init_zs_surface(dev, ilo_texture(res),
1082            templ->format, templ->u.tex.level,
1083            templ->u.tex.first_layer,
1084            templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
1085            &surf->u.zs);
1086   }
1087
1088   return &surf->base;
1089}
1090
1091static void
1092ilo_surface_destroy(struct pipe_context *pipe,
1093                    struct pipe_surface *surface)
1094{
1095   pipe_resource_reference(&surface->texture, NULL);
1096   FREE(surface);
1097}
1098
1099static void *
1100ilo_create_compute_state(struct pipe_context *pipe,
1101                         const struct pipe_compute_state *state)
1102{
1103   struct ilo_context *ilo = ilo_context(pipe);
1104   struct ilo_shader_state *shader;
1105
1106   shader = ilo_shader_create_cs(ilo->dev, state, &ilo->state_vector);
1107   assert(shader);
1108
1109   ilo_shader_cache_add(ilo->shader_cache, shader);
1110
1111   return shader;
1112}
1113
1114static void
1115ilo_bind_compute_state(struct pipe_context *pipe, void *state)
1116{
1117   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1118
1119   vec->cs = state;
1120
1121   vec->dirty |= ILO_DIRTY_CS;
1122}
1123
1124static void
1125ilo_delete_compute_state(struct pipe_context *pipe, void *state)
1126{
1127   struct ilo_context *ilo = ilo_context(pipe);
1128   struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
1129
1130   ilo_shader_cache_remove(ilo->shader_cache, cs);
1131   ilo_shader_destroy(cs);
1132}
1133
1134static void
1135ilo_set_compute_resources(struct pipe_context *pipe,
1136                          unsigned start, unsigned count,
1137                          struct pipe_surface **surfaces)
1138{
1139   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1140   struct ilo_resource_state *dst = &vec->cs_resource;
1141   unsigned i;
1142
1143   assert(start + count <= Elements(dst->states));
1144
1145   if (surfaces) {
1146      for (i = 0; i < count; i++)
1147         pipe_surface_reference(&dst->states[start + i], surfaces[i]);
1148   }
1149   else {
1150      for (i = 0; i < count; i++)
1151         pipe_surface_reference(&dst->states[start + i], NULL);
1152   }
1153
1154   if (dst->count <= start + count) {
1155      if (surfaces)
1156         count += start;
1157      else
1158         count = start;
1159
1160      while (count > 0 && !dst->states[count - 1])
1161         count--;
1162
1163      dst->count = count;
1164   }
1165
1166   vec->dirty |= ILO_DIRTY_CS_RESOURCE;
1167}
1168
1169static void
1170ilo_set_global_binding(struct pipe_context *pipe,
1171                       unsigned start, unsigned count,
1172                       struct pipe_resource **resources,
1173                       uint32_t **handles)
1174{
1175   struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1176   struct ilo_global_binding_cso *dst;
1177   unsigned i;
1178
1179   /* make room */
1180   if (vec->global_binding.count < start + count) {
1181      if (resources) {
1182         const unsigned old_size = vec->global_binding.bindings.size;
1183         const unsigned new_size = sizeof(*dst) * (start + count);
1184
1185         if (old_size < new_size) {
1186            util_dynarray_resize(&vec->global_binding.bindings, new_size);
1187            memset(vec->global_binding.bindings.data + old_size, 0,
1188                  new_size - old_size);
1189         }
1190      } else {
1191         count = vec->global_binding.count - start;
1192      }
1193   }
1194
1195   dst = util_dynarray_element(&vec->global_binding.bindings,
1196         struct ilo_global_binding_cso, start);
1197
1198   if (resources) {
1199      for (i = 0; i < count; i++) {
1200         pipe_resource_reference(&dst[i].resource, resources[i]);
1201         dst[i].handle = handles[i];
1202      }
1203   } else {
1204      for (i = 0; i < count; i++) {
1205         pipe_resource_reference(&dst[i].resource, NULL);
1206         dst[i].handle = NULL;
1207      }
1208   }
1209
1210   if (vec->global_binding.count <= start + count) {
1211      dst = util_dynarray_begin(&vec->global_binding.bindings);
1212
1213      if (resources)
1214         count += start;
1215      else
1216         count = start;
1217
1218      while (count > 0 && !dst[count - 1].resource)
1219         count--;
1220
1221      vec->global_binding.count = count;
1222   }
1223
1224   vec->dirty |= ILO_DIRTY_GLOBAL_BINDING;
1225}
1226
1227/**
1228 * Initialize state-related functions.
1229 */
1230void
1231ilo_init_state_functions(struct ilo_context *ilo)
1232{
1233   STATIC_ASSERT(ILO_STATE_COUNT <= 32);
1234
1235   ilo->base.create_blend_state = ilo_create_blend_state;
1236   ilo->base.bind_blend_state = ilo_bind_blend_state;
1237   ilo->base.delete_blend_state = ilo_delete_blend_state;
1238   ilo->base.create_sampler_state = ilo_create_sampler_state;
1239   ilo->base.bind_sampler_states = ilo_bind_sampler_states;
1240   ilo->base.delete_sampler_state = ilo_delete_sampler_state;
1241   ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
1242   ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
1243   ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
1244   ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
1245   ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
1246   ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
1247   ilo->base.create_fs_state = ilo_create_fs_state;
1248   ilo->base.bind_fs_state = ilo_bind_fs_state;
1249   ilo->base.delete_fs_state = ilo_delete_fs_state;
1250   ilo->base.create_vs_state = ilo_create_vs_state;
1251   ilo->base.bind_vs_state = ilo_bind_vs_state;
1252   ilo->base.delete_vs_state = ilo_delete_vs_state;
1253   ilo->base.create_gs_state = ilo_create_gs_state;
1254   ilo->base.bind_gs_state = ilo_bind_gs_state;
1255   ilo->base.delete_gs_state = ilo_delete_gs_state;
1256   ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
1257   ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
1258   ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
1259
1260   ilo->base.set_blend_color = ilo_set_blend_color;
1261   ilo->base.set_stencil_ref = ilo_set_stencil_ref;
1262   ilo->base.set_sample_mask = ilo_set_sample_mask;
1263   ilo->base.set_clip_state = ilo_set_clip_state;
1264   ilo->base.set_constant_buffer = ilo_set_constant_buffer;
1265   ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
1266   ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
1267   ilo->base.set_scissor_states = ilo_set_scissor_states;
1268   ilo->base.set_viewport_states = ilo_set_viewport_states;
1269   ilo->base.set_sampler_views = ilo_set_sampler_views;
1270   ilo->base.set_shader_resources = ilo_set_shader_resources;
1271   ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
1272   ilo->base.set_index_buffer = ilo_set_index_buffer;
1273
1274   ilo->base.create_stream_output_target = ilo_create_stream_output_target;
1275   ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
1276   ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
1277
1278   ilo->base.create_sampler_view = ilo_create_sampler_view;
1279   ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
1280
1281   ilo->base.create_surface = ilo_create_surface;
1282   ilo->base.surface_destroy = ilo_surface_destroy;
1283
1284   ilo->base.create_compute_state = ilo_create_compute_state;
1285   ilo->base.bind_compute_state = ilo_bind_compute_state;
1286   ilo->base.delete_compute_state = ilo_delete_compute_state;
1287   ilo->base.set_compute_resources = ilo_set_compute_resources;
1288   ilo->base.set_global_binding = ilo_set_global_binding;
1289}
1290
1291void
1292ilo_state_vector_init(const struct ilo_dev *dev,
1293                      struct ilo_state_vector *vec)
1294{
1295   ilo_gpe_set_scissor_null(dev, &vec->scissor);
1296
1297   ilo_gpe_init_zs_surface(dev, NULL, PIPE_FORMAT_NONE,
1298         0, 0, 1, &vec->fb.null_zs);
1299
1300   util_dynarray_init(&vec->global_binding.bindings);
1301
1302   vec->dirty = ILO_DIRTY_ALL;
1303}
1304
1305void
1306ilo_state_vector_cleanup(struct ilo_state_vector *vec)
1307{
1308   unsigned i, sh;
1309
1310   for (i = 0; i < Elements(vec->vb.states); i++) {
1311      if (vec->vb.enabled_mask & (1 << i))
1312         pipe_resource_reference(&vec->vb.states[i].buffer, NULL);
1313   }
1314
1315   pipe_resource_reference(&vec->ib.buffer, NULL);
1316   pipe_resource_reference(&vec->ib.hw_resource, NULL);
1317
1318   for (i = 0; i < vec->so.count; i++)
1319      pipe_so_target_reference(&vec->so.states[i], NULL);
1320
1321   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
1322      for (i = 0; i < vec->view[sh].count; i++) {
1323         struct pipe_sampler_view *view = vec->view[sh].states[i];
1324         pipe_sampler_view_reference(&view, NULL);
1325      }
1326
1327      for (i = 0; i < Elements(vec->cbuf[sh].cso); i++) {
1328         struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
1329         pipe_resource_reference(&cbuf->resource, NULL);
1330      }
1331   }
1332
1333   for (i = 0; i < vec->resource.count; i++)
1334      pipe_surface_reference(&vec->resource.states[i], NULL);
1335
1336   for (i = 0; i < vec->fb.state.nr_cbufs; i++)
1337      pipe_surface_reference(&vec->fb.state.cbufs[i], NULL);
1338
1339   if (vec->fb.state.zsbuf)
1340      pipe_surface_reference(&vec->fb.state.zsbuf, NULL);
1341
1342   for (i = 0; i < vec->cs_resource.count; i++)
1343      pipe_surface_reference(&vec->cs_resource.states[i], NULL);
1344
1345   for (i = 0; i < vec->global_binding.count; i++) {
1346      struct ilo_global_binding_cso *cso =
1347         util_dynarray_element(&vec->global_binding.bindings,
1348               struct ilo_global_binding_cso, i);
1349      pipe_resource_reference(&cso->resource, NULL);
1350   }
1351
1352   util_dynarray_fini(&vec->global_binding.bindings);
1353}
1354
1355/**
1356 * Mark all states that have the resource dirty.
1357 */
1358void
1359ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
1360                                  struct pipe_resource *res)
1361{
1362   struct intel_bo *bo = ilo_resource_get_bo(res);
1363   uint32_t states = 0;
1364   unsigned sh, i;
1365
1366   if (res->target == PIPE_BUFFER) {
1367      uint32_t vb_mask = vec->vb.enabled_mask;
1368
1369      while (vb_mask) {
1370         const unsigned idx = u_bit_scan(&vb_mask);
1371
1372         if (vec->vb.states[idx].buffer == res) {
1373            states |= ILO_DIRTY_VB;
1374            break;
1375         }
1376      }
1377
1378      if (vec->ib.buffer == res) {
1379         states |= ILO_DIRTY_IB;
1380
1381         /*
1382          * finalize_index_buffer() has an optimization that clears
1383          * ILO_DIRTY_IB when the HW states do not change.  However, it fails
1384          * to flush the VF cache when the HW states do not change, but the
1385          * contents of the IB has changed.  Here, we set the index size to an
1386          * invalid value to avoid the optimization.
1387          */
1388         vec->ib.hw_index_size = 0;
1389      }
1390
1391      for (i = 0; i < vec->so.count; i++) {
1392         if (vec->so.states[i]->buffer == res) {
1393            states |= ILO_DIRTY_SO;
1394            break;
1395         }
1396      }
1397   }
1398
1399   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
1400      for (i = 0; i < vec->view[sh].count; i++) {
1401         struct ilo_view_cso *cso = (struct ilo_view_cso *) vec->view[sh].states[i];
1402
1403         if (cso->base.texture == res) {
1404            static const unsigned view_dirty_bits[PIPE_SHADER_TYPES] = {
1405               [PIPE_SHADER_VERTEX]    = ILO_DIRTY_VIEW_VS,
1406               [PIPE_SHADER_FRAGMENT]  = ILO_DIRTY_VIEW_FS,
1407               [PIPE_SHADER_GEOMETRY]  = ILO_DIRTY_VIEW_GS,
1408               [PIPE_SHADER_COMPUTE]   = ILO_DIRTY_VIEW_CS,
1409            };
1410            cso->surface.bo = bo;
1411
1412            states |= view_dirty_bits[sh];
1413            break;
1414         }
1415      }
1416
1417      if (res->target == PIPE_BUFFER) {
1418         for (i = 0; i < Elements(vec->cbuf[sh].cso); i++) {
1419            struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
1420
1421            if (cbuf->resource == res) {
1422               cbuf->surface.bo = bo;
1423               states |= ILO_DIRTY_CBUF;
1424               break;
1425            }
1426         }
1427      }
1428   }
1429
1430   for (i = 0; i < vec->resource.count; i++) {
1431      struct ilo_surface_cso *cso =
1432         (struct ilo_surface_cso *) vec->resource.states[i];
1433
1434      if (cso->base.texture == res) {
1435         cso->u.rt.bo = bo;
1436         states |= ILO_DIRTY_RESOURCE;
1437         break;
1438      }
1439   }
1440
1441   /* for now? */
1442   if (res->target != PIPE_BUFFER) {
1443      for (i = 0; i < vec->fb.state.nr_cbufs; i++) {
1444         struct ilo_surface_cso *cso =
1445            (struct ilo_surface_cso *) vec->fb.state.cbufs[i];
1446         if (cso && cso->base.texture == res) {
1447            cso->u.rt.bo = bo;
1448            states |= ILO_DIRTY_FB;
1449            break;
1450         }
1451      }
1452
1453      if (vec->fb.state.zsbuf && vec->fb.state.zsbuf->texture == res) {
1454         struct ilo_surface_cso *cso =
1455            (struct ilo_surface_cso *) vec->fb.state.zsbuf;
1456
1457         cso->u.rt.bo = bo;
1458         states |= ILO_DIRTY_FB;
1459      }
1460   }
1461
1462   for (i = 0; i < vec->cs_resource.count; i++) {
1463      struct ilo_surface_cso *cso =
1464         (struct ilo_surface_cso *) vec->cs_resource.states[i];
1465      if (cso->base.texture == res) {
1466         cso->u.rt.bo = bo;
1467         states |= ILO_DIRTY_CS_RESOURCE;
1468         break;
1469      }
1470   }
1471
1472   for (i = 0; i < vec->global_binding.count; i++) {
1473      struct ilo_global_binding_cso *cso =
1474         util_dynarray_element(&vec->global_binding.bindings,
1475               struct ilo_global_binding_cso, i);
1476
1477      if (cso->resource == res) {
1478         states |= ILO_DIRTY_GLOBAL_BINDING;
1479         break;
1480      }
1481   }
1482
1483   vec->dirty |= states;
1484}
1485
1486void
1487ilo_state_vector_dump_dirty(const struct ilo_state_vector *vec)
1488{
1489   static const char *state_names[ILO_STATE_COUNT] = {
1490      [ILO_STATE_VB]              = "VB",
1491      [ILO_STATE_VE]              = "VE",
1492      [ILO_STATE_IB]              = "IB",
1493      [ILO_STATE_VS]              = "VS",
1494      [ILO_STATE_GS]              = "GS",
1495      [ILO_STATE_SO]              = "SO",
1496      [ILO_STATE_CLIP]            = "CLIP",
1497      [ILO_STATE_VIEWPORT]        = "VIEWPORT",
1498      [ILO_STATE_SCISSOR]         = "SCISSOR",
1499      [ILO_STATE_RASTERIZER]      = "RASTERIZER",
1500      [ILO_STATE_POLY_STIPPLE]    = "POLY_STIPPLE",
1501      [ILO_STATE_SAMPLE_MASK]     = "SAMPLE_MASK",
1502      [ILO_STATE_FS]              = "FS",
1503      [ILO_STATE_DSA]             = "DSA",
1504      [ILO_STATE_STENCIL_REF]     = "STENCIL_REF",
1505      [ILO_STATE_BLEND]           = "BLEND",
1506      [ILO_STATE_BLEND_COLOR]     = "BLEND_COLOR",
1507      [ILO_STATE_FB]              = "FB",
1508      [ILO_STATE_SAMPLER_VS]      = "SAMPLER_VS",
1509      [ILO_STATE_SAMPLER_GS]      = "SAMPLER_GS",
1510      [ILO_STATE_SAMPLER_FS]      = "SAMPLER_FS",
1511      [ILO_STATE_SAMPLER_CS]      = "SAMPLER_CS",
1512      [ILO_STATE_VIEW_VS]         = "VIEW_VS",
1513      [ILO_STATE_VIEW_GS]         = "VIEW_GS",
1514      [ILO_STATE_VIEW_FS]         = "VIEW_FS",
1515      [ILO_STATE_VIEW_CS]         = "VIEW_CS",
1516      [ILO_STATE_CBUF]            = "CBUF",
1517      [ILO_STATE_RESOURCE]        = "RESOURCE",
1518      [ILO_STATE_CS]              = "CS",
1519      [ILO_STATE_CS_RESOURCE]     = "CS_RESOURCE",
1520      [ILO_STATE_GLOBAL_BINDING]  = "GLOBAL_BINDING",
1521   };
1522   uint32_t dirty = vec->dirty;
1523
1524   if (!dirty) {
1525      ilo_printf("no state is dirty\n");
1526      return;
1527   }
1528
1529   dirty &= (1U << ILO_STATE_COUNT) - 1;
1530
1531   ilo_printf("%2d states are dirty:", util_bitcount(dirty));
1532   while (dirty) {
1533      const enum ilo_state state = u_bit_scan(&dirty);
1534      ilo_printf(" %s", state_names[state]);
1535   }
1536   ilo_printf("\n");
1537}
1538