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