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