ilo: allow ilo_view_surface to skip layer offsetting
[mesa.git] / src / gallium / drivers / ilo / ilo_state.c
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
37 static void
38 finalize_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
87 static void
88 finalize_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
120 static void
121 finalize_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
130 static void
131 finalize_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 */
190 void
191 ilo_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
203 static void *
204 ilo_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
218 static void
219 ilo_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
228 static void
229 ilo_delete_blend_state(struct pipe_context *pipe, void *state)
230 {
231 FREE(state);
232 }
233
234 static void *
235 ilo_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
249 static void
250 ilo_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
310 static void
311 ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
312 {
313 FREE(state);
314 }
315
316 static void *
317 ilo_create_rasterizer_state(struct pipe_context *pipe,
318 const struct pipe_rasterizer_state *state)
319 {
320 struct ilo_context *ilo = ilo_context(pipe);
321 struct ilo_rasterizer_state *rast;
322
323 rast = MALLOC_STRUCT(ilo_rasterizer_state);
324 assert(rast);
325
326 rast->state = *state;
327 ilo_gpe_init_rasterizer(ilo->dev, state, rast);
328
329 return rast;
330 }
331
332 static void
333 ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state)
334 {
335 struct ilo_context *ilo = ilo_context(pipe);
336
337 ilo->rasterizer = state;
338
339 ilo->dirty |= ILO_DIRTY_RASTERIZER;
340 }
341
342 static void
343 ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
344 {
345 FREE(state);
346 }
347
348 static void *
349 ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
350 const struct pipe_depth_stencil_alpha_state *state)
351 {
352 struct ilo_context *ilo = ilo_context(pipe);
353 struct ilo_dsa_state *dsa;
354
355 dsa = MALLOC_STRUCT(ilo_dsa_state);
356 assert(dsa);
357
358 ilo_gpe_init_dsa(ilo->dev, state, dsa);
359
360 return dsa;
361 }
362
363 static void
364 ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
365 {
366 struct ilo_context *ilo = ilo_context(pipe);
367
368 ilo->dsa = state;
369
370 ilo->dirty |= ILO_DIRTY_DSA;
371 }
372
373 static void
374 ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
375 {
376 FREE(state);
377 }
378
379 static void *
380 ilo_create_fs_state(struct pipe_context *pipe,
381 const struct pipe_shader_state *state)
382 {
383 struct ilo_context *ilo = ilo_context(pipe);
384 struct ilo_shader_state *shader;
385
386 shader = ilo_shader_create_fs(ilo->dev, state, ilo);
387 assert(shader);
388
389 ilo_shader_cache_add(ilo->shader_cache, shader);
390
391 return shader;
392 }
393
394 static void
395 ilo_bind_fs_state(struct pipe_context *pipe, void *state)
396 {
397 struct ilo_context *ilo = ilo_context(pipe);
398
399 ilo->fs = state;
400
401 ilo->dirty |= ILO_DIRTY_FS;
402 }
403
404 static void
405 ilo_delete_fs_state(struct pipe_context *pipe, void *state)
406 {
407 struct ilo_context *ilo = ilo_context(pipe);
408 struct ilo_shader_state *fs = (struct ilo_shader_state *) state;
409
410 ilo_shader_cache_remove(ilo->shader_cache, fs);
411 ilo_shader_destroy(fs);
412 }
413
414 static void *
415 ilo_create_vs_state(struct pipe_context *pipe,
416 const struct pipe_shader_state *state)
417 {
418 struct ilo_context *ilo = ilo_context(pipe);
419 struct ilo_shader_state *shader;
420
421 shader = ilo_shader_create_vs(ilo->dev, state, ilo);
422 assert(shader);
423
424 ilo_shader_cache_add(ilo->shader_cache, shader);
425
426 return shader;
427 }
428
429 static void
430 ilo_bind_vs_state(struct pipe_context *pipe, void *state)
431 {
432 struct ilo_context *ilo = ilo_context(pipe);
433
434 ilo->vs = state;
435
436 ilo->dirty |= ILO_DIRTY_VS;
437 }
438
439 static void
440 ilo_delete_vs_state(struct pipe_context *pipe, void *state)
441 {
442 struct ilo_context *ilo = ilo_context(pipe);
443 struct ilo_shader_state *vs = (struct ilo_shader_state *) state;
444
445 ilo_shader_cache_remove(ilo->shader_cache, vs);
446 ilo_shader_destroy(vs);
447 }
448
449 static void *
450 ilo_create_gs_state(struct pipe_context *pipe,
451 const struct pipe_shader_state *state)
452 {
453 struct ilo_context *ilo = ilo_context(pipe);
454 struct ilo_shader_state *shader;
455
456 shader = ilo_shader_create_gs(ilo->dev, state, ilo);
457 assert(shader);
458
459 ilo_shader_cache_add(ilo->shader_cache, shader);
460
461 return shader;
462 }
463
464 static void
465 ilo_bind_gs_state(struct pipe_context *pipe, void *state)
466 {
467 struct ilo_context *ilo = ilo_context(pipe);
468
469 /* util_blitter may set this unnecessarily */
470 if (ilo->gs == state)
471 return;
472
473 ilo->gs = state;
474
475 ilo->dirty |= ILO_DIRTY_GS;
476 }
477
478 static void
479 ilo_delete_gs_state(struct pipe_context *pipe, void *state)
480 {
481 struct ilo_context *ilo = ilo_context(pipe);
482 struct ilo_shader_state *gs = (struct ilo_shader_state *) state;
483
484 ilo_shader_cache_remove(ilo->shader_cache, gs);
485 ilo_shader_destroy(gs);
486 }
487
488 static void *
489 ilo_create_vertex_elements_state(struct pipe_context *pipe,
490 unsigned num_elements,
491 const struct pipe_vertex_element *elements)
492 {
493 struct ilo_context *ilo = ilo_context(pipe);
494 struct ilo_ve_state *ve;
495
496 ve = MALLOC_STRUCT(ilo_ve_state);
497 assert(ve);
498
499 ilo_gpe_init_ve(ilo->dev, num_elements, elements, ve);
500
501 return ve;
502 }
503
504 static void
505 ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
506 {
507 struct ilo_context *ilo = ilo_context(pipe);
508
509 ilo->ve = state;
510
511 ilo->dirty |= ILO_DIRTY_VE;
512 }
513
514 static void
515 ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
516 {
517 struct ilo_ve_state *ve = state;
518
519 FREE(ve);
520 }
521
522 static void
523 ilo_set_blend_color(struct pipe_context *pipe,
524 const struct pipe_blend_color *state)
525 {
526 struct ilo_context *ilo = ilo_context(pipe);
527
528 ilo->blend_color = *state;
529
530 ilo->dirty |= ILO_DIRTY_BLEND_COLOR;
531 }
532
533 static void
534 ilo_set_stencil_ref(struct pipe_context *pipe,
535 const struct pipe_stencil_ref *state)
536 {
537 struct ilo_context *ilo = ilo_context(pipe);
538
539 /* util_blitter may set this unnecessarily */
540 if (!memcmp(&ilo->stencil_ref, state, sizeof(*state)))
541 return;
542
543 ilo->stencil_ref = *state;
544
545 ilo->dirty |= ILO_DIRTY_STENCIL_REF;
546 }
547
548 static void
549 ilo_set_sample_mask(struct pipe_context *pipe,
550 unsigned sample_mask)
551 {
552 struct ilo_context *ilo = ilo_context(pipe);
553
554 /* util_blitter may set this unnecessarily */
555 if (ilo->sample_mask == sample_mask)
556 return;
557
558 ilo->sample_mask = sample_mask;
559
560 ilo->dirty |= ILO_DIRTY_SAMPLE_MASK;
561 }
562
563 static void
564 ilo_set_clip_state(struct pipe_context *pipe,
565 const struct pipe_clip_state *state)
566 {
567 struct ilo_context *ilo = ilo_context(pipe);
568
569 ilo->clip = *state;
570
571 ilo->dirty |= ILO_DIRTY_CLIP;
572 }
573
574 static void
575 ilo_set_constant_buffer(struct pipe_context *pipe,
576 uint shader, uint index,
577 struct pipe_constant_buffer *buf)
578 {
579 struct ilo_context *ilo = ilo_context(pipe);
580 struct ilo_cbuf_state *cbuf = &ilo->cbuf[shader];
581 const unsigned count = 1;
582 unsigned i;
583
584 assert(shader < Elements(ilo->cbuf));
585 assert(index + count <= Elements(ilo->cbuf[shader].cso));
586
587 if (buf) {
588 for (i = 0; i < count; i++) {
589 struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
590
591 pipe_resource_reference(&cso->resource, buf[i].buffer);
592
593 if (buf[i].buffer) {
594 const enum pipe_format elem_format =
595 PIPE_FORMAT_R32G32B32A32_FLOAT;
596
597 ilo_gpe_init_view_surface_for_buffer(ilo->dev,
598 ilo_buffer(buf[i].buffer),
599 buf[i].buffer_offset, buf[i].buffer_size,
600 util_format_get_blocksize(elem_format), elem_format,
601 false, false, &cso->surface);
602
603 cso->user_buffer = NULL;
604 cso->user_buffer_size = 0;
605
606 cbuf->enabled_mask |= 1 << (index + i);
607 }
608 else if (buf[i].user_buffer) {
609 cso->surface.bo = NULL;
610
611 /* buffer_offset does not apply for user buffer */
612 cso->user_buffer = buf[i].user_buffer;
613 cso->user_buffer_size = buf[i].buffer_size;
614
615 cbuf->enabled_mask |= 1 << (index + i);
616 }
617 else {
618 cso->surface.bo = NULL;
619 cso->user_buffer = NULL;
620 cso->user_buffer_size = 0;
621
622 cbuf->enabled_mask &= ~(1 << (index + i));
623 }
624 }
625 }
626 else {
627 for (i = 0; i < count; i++) {
628 struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
629
630 pipe_resource_reference(&cso->resource, NULL);
631 cso->surface.bo = NULL;
632 cso->user_buffer = NULL;
633 cso->user_buffer_size = 0;
634
635 cbuf->enabled_mask &= ~(1 << (index + i));
636 }
637 }
638
639 ilo->dirty |= ILO_DIRTY_CBUF;
640 }
641
642 static void
643 ilo_set_framebuffer_state(struct pipe_context *pipe,
644 const struct pipe_framebuffer_state *state)
645 {
646 struct ilo_context *ilo = ilo_context(pipe);
647
648 util_copy_framebuffer_state(&ilo->fb.state, state);
649
650 if (state->nr_cbufs)
651 ilo->fb.num_samples = state->cbufs[0]->texture->nr_samples;
652 else if (state->zsbuf)
653 ilo->fb.num_samples = state->zsbuf->texture->nr_samples;
654 else
655 ilo->fb.num_samples = 1;
656
657 if (!ilo->fb.num_samples)
658 ilo->fb.num_samples = 1;
659
660 ilo->dirty |= ILO_DIRTY_FB;
661 }
662
663 static void
664 ilo_set_polygon_stipple(struct pipe_context *pipe,
665 const struct pipe_poly_stipple *state)
666 {
667 struct ilo_context *ilo = ilo_context(pipe);
668
669 ilo->poly_stipple = *state;
670
671 ilo->dirty |= ILO_DIRTY_POLY_STIPPLE;
672 }
673
674 static void
675 ilo_set_scissor_states(struct pipe_context *pipe,
676 unsigned start_slot,
677 unsigned num_scissors,
678 const struct pipe_scissor_state *scissors)
679 {
680 struct ilo_context *ilo = ilo_context(pipe);
681
682 ilo_gpe_set_scissor(ilo->dev, start_slot, num_scissors,
683 scissors, &ilo->scissor);
684
685 ilo->dirty |= ILO_DIRTY_SCISSOR;
686 }
687
688 static void
689 ilo_set_viewport_states(struct pipe_context *pipe,
690 unsigned start_slot,
691 unsigned num_viewports,
692 const struct pipe_viewport_state *viewports)
693 {
694 struct ilo_context *ilo = ilo_context(pipe);
695
696 if (viewports) {
697 unsigned i;
698
699 for (i = 0; i < num_viewports; i++) {
700 ilo_gpe_set_viewport_cso(ilo->dev, &viewports[i],
701 &ilo->viewport.cso[start_slot + i]);
702 }
703
704 if (ilo->viewport.count < start_slot + num_viewports)
705 ilo->viewport.count = start_slot + num_viewports;
706
707 /* need to save viewport 0 for util_blitter */
708 if (!start_slot && num_viewports)
709 ilo->viewport.viewport0 = viewports[0];
710 }
711 else {
712 if (ilo->viewport.count <= start_slot + num_viewports &&
713 ilo->viewport.count > start_slot)
714 ilo->viewport.count = start_slot;
715 }
716
717 ilo->dirty |= ILO_DIRTY_VIEWPORT;
718 }
719
720 static void
721 ilo_set_sampler_views(struct pipe_context *pipe, unsigned shader,
722 unsigned start, unsigned count,
723 struct pipe_sampler_view **views)
724 {
725 struct ilo_context *ilo = ilo_context(pipe);
726 struct ilo_view_state *dst = &ilo->view[shader];
727 unsigned i;
728
729 assert(start + count <= Elements(dst->states));
730
731 if (views) {
732 for (i = 0; i < count; i++)
733 pipe_sampler_view_reference(&dst->states[start + i], views[i]);
734 }
735 else {
736 for (i = 0; i < count; i++)
737 pipe_sampler_view_reference(&dst->states[start + i], NULL);
738 }
739
740 if (dst->count <= start + count) {
741 if (views)
742 count += start;
743 else
744 count = start;
745
746 while (count > 0 && !dst->states[count - 1])
747 count--;
748
749 dst->count = count;
750 }
751
752 switch (shader) {
753 case PIPE_SHADER_VERTEX:
754 ilo->dirty |= ILO_DIRTY_VIEW_VS;
755 break;
756 case PIPE_SHADER_GEOMETRY:
757 ilo->dirty |= ILO_DIRTY_VIEW_GS;
758 break;
759 case PIPE_SHADER_FRAGMENT:
760 ilo->dirty |= ILO_DIRTY_VIEW_FS;
761 break;
762 case PIPE_SHADER_COMPUTE:
763 ilo->dirty |= ILO_DIRTY_VIEW_CS;
764 break;
765 }
766 }
767
768 static void
769 ilo_set_shader_resources(struct pipe_context *pipe,
770 unsigned start, unsigned count,
771 struct pipe_surface **surfaces)
772 {
773 struct ilo_context *ilo = ilo_context(pipe);
774 struct ilo_resource_state *dst = &ilo->resource;
775 unsigned i;
776
777 assert(start + count <= Elements(dst->states));
778
779 if (surfaces) {
780 for (i = 0; i < count; i++)
781 pipe_surface_reference(&dst->states[start + i], surfaces[i]);
782 }
783 else {
784 for (i = 0; i < count; i++)
785 pipe_surface_reference(&dst->states[start + i], NULL);
786 }
787
788 if (dst->count <= start + count) {
789 if (surfaces)
790 count += start;
791 else
792 count = start;
793
794 while (count > 0 && !dst->states[count - 1])
795 count--;
796
797 dst->count = count;
798 }
799
800 ilo->dirty |= ILO_DIRTY_RESOURCE;
801 }
802
803 static void
804 ilo_set_vertex_buffers(struct pipe_context *pipe,
805 unsigned start_slot, unsigned num_buffers,
806 const struct pipe_vertex_buffer *buffers)
807 {
808 struct ilo_context *ilo = ilo_context(pipe);
809 unsigned i;
810
811 /* no PIPE_CAP_USER_VERTEX_BUFFERS */
812 if (buffers) {
813 for (i = 0; i < num_buffers; i++)
814 assert(!buffers[i].user_buffer);
815 }
816
817 util_set_vertex_buffers_mask(ilo->vb.states,
818 &ilo->vb.enabled_mask, buffers, start_slot, num_buffers);
819
820 ilo->dirty |= ILO_DIRTY_VB;
821 }
822
823 static void
824 ilo_set_index_buffer(struct pipe_context *pipe,
825 const struct pipe_index_buffer *state)
826 {
827 struct ilo_context *ilo = ilo_context(pipe);
828
829 if (state) {
830 pipe_resource_reference(&ilo->ib.buffer, state->buffer);
831 ilo->ib.user_buffer = state->user_buffer;
832 ilo->ib.offset = state->offset;
833 ilo->ib.index_size = state->index_size;
834 }
835 else {
836 pipe_resource_reference(&ilo->ib.buffer, NULL);
837 ilo->ib.user_buffer = NULL;
838 ilo->ib.offset = 0;
839 ilo->ib.index_size = 0;
840 }
841
842 ilo->dirty |= ILO_DIRTY_IB;
843 }
844
845 static struct pipe_stream_output_target *
846 ilo_create_stream_output_target(struct pipe_context *pipe,
847 struct pipe_resource *res,
848 unsigned buffer_offset,
849 unsigned buffer_size)
850 {
851 struct pipe_stream_output_target *target;
852
853 target = MALLOC_STRUCT(pipe_stream_output_target);
854 assert(target);
855
856 pipe_reference_init(&target->reference, 1);
857 target->buffer = NULL;
858 pipe_resource_reference(&target->buffer, res);
859 target->context = pipe;
860 target->buffer_offset = buffer_offset;
861 target->buffer_size = buffer_size;
862
863 return target;
864 }
865
866 static void
867 ilo_set_stream_output_targets(struct pipe_context *pipe,
868 unsigned num_targets,
869 struct pipe_stream_output_target **targets,
870 unsigned append_bitmask)
871 {
872 struct ilo_context *ilo = ilo_context(pipe);
873 unsigned i;
874
875 if (!targets)
876 num_targets = 0;
877
878 /* util_blitter may set this unnecessarily */
879 if (!ilo->so.count && !num_targets)
880 return;
881
882 for (i = 0; i < num_targets; i++)
883 pipe_so_target_reference(&ilo->so.states[i], targets[i]);
884
885 for (; i < ilo->so.count; i++)
886 pipe_so_target_reference(&ilo->so.states[i], NULL);
887
888 ilo->so.count = num_targets;
889 ilo->so.append_bitmask = append_bitmask;
890
891 ilo->so.enabled = (ilo->so.count > 0);
892
893 ilo->dirty |= ILO_DIRTY_SO;
894 }
895
896 static void
897 ilo_stream_output_target_destroy(struct pipe_context *pipe,
898 struct pipe_stream_output_target *target)
899 {
900 pipe_resource_reference(&target->buffer, NULL);
901 FREE(target);
902 }
903
904 static struct pipe_sampler_view *
905 ilo_create_sampler_view(struct pipe_context *pipe,
906 struct pipe_resource *res,
907 const struct pipe_sampler_view *templ)
908 {
909 struct ilo_context *ilo = ilo_context(pipe);
910 struct ilo_view_cso *view;
911
912 view = MALLOC_STRUCT(ilo_view_cso);
913 assert(view);
914
915 view->base = *templ;
916 pipe_reference_init(&view->base.reference, 1);
917 view->base.texture = NULL;
918 pipe_resource_reference(&view->base.texture, res);
919 view->base.context = pipe;
920
921 if (res->target == PIPE_BUFFER) {
922 const unsigned elem_size = util_format_get_blocksize(templ->format);
923 const unsigned first_elem = templ->u.buf.first_element;
924 const unsigned num_elems = templ->u.buf.last_element - first_elem + 1;
925
926 ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(res),
927 first_elem * elem_size, num_elems * elem_size,
928 elem_size, templ->format, false, false, &view->surface);
929 }
930 else {
931 struct ilo_texture *tex = ilo_texture(res);
932
933 /* warn about degraded performance because of a missing binding flag */
934 if (tex->tiling == INTEL_TILING_NONE &&
935 !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) {
936 ilo_warn("creating sampler view for a resource "
937 "not created for sampling\n");
938 }
939
940 ilo_gpe_init_view_surface_for_texture(ilo->dev, tex,
941 templ->format,
942 templ->u.tex.first_level,
943 templ->u.tex.last_level - templ->u.tex.first_level + 1,
944 templ->u.tex.first_layer,
945 templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
946 false, true, &view->surface);
947 }
948
949 return &view->base;
950 }
951
952 static void
953 ilo_sampler_view_destroy(struct pipe_context *pipe,
954 struct pipe_sampler_view *view)
955 {
956 pipe_resource_reference(&view->texture, NULL);
957 FREE(view);
958 }
959
960 static struct pipe_surface *
961 ilo_create_surface(struct pipe_context *pipe,
962 struct pipe_resource *res,
963 const struct pipe_surface *templ)
964 {
965 struct ilo_context *ilo = ilo_context(pipe);
966 struct ilo_surface_cso *surf;
967
968 surf = MALLOC_STRUCT(ilo_surface_cso);
969 assert(surf);
970
971 surf->base = *templ;
972 pipe_reference_init(&surf->base.reference, 1);
973 surf->base.texture = NULL;
974 pipe_resource_reference(&surf->base.texture, res);
975
976 surf->base.context = pipe;
977 surf->base.width = u_minify(res->width0, templ->u.tex.level);
978 surf->base.height = u_minify(res->height0, templ->u.tex.level);
979
980 surf->is_rt = !util_format_is_depth_or_stencil(templ->format);
981
982 if (surf->is_rt) {
983 /* relax this? */
984 assert(res->target != PIPE_BUFFER);
985
986 /*
987 * classic i965 sets render_cache_rw for constant buffers and sol
988 * surfaces but not render buffers. Why?
989 */
990 ilo_gpe_init_view_surface_for_texture(ilo->dev, ilo_texture(res),
991 templ->format, templ->u.tex.level, 1,
992 templ->u.tex.first_layer,
993 templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
994 true, true, &surf->u.rt);
995 }
996 else {
997 assert(res->target != PIPE_BUFFER);
998
999 ilo_gpe_init_zs_surface(ilo->dev, ilo_texture(res),
1000 templ->format, templ->u.tex.level,
1001 templ->u.tex.first_layer,
1002 templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
1003 &surf->u.zs);
1004 }
1005
1006 return &surf->base;
1007 }
1008
1009 static void
1010 ilo_surface_destroy(struct pipe_context *pipe,
1011 struct pipe_surface *surface)
1012 {
1013 pipe_resource_reference(&surface->texture, NULL);
1014 FREE(surface);
1015 }
1016
1017 static void *
1018 ilo_create_compute_state(struct pipe_context *pipe,
1019 const struct pipe_compute_state *state)
1020 {
1021 struct ilo_context *ilo = ilo_context(pipe);
1022 struct ilo_shader_state *shader;
1023
1024 shader = ilo_shader_create_cs(ilo->dev, state, ilo);
1025 assert(shader);
1026
1027 ilo_shader_cache_add(ilo->shader_cache, shader);
1028
1029 return shader;
1030 }
1031
1032 static void
1033 ilo_bind_compute_state(struct pipe_context *pipe, void *state)
1034 {
1035 struct ilo_context *ilo = ilo_context(pipe);
1036
1037 ilo->cs = state;
1038
1039 ilo->dirty |= ILO_DIRTY_CS;
1040 }
1041
1042 static void
1043 ilo_delete_compute_state(struct pipe_context *pipe, void *state)
1044 {
1045 struct ilo_context *ilo = ilo_context(pipe);
1046 struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
1047
1048 ilo_shader_cache_remove(ilo->shader_cache, cs);
1049 ilo_shader_destroy(cs);
1050 }
1051
1052 static void
1053 ilo_set_compute_resources(struct pipe_context *pipe,
1054 unsigned start, unsigned count,
1055 struct pipe_surface **surfaces)
1056 {
1057 struct ilo_context *ilo = ilo_context(pipe);
1058 struct ilo_resource_state *dst = &ilo->cs_resource;
1059 unsigned i;
1060
1061 assert(start + count <= Elements(dst->states));
1062
1063 if (surfaces) {
1064 for (i = 0; i < count; i++)
1065 pipe_surface_reference(&dst->states[start + i], surfaces[i]);
1066 }
1067 else {
1068 for (i = 0; i < count; i++)
1069 pipe_surface_reference(&dst->states[start + i], NULL);
1070 }
1071
1072 if (dst->count <= start + count) {
1073 if (surfaces)
1074 count += start;
1075 else
1076 count = start;
1077
1078 while (count > 0 && !dst->states[count - 1])
1079 count--;
1080
1081 dst->count = count;
1082 }
1083
1084 ilo->dirty |= ILO_DIRTY_CS_RESOURCE;
1085 }
1086
1087 static void
1088 ilo_set_global_binding(struct pipe_context *pipe,
1089 unsigned start, unsigned count,
1090 struct pipe_resource **resources,
1091 uint32_t **handles)
1092 {
1093 struct ilo_context *ilo = ilo_context(pipe);
1094 struct ilo_global_binding *dst = &ilo->global_binding;
1095 unsigned i;
1096
1097 assert(start + count <= Elements(dst->resources));
1098
1099 if (resources) {
1100 for (i = 0; i < count; i++)
1101 pipe_resource_reference(&dst->resources[start + i], resources[i]);
1102 }
1103 else {
1104 for (i = 0; i < count; i++)
1105 pipe_resource_reference(&dst->resources[start + i], NULL);
1106 }
1107
1108 if (dst->count <= start + count) {
1109 if (resources)
1110 count += start;
1111 else
1112 count = start;
1113
1114 while (count > 0 && !dst->resources[count - 1])
1115 count--;
1116
1117 dst->count = count;
1118 }
1119
1120 ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING;
1121 }
1122
1123 /**
1124 * Initialize state-related functions.
1125 */
1126 void
1127 ilo_init_state_functions(struct ilo_context *ilo)
1128 {
1129 STATIC_ASSERT(ILO_STATE_COUNT <= 32);
1130
1131 ilo->base.create_blend_state = ilo_create_blend_state;
1132 ilo->base.bind_blend_state = ilo_bind_blend_state;
1133 ilo->base.delete_blend_state = ilo_delete_blend_state;
1134 ilo->base.create_sampler_state = ilo_create_sampler_state;
1135 ilo->base.bind_sampler_states = ilo_bind_sampler_states;
1136 ilo->base.delete_sampler_state = ilo_delete_sampler_state;
1137 ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
1138 ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
1139 ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
1140 ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
1141 ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
1142 ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
1143 ilo->base.create_fs_state = ilo_create_fs_state;
1144 ilo->base.bind_fs_state = ilo_bind_fs_state;
1145 ilo->base.delete_fs_state = ilo_delete_fs_state;
1146 ilo->base.create_vs_state = ilo_create_vs_state;
1147 ilo->base.bind_vs_state = ilo_bind_vs_state;
1148 ilo->base.delete_vs_state = ilo_delete_vs_state;
1149 ilo->base.create_gs_state = ilo_create_gs_state;
1150 ilo->base.bind_gs_state = ilo_bind_gs_state;
1151 ilo->base.delete_gs_state = ilo_delete_gs_state;
1152 ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
1153 ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
1154 ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
1155
1156 ilo->base.set_blend_color = ilo_set_blend_color;
1157 ilo->base.set_stencil_ref = ilo_set_stencil_ref;
1158 ilo->base.set_sample_mask = ilo_set_sample_mask;
1159 ilo->base.set_clip_state = ilo_set_clip_state;
1160 ilo->base.set_constant_buffer = ilo_set_constant_buffer;
1161 ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
1162 ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
1163 ilo->base.set_scissor_states = ilo_set_scissor_states;
1164 ilo->base.set_viewport_states = ilo_set_viewport_states;
1165 ilo->base.set_sampler_views = ilo_set_sampler_views;
1166 ilo->base.set_shader_resources = ilo_set_shader_resources;
1167 ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
1168 ilo->base.set_index_buffer = ilo_set_index_buffer;
1169
1170 ilo->base.create_stream_output_target = ilo_create_stream_output_target;
1171 ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
1172 ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
1173
1174 ilo->base.create_sampler_view = ilo_create_sampler_view;
1175 ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
1176
1177 ilo->base.create_surface = ilo_create_surface;
1178 ilo->base.surface_destroy = ilo_surface_destroy;
1179
1180 ilo->base.create_compute_state = ilo_create_compute_state;
1181 ilo->base.bind_compute_state = ilo_bind_compute_state;
1182 ilo->base.delete_compute_state = ilo_delete_compute_state;
1183 ilo->base.set_compute_resources = ilo_set_compute_resources;
1184 ilo->base.set_global_binding = ilo_set_global_binding;
1185 }
1186
1187 void
1188 ilo_init_states(struct ilo_context *ilo)
1189 {
1190 ilo_gpe_set_scissor_null(ilo->dev, &ilo->scissor);
1191
1192 ilo_gpe_init_zs_surface(ilo->dev, NULL,
1193 PIPE_FORMAT_NONE, 0, 0, 1, &ilo->fb.null_zs);
1194
1195 ilo->dirty = ILO_DIRTY_ALL;
1196 }
1197
1198 void
1199 ilo_cleanup_states(struct ilo_context *ilo)
1200 {
1201 unsigned i, sh;
1202
1203 for (i = 0; i < Elements(ilo->vb.states); i++) {
1204 if (ilo->vb.enabled_mask & (1 << i))
1205 pipe_resource_reference(&ilo->vb.states[i].buffer, NULL);
1206 }
1207
1208 pipe_resource_reference(&ilo->ib.buffer, NULL);
1209 pipe_resource_reference(&ilo->ib.hw_resource, NULL);
1210
1211 for (i = 0; i < ilo->so.count; i++)
1212 pipe_so_target_reference(&ilo->so.states[i], NULL);
1213
1214 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
1215 for (i = 0; i < ilo->view[sh].count; i++) {
1216 struct pipe_sampler_view *view = ilo->view[sh].states[i];
1217 pipe_sampler_view_reference(&view, NULL);
1218 }
1219
1220 for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) {
1221 struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i];
1222 pipe_resource_reference(&cbuf->resource, NULL);
1223 }
1224 }
1225
1226 for (i = 0; i < ilo->resource.count; i++)
1227 pipe_surface_reference(&ilo->resource.states[i], NULL);
1228
1229 for (i = 0; i < ilo->fb.state.nr_cbufs; i++)
1230 pipe_surface_reference(&ilo->fb.state.cbufs[i], NULL);
1231
1232 if (ilo->fb.state.zsbuf)
1233 pipe_surface_reference(&ilo->fb.state.zsbuf, NULL);
1234
1235 for (i = 0; i < ilo->cs_resource.count; i++)
1236 pipe_surface_reference(&ilo->cs_resource.states[i], NULL);
1237
1238 for (i = 0; i < ilo->global_binding.count; i++)
1239 pipe_resource_reference(&ilo->global_binding.resources[i], NULL);
1240 }
1241
1242 /**
1243 * Mark all states that have the resource dirty.
1244 */
1245 void
1246 ilo_mark_states_with_resource_dirty(struct ilo_context *ilo,
1247 const struct pipe_resource *res)
1248 {
1249 uint32_t states = 0;
1250 unsigned sh, i;
1251
1252 if (res->target == PIPE_BUFFER) {
1253 uint32_t vb_mask = ilo->vb.enabled_mask;
1254
1255 while (vb_mask) {
1256 const unsigned idx = u_bit_scan(&vb_mask);
1257
1258 if (ilo->vb.states[idx].buffer == res) {
1259 states |= ILO_DIRTY_VB;
1260 break;
1261 }
1262 }
1263
1264 if (ilo->ib.buffer == res) {
1265 states |= ILO_DIRTY_IB;
1266
1267 /*
1268 * finalize_index_buffer() has an optimization that clears
1269 * ILO_DIRTY_IB when the HW states do not change. However, it fails
1270 * to flush the VF cache when the HW states do not change, but the
1271 * contents of the IB has changed. Here, we set the index size to an
1272 * invalid value to avoid the optimization.
1273 */
1274 ilo->ib.hw_index_size = 0;
1275 }
1276
1277 for (i = 0; i < ilo->so.count; i++) {
1278 if (ilo->so.states[i]->buffer == res) {
1279 states |= ILO_DIRTY_SO;
1280 break;
1281 }
1282 }
1283 }
1284
1285 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
1286 for (i = 0; i < ilo->view[sh].count; i++) {
1287 struct pipe_sampler_view *view = ilo->view[sh].states[i];
1288
1289 if (view->texture == res) {
1290 static const unsigned view_dirty_bits[PIPE_SHADER_TYPES] = {
1291 [PIPE_SHADER_VERTEX] = ILO_DIRTY_VIEW_VS,
1292 [PIPE_SHADER_FRAGMENT] = ILO_DIRTY_VIEW_FS,
1293 [PIPE_SHADER_GEOMETRY] = ILO_DIRTY_VIEW_GS,
1294 [PIPE_SHADER_COMPUTE] = ILO_DIRTY_VIEW_CS,
1295 };
1296
1297 states |= view_dirty_bits[sh];
1298 break;
1299 }
1300 }
1301
1302 if (res->target == PIPE_BUFFER) {
1303 for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) {
1304 struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i];
1305
1306 if (cbuf->resource == res) {
1307 states |= ILO_DIRTY_CBUF;
1308 break;
1309 }
1310 }
1311 }
1312 }
1313
1314 for (i = 0; i < ilo->resource.count; i++) {
1315 if (ilo->resource.states[i]->texture == res) {
1316 states |= ILO_DIRTY_RESOURCE;
1317 break;
1318 }
1319 }
1320
1321 /* for now? */
1322 if (res->target != PIPE_BUFFER) {
1323 for (i = 0; i < ilo->fb.state.nr_cbufs; i++) {
1324 if (ilo->fb.state.cbufs[i]->texture == res) {
1325 states |= ILO_DIRTY_FB;
1326 break;
1327 }
1328 }
1329
1330 if (ilo->fb.state.zsbuf && ilo->fb.state.zsbuf->texture == res)
1331 states |= ILO_DIRTY_FB;
1332 }
1333
1334 for (i = 0; i < ilo->cs_resource.count; i++) {
1335 pipe_surface_reference(&ilo->cs_resource.states[i], NULL);
1336 if (ilo->cs_resource.states[i]->texture == res) {
1337 states |= ILO_DIRTY_CS_RESOURCE;
1338 break;
1339 }
1340 }
1341
1342 for (i = 0; i < ilo->global_binding.count; i++) {
1343 if (ilo->global_binding.resources[i] == res) {
1344 states |= ILO_DIRTY_GLOBAL_BINDING;
1345 break;
1346 }
1347 }
1348
1349 ilo->dirty |= states;
1350 }
1351
1352 void
1353 ilo_dump_dirty_flags(uint32_t dirty)
1354 {
1355 static const char *state_names[ILO_STATE_COUNT] = {
1356 [ILO_STATE_VB] = "VB",
1357 [ILO_STATE_VE] = "VE",
1358 [ILO_STATE_IB] = "IB",
1359 [ILO_STATE_VS] = "VS",
1360 [ILO_STATE_GS] = "GS",
1361 [ILO_STATE_SO] = "SO",
1362 [ILO_STATE_CLIP] = "CLIP",
1363 [ILO_STATE_VIEWPORT] = "VIEWPORT",
1364 [ILO_STATE_SCISSOR] = "SCISSOR",
1365 [ILO_STATE_RASTERIZER] = "RASTERIZER",
1366 [ILO_STATE_POLY_STIPPLE] = "POLY_STIPPLE",
1367 [ILO_STATE_SAMPLE_MASK] = "SAMPLE_MASK",
1368 [ILO_STATE_FS] = "FS",
1369 [ILO_STATE_DSA] = "DSA",
1370 [ILO_STATE_STENCIL_REF] = "STENCIL_REF",
1371 [ILO_STATE_BLEND] = "BLEND",
1372 [ILO_STATE_BLEND_COLOR] = "BLEND_COLOR",
1373 [ILO_STATE_FB] = "FB",
1374 [ILO_STATE_SAMPLER_VS] = "SAMPLER_VS",
1375 [ILO_STATE_SAMPLER_GS] = "SAMPLER_GS",
1376 [ILO_STATE_SAMPLER_FS] = "SAMPLER_FS",
1377 [ILO_STATE_SAMPLER_CS] = "SAMPLER_CS",
1378 [ILO_STATE_VIEW_VS] = "VIEW_VS",
1379 [ILO_STATE_VIEW_GS] = "VIEW_GS",
1380 [ILO_STATE_VIEW_FS] = "VIEW_FS",
1381 [ILO_STATE_VIEW_CS] = "VIEW_CS",
1382 [ILO_STATE_CBUF] = "CBUF",
1383 [ILO_STATE_RESOURCE] = "RESOURCE",
1384 [ILO_STATE_CS] = "CS",
1385 [ILO_STATE_CS_RESOURCE] = "CS_RESOURCE",
1386 [ILO_STATE_GLOBAL_BINDING] = "GLOBAL_BINDING",
1387 };
1388
1389 if (!dirty) {
1390 ilo_printf("no state is dirty\n");
1391 return;
1392 }
1393
1394 dirty &= (1U << ILO_STATE_COUNT) - 1;
1395
1396 ilo_printf("%2d states are dirty:", util_bitcount(dirty));
1397 while (dirty) {
1398 const enum ilo_state state = u_bit_scan(&dirty);
1399 ilo_printf(" %s", state_names[state]);
1400 }
1401 ilo_printf("\n");
1402 }