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