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