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