ilo: add emit_SURFACE_STATE() for sampler views
[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].states) - 1;
135
136 /* find the last cbuf */
137 while (last_cbuf >= 0 &&
138 !ilo->cbuf[sh].states[last_cbuf].buffer)
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_rasterizer_state *rast;
307
308 rast = MALLOC_STRUCT(ilo_rasterizer_state);
309 assert(rast);
310
311 rast->state = *state;
312
313 return rast;
314 }
315
316 static void
317 ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state)
318 {
319 struct ilo_context *ilo = ilo_context(pipe);
320
321 ilo->rasterizer = state;
322
323 ilo->dirty |= ILO_DIRTY_RASTERIZER;
324 }
325
326 static void
327 ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
328 {
329 FREE(state);
330 }
331
332 static void *
333 ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
334 const struct pipe_depth_stencil_alpha_state *state)
335 {
336 struct ilo_context *ilo = ilo_context(pipe);
337 struct ilo_dsa_state *dsa;
338
339 dsa = MALLOC_STRUCT(ilo_dsa_state);
340 assert(dsa);
341
342 ilo_gpe_init_dsa(ilo->dev, state, dsa);
343
344 return dsa;
345 }
346
347 static void
348 ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
349 {
350 struct ilo_context *ilo = ilo_context(pipe);
351
352 ilo->dsa = state;
353
354 ilo->dirty |= ILO_DIRTY_DEPTH_STENCIL_ALPHA;
355 }
356
357 static void
358 ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
359 {
360 FREE(state);
361 }
362
363 static void *
364 ilo_create_fs_state(struct pipe_context *pipe,
365 const struct pipe_shader_state *state)
366 {
367 struct ilo_context *ilo = ilo_context(pipe);
368 return ilo_shader_state_create(ilo, PIPE_SHADER_FRAGMENT, state);
369 }
370
371 static void
372 ilo_bind_fs_state(struct pipe_context *pipe, void *state)
373 {
374 struct ilo_context *ilo = ilo_context(pipe);
375
376 ilo->fs = state;
377
378 ilo->dirty |= ILO_DIRTY_FS;
379 }
380
381 static void
382 ilo_delete_fs_state(struct pipe_context *pipe, void *state)
383 {
384 struct ilo_shader_state *fs = (struct ilo_shader_state *) state;
385 ilo_shader_state_destroy(fs);
386 }
387
388 static void *
389 ilo_create_vs_state(struct pipe_context *pipe,
390 const struct pipe_shader_state *state)
391 {
392 struct ilo_context *ilo = ilo_context(pipe);
393 return ilo_shader_state_create(ilo, PIPE_SHADER_VERTEX, state);
394 }
395
396 static void
397 ilo_bind_vs_state(struct pipe_context *pipe, void *state)
398 {
399 struct ilo_context *ilo = ilo_context(pipe);
400
401 ilo->vs = state;
402
403 ilo->dirty |= ILO_DIRTY_VS;
404 }
405
406 static void
407 ilo_delete_vs_state(struct pipe_context *pipe, void *state)
408 {
409 struct ilo_shader_state *vs = (struct ilo_shader_state *) state;
410 ilo_shader_state_destroy(vs);
411 }
412
413 static void *
414 ilo_create_gs_state(struct pipe_context *pipe,
415 const struct pipe_shader_state *state)
416 {
417 struct ilo_context *ilo = ilo_context(pipe);
418 return ilo_shader_state_create(ilo, PIPE_SHADER_GEOMETRY, state);
419 }
420
421 static void
422 ilo_bind_gs_state(struct pipe_context *pipe, void *state)
423 {
424 struct ilo_context *ilo = ilo_context(pipe);
425
426 ilo->gs = state;
427
428 ilo->dirty |= ILO_DIRTY_GS;
429 }
430
431 static void
432 ilo_delete_gs_state(struct pipe_context *pipe, void *state)
433 {
434 struct ilo_shader_state *gs = (struct ilo_shader_state *) state;
435 ilo_shader_state_destroy(gs);
436 }
437
438 static void *
439 ilo_create_vertex_elements_state(struct pipe_context *pipe,
440 unsigned num_elements,
441 const struct pipe_vertex_element *elements)
442 {
443 struct ilo_context *ilo = ilo_context(pipe);
444 struct ilo_ve_state *ve;
445
446 ve = MALLOC_STRUCT(ilo_ve_state);
447 assert(ve);
448
449 ilo_gpe_init_ve(ilo->dev, num_elements, elements, ve);
450
451 return ve;
452 }
453
454 static void
455 ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
456 {
457 struct ilo_context *ilo = ilo_context(pipe);
458
459 ilo->ve = state;
460
461 ilo->dirty |= ILO_DIRTY_VERTEX_ELEMENTS;
462 }
463
464 static void
465 ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
466 {
467 struct ilo_ve_state *ve = state;
468
469 FREE(ve);
470 }
471
472 static void
473 ilo_set_blend_color(struct pipe_context *pipe,
474 const struct pipe_blend_color *state)
475 {
476 struct ilo_context *ilo = ilo_context(pipe);
477
478 ilo->blend_color = *state;
479
480 ilo->dirty |= ILO_DIRTY_BLEND_COLOR;
481 }
482
483 static void
484 ilo_set_stencil_ref(struct pipe_context *pipe,
485 const struct pipe_stencil_ref *state)
486 {
487 struct ilo_context *ilo = ilo_context(pipe);
488
489 ilo->stencil_ref = *state;
490
491 ilo->dirty |= ILO_DIRTY_STENCIL_REF;
492 }
493
494 static void
495 ilo_set_sample_mask(struct pipe_context *pipe,
496 unsigned sample_mask)
497 {
498 struct ilo_context *ilo = ilo_context(pipe);
499
500 ilo->sample_mask = sample_mask;
501
502 ilo->dirty |= ILO_DIRTY_SAMPLE_MASK;
503 }
504
505 static void
506 ilo_set_clip_state(struct pipe_context *pipe,
507 const struct pipe_clip_state *state)
508 {
509 struct ilo_context *ilo = ilo_context(pipe);
510
511 ilo->clip = *state;
512
513 ilo->dirty |= ILO_DIRTY_CLIP;
514 }
515
516 static void
517 ilo_set_constant_buffer(struct pipe_context *pipe,
518 uint shader, uint index,
519 struct pipe_constant_buffer *buf)
520 {
521 struct ilo_context *ilo = ilo_context(pipe);
522 struct pipe_constant_buffer *cbuf;
523
524 assert(shader < Elements(ilo->cbuf));
525 assert(index < Elements(ilo->cbuf[shader].states));
526
527 cbuf = &ilo->cbuf[shader].states[index];
528
529 pipe_resource_reference(&cbuf->buffer, NULL);
530
531 if (buf) {
532 pipe_resource_reference(&cbuf->buffer, buf->buffer);
533 cbuf->buffer_offset = buf->buffer_offset;
534 cbuf->buffer_size = buf->buffer_size;
535 cbuf->user_buffer = buf->user_buffer;
536 }
537 else {
538 cbuf->buffer_offset = 0;
539 cbuf->buffer_size = 0;
540 cbuf->user_buffer = 0;
541 }
542
543 /* the correct value will be set in ilo_finalize_states() */
544 ilo->cbuf[shader].count = 0;
545
546 ilo->dirty |= ILO_DIRTY_CONSTANT_BUFFER;
547 }
548
549 static void
550 ilo_set_framebuffer_state(struct pipe_context *pipe,
551 const struct pipe_framebuffer_state *state)
552 {
553 struct ilo_context *ilo = ilo_context(pipe);
554
555 util_copy_framebuffer_state(&ilo->fb.state, state);
556
557 if (state->nr_cbufs)
558 ilo->fb.num_samples = state->cbufs[0]->texture->nr_samples;
559 else if (state->zsbuf)
560 ilo->fb.num_samples = state->zsbuf->texture->nr_samples;
561 else
562 ilo->fb.num_samples = 1;
563
564 if (!ilo->fb.num_samples)
565 ilo->fb.num_samples = 1;
566
567 ilo->dirty |= ILO_DIRTY_FRAMEBUFFER;
568 }
569
570 static void
571 ilo_set_polygon_stipple(struct pipe_context *pipe,
572 const struct pipe_poly_stipple *state)
573 {
574 struct ilo_context *ilo = ilo_context(pipe);
575
576 ilo->poly_stipple = *state;
577
578 ilo->dirty |= ILO_DIRTY_POLY_STIPPLE;
579 }
580
581 static void
582 ilo_set_scissor_states(struct pipe_context *pipe,
583 unsigned start_slot,
584 unsigned num_scissors,
585 const struct pipe_scissor_state *scissors)
586 {
587 struct ilo_context *ilo = ilo_context(pipe);
588
589 ilo_gpe_set_scissor(ilo->dev, start_slot, num_scissors,
590 scissors, &ilo->scissor);
591
592 ilo->dirty |= ILO_DIRTY_SCISSOR;
593 }
594
595 static void
596 ilo_set_viewport_states(struct pipe_context *pipe,
597 unsigned start_slot,
598 unsigned num_viewports,
599 const struct pipe_viewport_state *viewports)
600 {
601 struct ilo_context *ilo = ilo_context(pipe);
602
603 if (viewports) {
604 unsigned i;
605
606 for (i = 0; i < num_viewports; i++) {
607 ilo_gpe_set_viewport_cso(ilo->dev, &viewports[i],
608 &ilo->viewport.cso[start_slot + i]);
609 }
610
611 if (ilo->viewport.count < start_slot + num_viewports)
612 ilo->viewport.count = start_slot + num_viewports;
613
614 /* need to save viewport 0 for util_blitter */
615 if (!start_slot && num_viewports)
616 ilo->viewport.viewport0 = viewports[0];
617 }
618 else {
619 if (ilo->viewport.count <= start_slot + num_viewports &&
620 ilo->viewport.count > start_slot)
621 ilo->viewport.count = start_slot;
622 }
623
624 ilo->dirty |= ILO_DIRTY_VIEWPORT;
625 }
626
627 static void
628 set_sampler_views(struct ilo_context *ilo,
629 unsigned shader, unsigned start, unsigned count,
630 struct pipe_sampler_view **views, bool unset_old)
631 {
632 struct pipe_sampler_view **dst = ilo->view[shader].states;
633 unsigned i;
634
635 assert(start + count <= Elements(ilo->view[shader].states));
636
637 if (unset_old) {
638 if (!views) {
639 start = 0;
640 count = 0;
641 }
642
643 for (i = 0; i < start; i++)
644 pipe_sampler_view_reference(&dst[i], NULL);
645 for (; i < start + count; i++)
646 pipe_sampler_view_reference(&dst[i], views[i - start]);
647 for (; i < ilo->view[shader].count; i++)
648 pipe_sampler_view_reference(&dst[i], NULL);
649
650 ilo->view[shader].count = start + count;
651
652 return;
653 }
654
655 dst += start;
656 if (views) {
657 for (i = 0; i < count; i++)
658 pipe_sampler_view_reference(&dst[i], views[i]);
659 }
660 else {
661 for (i = 0; i < count; i++)
662 pipe_sampler_view_reference(&dst[i], NULL);
663 }
664
665 if (ilo->view[shader].count <= start + count) {
666 count += start;
667
668 while (count > 0 && !ilo->view[shader].states[count - 1])
669 count--;
670
671 ilo->view[shader].count = count;
672 }
673 }
674
675 static void
676 ilo_set_fragment_sampler_views(struct pipe_context *pipe,
677 unsigned num_views,
678 struct pipe_sampler_view **views)
679 {
680 struct ilo_context *ilo = ilo_context(pipe);
681
682 set_sampler_views(ilo, PIPE_SHADER_FRAGMENT, 0, num_views, views, true);
683 ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS;
684 }
685
686 static void
687 ilo_set_vertex_sampler_views(struct pipe_context *pipe,
688 unsigned num_views,
689 struct pipe_sampler_view **views)
690 {
691 struct ilo_context *ilo = ilo_context(pipe);
692
693 set_sampler_views(ilo, PIPE_SHADER_VERTEX, 0, num_views, views, true);
694 ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLER_VIEWS;
695 }
696
697 static void
698 ilo_set_geometry_sampler_views(struct pipe_context *pipe,
699 unsigned num_views,
700 struct pipe_sampler_view **views)
701 {
702 struct ilo_context *ilo = ilo_context(pipe);
703
704 set_sampler_views(ilo, PIPE_SHADER_GEOMETRY, 0, num_views, views, true);
705 ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS;
706 }
707
708 static void
709 ilo_set_compute_sampler_views(struct pipe_context *pipe,
710 unsigned start_slot, unsigned num_views,
711 struct pipe_sampler_view **views)
712 {
713 struct ilo_context *ilo = ilo_context(pipe);
714
715 set_sampler_views(ilo, PIPE_SHADER_COMPUTE,
716 start_slot, num_views, views, false);
717
718 ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLER_VIEWS;
719 }
720
721 static void
722 ilo_set_shader_resources(struct pipe_context *pipe,
723 unsigned start, unsigned count,
724 struct pipe_surface **surfaces)
725 {
726 struct ilo_context *ilo = ilo_context(pipe);
727 struct pipe_surface **dst = ilo->resource.states;
728 unsigned i;
729
730 assert(start + count <= Elements(ilo->resource.states));
731
732 dst += start;
733 if (surfaces) {
734 for (i = 0; i < count; i++)
735 pipe_surface_reference(&dst[i], surfaces[i]);
736 }
737 else {
738 for (i = 0; i < count; i++)
739 pipe_surface_reference(&dst[i], NULL);
740 }
741
742 if (ilo->resource.count <= start + count) {
743 count += start;
744
745 while (count > 0 && !ilo->resource.states[count - 1])
746 count--;
747
748 ilo->resource.count = count;
749 }
750
751 ilo->dirty |= ILO_DIRTY_SHADER_RESOURCES;
752 }
753
754 static void
755 ilo_set_vertex_buffers(struct pipe_context *pipe,
756 unsigned start_slot, unsigned num_buffers,
757 const struct pipe_vertex_buffer *buffers)
758 {
759 struct ilo_context *ilo = ilo_context(pipe);
760
761 util_set_vertex_buffers_mask(ilo->vb.states,
762 &ilo->vb.enabled_mask, buffers, start_slot, num_buffers);
763
764 ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS;
765 }
766
767 static void
768 ilo_set_index_buffer(struct pipe_context *pipe,
769 const struct pipe_index_buffer *state)
770 {
771 struct ilo_context *ilo = ilo_context(pipe);
772
773 if (state) {
774 ilo->ib.state.index_size = state->index_size;
775 ilo->ib.state.offset = state->offset;
776 pipe_resource_reference(&ilo->ib.state.buffer, state->buffer);
777 ilo->ib.state.user_buffer = state->user_buffer;
778 }
779 else {
780 ilo->ib.state.index_size = 0;
781 ilo->ib.state.offset = 0;
782 pipe_resource_reference(&ilo->ib.state.buffer, NULL);
783 ilo->ib.state.user_buffer = NULL;
784 }
785
786 ilo->dirty |= ILO_DIRTY_INDEX_BUFFER;
787 }
788
789 static struct pipe_stream_output_target *
790 ilo_create_stream_output_target(struct pipe_context *pipe,
791 struct pipe_resource *res,
792 unsigned buffer_offset,
793 unsigned buffer_size)
794 {
795 struct pipe_stream_output_target *target;
796
797 target = MALLOC_STRUCT(pipe_stream_output_target);
798 assert(target);
799
800 pipe_reference_init(&target->reference, 1);
801 target->buffer = NULL;
802 pipe_resource_reference(&target->buffer, res);
803 target->context = pipe;
804 target->buffer_offset = buffer_offset;
805 target->buffer_size = buffer_size;
806
807 return target;
808 }
809
810 static void
811 ilo_set_stream_output_targets(struct pipe_context *pipe,
812 unsigned num_targets,
813 struct pipe_stream_output_target **targets,
814 unsigned append_bitmask)
815 {
816 struct ilo_context *ilo = ilo_context(pipe);
817 unsigned i;
818
819 if (!targets)
820 num_targets = 0;
821
822 for (i = 0; i < num_targets; i++)
823 pipe_so_target_reference(&ilo->so.states[i], targets[i]);
824
825 for (; i < ilo->so.count; i++)
826 pipe_so_target_reference(&ilo->so.states[i], NULL);
827
828 ilo->so.count = num_targets;
829 ilo->so.append_bitmask = append_bitmask;
830
831 ilo->so.enabled = (ilo->so.count > 0);
832
833 ilo->dirty |= ILO_DIRTY_STREAM_OUTPUT_TARGETS;
834 }
835
836 static void
837 ilo_stream_output_target_destroy(struct pipe_context *pipe,
838 struct pipe_stream_output_target *target)
839 {
840 pipe_resource_reference(&target->buffer, NULL);
841 FREE(target);
842 }
843
844 static struct pipe_sampler_view *
845 ilo_create_sampler_view(struct pipe_context *pipe,
846 struct pipe_resource *res,
847 const struct pipe_sampler_view *templ)
848 {
849 struct ilo_context *ilo = ilo_context(pipe);
850 struct ilo_view_cso *view;
851
852 view = MALLOC_STRUCT(ilo_view_cso);
853 assert(view);
854
855 view->base = *templ;
856 pipe_reference_init(&view->base.reference, 1);
857 view->base.texture = NULL;
858 pipe_resource_reference(&view->base.texture, res);
859 view->base.context = pipe;
860
861 if (res->target == PIPE_BUFFER) {
862 const unsigned elem_size = util_format_get_blocksize(templ->format);
863 const unsigned first_elem = templ->u.buf.first_element;
864 const unsigned num_elems = templ->u.buf.last_element - first_elem + 1;
865
866 ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(res),
867 first_elem * elem_size, num_elems * elem_size,
868 elem_size, templ->format, false, false, &view->surface);
869 }
870 else {
871 ilo_gpe_init_view_surface_for_texture(ilo->dev, ilo_texture(res),
872 templ->format,
873 templ->u.tex.first_level,
874 templ->u.tex.last_level - templ->u.tex.first_level + 1,
875 templ->u.tex.first_layer,
876 templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
877 false, false, &view->surface);
878 }
879
880 return &view->base;
881 }
882
883 static void
884 ilo_sampler_view_destroy(struct pipe_context *pipe,
885 struct pipe_sampler_view *view)
886 {
887 pipe_resource_reference(&view->texture, NULL);
888 FREE(view);
889 }
890
891 static struct pipe_surface *
892 ilo_create_surface(struct pipe_context *pipe,
893 struct pipe_resource *res,
894 const struct pipe_surface *templ)
895 {
896 struct pipe_surface *surface;
897
898 surface = MALLOC_STRUCT(pipe_surface);
899 assert(surface);
900
901 *surface = *templ;
902 pipe_reference_init(&surface->reference, 1);
903 surface->texture = NULL;
904 pipe_resource_reference(&surface->texture, res);
905
906 surface->context = pipe;
907 surface->width = u_minify(res->width0, surface->u.tex.level);
908 surface->height = u_minify(res->height0, surface->u.tex.level);
909
910 return surface;
911 }
912
913 static void
914 ilo_surface_destroy(struct pipe_context *pipe,
915 struct pipe_surface *surface)
916 {
917 pipe_resource_reference(&surface->texture, NULL);
918 FREE(surface);
919 }
920
921 static void *
922 ilo_create_compute_state(struct pipe_context *pipe,
923 const struct pipe_compute_state *state)
924 {
925 struct ilo_context *ilo = ilo_context(pipe);
926 return ilo_shader_state_create(ilo, PIPE_SHADER_COMPUTE, state);
927 }
928
929 static void
930 ilo_bind_compute_state(struct pipe_context *pipe, void *state)
931 {
932 struct ilo_context *ilo = ilo_context(pipe);
933
934 ilo->cs = state;
935
936 ilo->dirty |= ILO_DIRTY_COMPUTE;
937 }
938
939 static void
940 ilo_delete_compute_state(struct pipe_context *pipe, void *state)
941 {
942 struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
943 ilo_shader_state_destroy(cs);
944 }
945
946 static void
947 ilo_set_compute_resources(struct pipe_context *pipe,
948 unsigned start, unsigned count,
949 struct pipe_surface **surfaces)
950 {
951 struct ilo_context *ilo = ilo_context(pipe);
952 struct pipe_surface **dst = ilo->cs_resource.states;
953 unsigned i;
954
955 assert(start + count <= Elements(ilo->cs_resource.states));
956
957 dst += start;
958 if (surfaces) {
959 for (i = 0; i < count; i++)
960 pipe_surface_reference(&dst[i], surfaces[i]);
961 }
962 else {
963 for (i = 0; i < count; i++)
964 pipe_surface_reference(&dst[i], NULL);
965 }
966
967 if (ilo->cs_resource.count <= start + count) {
968 count += start;
969
970 while (count > 0 && !ilo->cs_resource.states[count - 1])
971 count--;
972
973 ilo->cs_resource.count = count;
974 }
975
976 ilo->dirty |= ILO_DIRTY_COMPUTE_RESOURCES;
977 }
978
979 static void
980 ilo_set_global_binding(struct pipe_context *pipe,
981 unsigned start, unsigned count,
982 struct pipe_resource **resources,
983 uint32_t **handles)
984 {
985 struct ilo_context *ilo = ilo_context(pipe);
986 struct pipe_resource **dst = ilo->global_binding.resources;
987 unsigned i;
988
989 assert(start + count <= Elements(ilo->global_binding.resources));
990
991 dst += start;
992 if (resources) {
993 for (i = 0; i < count; i++)
994 pipe_resource_reference(&dst[i], resources[i]);
995 }
996 else {
997 for (i = 0; i < count; i++)
998 pipe_resource_reference(&dst[i], NULL);
999 }
1000
1001 if (ilo->global_binding.count <= start + count) {
1002 count += start;
1003
1004 while (count > 0 && !ilo->global_binding.resources[count - 1])
1005 count--;
1006
1007 ilo->global_binding.count = count;
1008 }
1009
1010 ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING;
1011 }
1012
1013 /**
1014 * Initialize state-related functions.
1015 */
1016 void
1017 ilo_init_state_functions(struct ilo_context *ilo)
1018 {
1019 STATIC_ASSERT(ILO_STATE_COUNT <= 32);
1020
1021 ilo->base.create_blend_state = ilo_create_blend_state;
1022 ilo->base.bind_blend_state = ilo_bind_blend_state;
1023 ilo->base.delete_blend_state = ilo_delete_blend_state;
1024 ilo->base.create_sampler_state = ilo_create_sampler_state;
1025 ilo->base.bind_fragment_sampler_states = ilo_bind_fragment_sampler_states;
1026 ilo->base.bind_vertex_sampler_states = ilo_bind_vertex_sampler_states;
1027 ilo->base.bind_geometry_sampler_states = ilo_bind_geometry_sampler_states;
1028 ilo->base.bind_compute_sampler_states = ilo_bind_compute_sampler_states;
1029 ilo->base.delete_sampler_state = ilo_delete_sampler_state;
1030 ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
1031 ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
1032 ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
1033 ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
1034 ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
1035 ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
1036 ilo->base.create_fs_state = ilo_create_fs_state;
1037 ilo->base.bind_fs_state = ilo_bind_fs_state;
1038 ilo->base.delete_fs_state = ilo_delete_fs_state;
1039 ilo->base.create_vs_state = ilo_create_vs_state;
1040 ilo->base.bind_vs_state = ilo_bind_vs_state;
1041 ilo->base.delete_vs_state = ilo_delete_vs_state;
1042 ilo->base.create_gs_state = ilo_create_gs_state;
1043 ilo->base.bind_gs_state = ilo_bind_gs_state;
1044 ilo->base.delete_gs_state = ilo_delete_gs_state;
1045 ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
1046 ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
1047 ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
1048
1049 ilo->base.set_blend_color = ilo_set_blend_color;
1050 ilo->base.set_stencil_ref = ilo_set_stencil_ref;
1051 ilo->base.set_sample_mask = ilo_set_sample_mask;
1052 ilo->base.set_clip_state = ilo_set_clip_state;
1053 ilo->base.set_constant_buffer = ilo_set_constant_buffer;
1054 ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
1055 ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
1056 ilo->base.set_scissor_states = ilo_set_scissor_states;
1057 ilo->base.set_viewport_states = ilo_set_viewport_states;
1058 ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views;
1059 ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views;
1060 ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views;
1061 ilo->base.set_compute_sampler_views = ilo_set_compute_sampler_views;
1062 ilo->base.set_shader_resources = ilo_set_shader_resources;
1063 ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
1064 ilo->base.set_index_buffer = ilo_set_index_buffer;
1065
1066 ilo->base.create_stream_output_target = ilo_create_stream_output_target;
1067 ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
1068 ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
1069
1070 ilo->base.create_sampler_view = ilo_create_sampler_view;
1071 ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
1072
1073 ilo->base.create_surface = ilo_create_surface;
1074 ilo->base.surface_destroy = ilo_surface_destroy;
1075
1076 ilo->base.create_compute_state = ilo_create_compute_state;
1077 ilo->base.bind_compute_state = ilo_bind_compute_state;
1078 ilo->base.delete_compute_state = ilo_delete_compute_state;
1079 ilo->base.set_compute_resources = ilo_set_compute_resources;
1080 ilo->base.set_global_binding = ilo_set_global_binding;
1081 }
1082
1083 void
1084 ilo_init_states(struct ilo_context *ilo)
1085 {
1086 ilo_gpe_set_scissor_null(ilo->dev, &ilo->scissor);
1087 }
1088
1089 void
1090 ilo_cleanup_states(struct ilo_context *ilo)
1091 {
1092 }