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