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