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