ilo: hook up pipe context state functions
[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->constant_buffers[sh].buffers) - 1;
134
135 /* find the last cbuf */
136 while (last_cbuf >= 0 &&
137 !ilo->constant_buffers[sh].buffers[last_cbuf].buffer)
138 last_cbuf--;
139
140 ilo->constant_buffers[sh].num_buffers = 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 pipe_blend_state *blend;
160
161 blend = MALLOC_STRUCT(pipe_blend_state);
162 assert(blend);
163
164 *blend = *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->samplers[shader].samplers;
205 unsigned i;
206
207 assert(start + count <= Elements(ilo->samplers[shader].samplers));
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->samplers[shader].num_samplers; i++)
220 dst[i] = NULL;
221
222 ilo->samplers[shader].num_samplers = 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->samplers[shader].num_samplers <= start + count) {
238 count += start;
239
240 while (count > 0 && !ilo->samplers[shader].samplers[count - 1])
241 count--;
242
243 ilo->samplers[shader].num_samplers = 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 pipe_rasterizer_state *rast;
304
305 rast = MALLOC_STRUCT(pipe_rasterizer_state);
306 assert(rast);
307
308 *rast = *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 pipe_depth_stencil_alpha_state *dsa;
334
335 dsa = MALLOC_STRUCT(pipe_depth_stencil_alpha_state);
336 assert(dsa);
337
338 *dsa = *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->depth_stencil_alpha = 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_vertex_element *velem;
440
441 velem = MALLOC_STRUCT(ilo_vertex_element);
442 assert(velem);
443
444 memcpy(velem->elements, elements, sizeof(*elements) * num_elements);
445 velem->num_elements = num_elements;
446
447 return velem;
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->vertex_elements = 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 FREE(state);
464 }
465
466 static void
467 ilo_set_blend_color(struct pipe_context *pipe,
468 const struct pipe_blend_color *state)
469 {
470 struct ilo_context *ilo = ilo_context(pipe);
471
472 ilo->blend_color = *state;
473
474 ilo->dirty |= ILO_DIRTY_BLEND_COLOR;
475 }
476
477 static void
478 ilo_set_stencil_ref(struct pipe_context *pipe,
479 const struct pipe_stencil_ref *state)
480 {
481 struct ilo_context *ilo = ilo_context(pipe);
482
483 ilo->stencil_ref = *state;
484
485 ilo->dirty |= ILO_DIRTY_STENCIL_REF;
486 }
487
488 static void
489 ilo_set_sample_mask(struct pipe_context *pipe,
490 unsigned sample_mask)
491 {
492 struct ilo_context *ilo = ilo_context(pipe);
493
494 ilo->sample_mask = sample_mask;
495
496 ilo->dirty |= ILO_DIRTY_SAMPLE_MASK;
497 }
498
499 static void
500 ilo_set_clip_state(struct pipe_context *pipe,
501 const struct pipe_clip_state *state)
502 {
503 struct ilo_context *ilo = ilo_context(pipe);
504
505 ilo->clip = *state;
506
507 ilo->dirty |= ILO_DIRTY_CLIP;
508 }
509
510 static void
511 ilo_set_constant_buffer(struct pipe_context *pipe,
512 uint shader, uint index,
513 struct pipe_constant_buffer *buf)
514 {
515 struct ilo_context *ilo = ilo_context(pipe);
516 struct pipe_constant_buffer *cbuf;
517
518 assert(shader < Elements(ilo->constant_buffers));
519 assert(index < Elements(ilo->constant_buffers[shader].buffers));
520
521 cbuf = &ilo->constant_buffers[shader].buffers[index];
522
523 pipe_resource_reference(&cbuf->buffer, NULL);
524
525 if (buf) {
526 pipe_resource_reference(&cbuf->buffer, buf->buffer);
527 cbuf->buffer_offset = buf->buffer_offset;
528 cbuf->buffer_size = buf->buffer_size;
529 cbuf->user_buffer = buf->user_buffer;
530 }
531 else {
532 cbuf->buffer_offset = 0;
533 cbuf->buffer_size = 0;
534 cbuf->user_buffer = 0;
535 }
536
537 /* the correct value will be set in ilo_finalize_states() */
538 ilo->constant_buffers[shader].num_buffers = 0;
539
540 ilo->dirty |= ILO_DIRTY_CONSTANT_BUFFER;
541 }
542
543 static void
544 ilo_set_framebuffer_state(struct pipe_context *pipe,
545 const struct pipe_framebuffer_state *state)
546 {
547 struct ilo_context *ilo = ilo_context(pipe);
548
549 util_copy_framebuffer_state(&ilo->framebuffer, state);
550
551 ilo->dirty |= ILO_DIRTY_FRAMEBUFFER;
552 }
553
554 static void
555 ilo_set_polygon_stipple(struct pipe_context *pipe,
556 const struct pipe_poly_stipple *state)
557 {
558 struct ilo_context *ilo = ilo_context(pipe);
559
560 ilo->poly_stipple = *state;
561
562 ilo->dirty |= ILO_DIRTY_POLY_STIPPLE;
563 }
564
565 static void
566 ilo_set_scissor_state(struct pipe_context *pipe,
567 const struct pipe_scissor_state *state)
568 {
569 struct ilo_context *ilo = ilo_context(pipe);
570
571 ilo->scissor = *state;
572
573 ilo->dirty |= ILO_DIRTY_SCISSOR;
574 }
575
576 static void
577 ilo_set_viewport_state(struct pipe_context *pipe,
578 const struct pipe_viewport_state *state)
579 {
580 struct ilo_context *ilo = ilo_context(pipe);
581
582 ilo->viewport = *state;
583
584 ilo->dirty |= ILO_DIRTY_VIEWPORT;
585 }
586
587 static void
588 set_sampler_views(struct ilo_context *ilo,
589 unsigned shader, unsigned start, unsigned count,
590 struct pipe_sampler_view **views, bool unset_old)
591 {
592 struct pipe_sampler_view **dst = ilo->sampler_views[shader].views;
593 unsigned i;
594
595 assert(start + count <= Elements(ilo->sampler_views[shader].views));
596
597 if (unset_old) {
598 if (!views) {
599 start = 0;
600 count = 0;
601 }
602
603 for (i = 0; i < start; i++)
604 pipe_sampler_view_reference(&dst[i], NULL);
605 for (; i < start + count; i++)
606 pipe_sampler_view_reference(&dst[i], views[i - start]);
607 for (; i < ilo->sampler_views[shader].num_views; i++)
608 pipe_sampler_view_reference(&dst[i], NULL);
609
610 ilo->sampler_views[shader].num_views = start + count;
611
612 return;
613 }
614
615 dst += start;
616 if (views) {
617 for (i = 0; i < count; i++)
618 pipe_sampler_view_reference(&dst[i], views[i]);
619 }
620 else {
621 for (i = 0; i < count; i++)
622 pipe_sampler_view_reference(&dst[i], NULL);
623 }
624
625 if (ilo->sampler_views[shader].num_views <= start + count) {
626 count += start;
627
628 while (count > 0 && !ilo->sampler_views[shader].views[count - 1])
629 count--;
630
631 ilo->sampler_views[shader].num_views = count;
632 }
633 }
634
635 static void
636 ilo_set_fragment_sampler_views(struct pipe_context *pipe,
637 unsigned num_views,
638 struct pipe_sampler_view **views)
639 {
640 struct ilo_context *ilo = ilo_context(pipe);
641
642 set_sampler_views(ilo, PIPE_SHADER_FRAGMENT, 0, num_views, views, true);
643 ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS;
644 }
645
646 static void
647 ilo_set_vertex_sampler_views(struct pipe_context *pipe,
648 unsigned num_views,
649 struct pipe_sampler_view **views)
650 {
651 struct ilo_context *ilo = ilo_context(pipe);
652
653 set_sampler_views(ilo, PIPE_SHADER_VERTEX, 0, num_views, views, true);
654 ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLER_VIEWS;
655 }
656
657 static void
658 ilo_set_geometry_sampler_views(struct pipe_context *pipe,
659 unsigned num_views,
660 struct pipe_sampler_view **views)
661 {
662 struct ilo_context *ilo = ilo_context(pipe);
663
664 set_sampler_views(ilo, PIPE_SHADER_GEOMETRY, 0, num_views, views, true);
665 ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS;
666 }
667
668 static void
669 ilo_set_compute_sampler_views(struct pipe_context *pipe,
670 unsigned start_slot, unsigned num_views,
671 struct pipe_sampler_view **views)
672 {
673 struct ilo_context *ilo = ilo_context(pipe);
674
675 set_sampler_views(ilo, PIPE_SHADER_COMPUTE,
676 start_slot, num_views, views, false);
677
678 ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLER_VIEWS;
679 }
680
681 static void
682 ilo_set_shader_resources(struct pipe_context *pipe,
683 unsigned start, unsigned count,
684 struct pipe_surface **surfaces)
685 {
686 struct ilo_context *ilo = ilo_context(pipe);
687 struct pipe_surface **dst = ilo->shader_resources.surfaces;
688 unsigned i;
689
690 assert(start + count <= Elements(ilo->shader_resources.surfaces));
691
692 dst += start;
693 if (surfaces) {
694 for (i = 0; i < count; i++)
695 pipe_surface_reference(&dst[i], surfaces[i]);
696 }
697 else {
698 for (i = 0; i < count; i++)
699 pipe_surface_reference(&dst[i], NULL);
700 }
701
702 if (ilo->shader_resources.num_surfaces <= start + count) {
703 count += start;
704
705 while (count > 0 && !ilo->shader_resources.surfaces[count - 1])
706 count--;
707
708 ilo->shader_resources.num_surfaces = count;
709 }
710
711 ilo->dirty |= ILO_DIRTY_SHADER_RESOURCES;
712 }
713
714 static void
715 ilo_set_vertex_buffers(struct pipe_context *pipe,
716 unsigned start_slot, unsigned num_buffers,
717 const struct pipe_vertex_buffer *buffers)
718 {
719 struct ilo_context *ilo = ilo_context(pipe);
720
721 util_set_vertex_buffers_count(ilo->vertex_buffers.buffers,
722 &ilo->vertex_buffers.num_buffers, buffers, start_slot, num_buffers);
723
724 ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS;
725 }
726
727 static void
728 ilo_set_index_buffer(struct pipe_context *pipe,
729 const struct pipe_index_buffer *state)
730 {
731 struct ilo_context *ilo = ilo_context(pipe);
732
733 if (state) {
734 ilo->index_buffer.index_size = state->index_size;
735 ilo->index_buffer.offset = state->offset;
736 pipe_resource_reference(&ilo->index_buffer.buffer, state->buffer);
737 ilo->index_buffer.user_buffer = state->user_buffer;
738 }
739 else {
740 ilo->index_buffer.index_size = 0;
741 ilo->index_buffer.offset = 0;
742 pipe_resource_reference(&ilo->index_buffer.buffer, NULL);
743 ilo->index_buffer.user_buffer = NULL;
744 }
745
746 ilo->dirty |= ILO_DIRTY_INDEX_BUFFER;
747 }
748
749 static struct pipe_stream_output_target *
750 ilo_create_stream_output_target(struct pipe_context *pipe,
751 struct pipe_resource *res,
752 unsigned buffer_offset,
753 unsigned buffer_size)
754 {
755 struct pipe_stream_output_target *target;
756
757 target = MALLOC_STRUCT(pipe_stream_output_target);
758 assert(target);
759
760 pipe_reference_init(&target->reference, 1);
761 target->buffer = NULL;
762 pipe_resource_reference(&target->buffer, res);
763 target->context = pipe;
764 target->buffer_offset = buffer_offset;
765 target->buffer_size = buffer_size;
766
767 return target;
768 }
769
770 static void
771 ilo_set_stream_output_targets(struct pipe_context *pipe,
772 unsigned num_targets,
773 struct pipe_stream_output_target **targets,
774 unsigned append_bitmask)
775 {
776 struct ilo_context *ilo = ilo_context(pipe);
777 unsigned i;
778
779 if (!targets)
780 num_targets = 0;
781
782 for (i = 0; i < num_targets; i++) {
783 pipe_so_target_reference(&ilo->stream_output_targets.targets[i],
784 targets[i]);
785 }
786 for (; i < ilo->stream_output_targets.num_targets; i++)
787 pipe_so_target_reference(&ilo->stream_output_targets.targets[i], NULL);
788
789 ilo->stream_output_targets.num_targets = num_targets;
790 ilo->stream_output_targets.append_bitmask = append_bitmask;
791
792 ilo->dirty |= ILO_DIRTY_STREAM_OUTPUT_TARGETS;
793 }
794
795 static void
796 ilo_stream_output_target_destroy(struct pipe_context *pipe,
797 struct pipe_stream_output_target *target)
798 {
799 pipe_resource_reference(&target->buffer, NULL);
800 FREE(target);
801 }
802
803 static struct pipe_sampler_view *
804 ilo_create_sampler_view(struct pipe_context *pipe,
805 struct pipe_resource *res,
806 const struct pipe_sampler_view *templ)
807 {
808 struct pipe_sampler_view *view;
809
810 view = MALLOC_STRUCT(pipe_sampler_view);
811 assert(view);
812
813 *view = *templ;
814 pipe_reference_init(&view->reference, 1);
815 view->texture = NULL;
816 pipe_resource_reference(&view->texture, res);
817 view->context = pipe;
818
819 return view;
820 }
821
822 static void
823 ilo_sampler_view_destroy(struct pipe_context *pipe,
824 struct pipe_sampler_view *view)
825 {
826 pipe_resource_reference(&view->texture, NULL);
827 FREE(view);
828 }
829
830 static struct pipe_surface *
831 ilo_create_surface(struct pipe_context *pipe,
832 struct pipe_resource *res,
833 const struct pipe_surface *templ)
834 {
835 struct pipe_surface *surface;
836
837 surface = MALLOC_STRUCT(pipe_surface);
838 assert(surface);
839
840 *surface = *templ;
841 pipe_reference_init(&surface->reference, 1);
842 surface->texture = NULL;
843 pipe_resource_reference(&surface->texture, res);
844
845 surface->context = pipe;
846 surface->width = u_minify(res->width0, surface->u.tex.level);
847 surface->height = u_minify(res->height0, surface->u.tex.level);
848
849 return surface;
850 }
851
852 static void
853 ilo_surface_destroy(struct pipe_context *pipe,
854 struct pipe_surface *surface)
855 {
856 pipe_resource_reference(&surface->texture, NULL);
857 FREE(surface);
858 }
859
860 static void *
861 ilo_create_compute_state(struct pipe_context *pipe,
862 const struct pipe_compute_state *state)
863 {
864 struct ilo_context *ilo = ilo_context(pipe);
865 return ilo_shader_state_create(ilo, PIPE_SHADER_COMPUTE, state);
866 }
867
868 static void
869 ilo_bind_compute_state(struct pipe_context *pipe, void *state)
870 {
871 struct ilo_context *ilo = ilo_context(pipe);
872
873 ilo->compute = state;
874
875 ilo->dirty |= ILO_DIRTY_COMPUTE;
876 }
877
878 static void
879 ilo_delete_compute_state(struct pipe_context *pipe, void *state)
880 {
881 struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
882 ilo_shader_state_destroy(cs);
883 }
884
885 static void
886 ilo_set_compute_resources(struct pipe_context *pipe,
887 unsigned start, unsigned count,
888 struct pipe_surface **surfaces)
889 {
890 struct ilo_context *ilo = ilo_context(pipe);
891 struct pipe_surface **dst = ilo->compute_resources.surfaces;
892 unsigned i;
893
894 assert(start + count <= Elements(ilo->compute_resources.surfaces));
895
896 dst += start;
897 if (surfaces) {
898 for (i = 0; i < count; i++)
899 pipe_surface_reference(&dst[i], surfaces[i]);
900 }
901 else {
902 for (i = 0; i < count; i++)
903 pipe_surface_reference(&dst[i], NULL);
904 }
905
906 if (ilo->compute_resources.num_surfaces <= start + count) {
907 count += start;
908
909 while (count > 0 && !ilo->compute_resources.surfaces[count - 1])
910 count--;
911
912 ilo->compute_resources.num_surfaces = count;
913 }
914
915 ilo->dirty |= ILO_DIRTY_COMPUTE_RESOURCES;
916 }
917
918 static void
919 ilo_set_global_binding(struct pipe_context *pipe,
920 unsigned start, unsigned count,
921 struct pipe_resource **resources,
922 uint32_t **handles)
923 {
924 struct ilo_context *ilo = ilo_context(pipe);
925 struct pipe_resource **dst = ilo->global_binding.resources;
926 unsigned i;
927
928 assert(start + count <= Elements(ilo->global_binding.resources));
929
930 dst += start;
931 if (resources) {
932 for (i = 0; i < count; i++)
933 pipe_resource_reference(&dst[i], resources[i]);
934 }
935 else {
936 for (i = 0; i < count; i++)
937 pipe_resource_reference(&dst[i], NULL);
938 }
939
940 if (ilo->global_binding.num_resources <= start + count) {
941 count += start;
942
943 while (count > 0 && !ilo->global_binding.resources[count - 1])
944 count--;
945
946 ilo->global_binding.num_resources = count;
947 }
948
949 ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING;
950 }
951
952 /**
953 * Initialize state-related functions.
954 */
955 void
956 ilo_init_state_functions(struct ilo_context *ilo)
957 {
958 STATIC_ASSERT(ILO_STATE_COUNT <= 32);
959
960 ilo->base.create_blend_state = ilo_create_blend_state;
961 ilo->base.bind_blend_state = ilo_bind_blend_state;
962 ilo->base.delete_blend_state = ilo_delete_blend_state;
963 ilo->base.create_sampler_state = ilo_create_sampler_state;
964 ilo->base.bind_fragment_sampler_states = ilo_bind_fragment_sampler_states;
965 ilo->base.bind_vertex_sampler_states = ilo_bind_vertex_sampler_states;
966 ilo->base.bind_geometry_sampler_states = ilo_bind_geometry_sampler_states;
967 ilo->base.bind_compute_sampler_states = ilo_bind_compute_sampler_states;
968 ilo->base.delete_sampler_state = ilo_delete_sampler_state;
969 ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
970 ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
971 ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
972 ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
973 ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
974 ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
975 ilo->base.create_fs_state = ilo_create_fs_state;
976 ilo->base.bind_fs_state = ilo_bind_fs_state;
977 ilo->base.delete_fs_state = ilo_delete_fs_state;
978 ilo->base.create_vs_state = ilo_create_vs_state;
979 ilo->base.bind_vs_state = ilo_bind_vs_state;
980 ilo->base.delete_vs_state = ilo_delete_vs_state;
981 ilo->base.create_gs_state = ilo_create_gs_state;
982 ilo->base.bind_gs_state = ilo_bind_gs_state;
983 ilo->base.delete_gs_state = ilo_delete_gs_state;
984 ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
985 ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
986 ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
987
988 ilo->base.set_blend_color = ilo_set_blend_color;
989 ilo->base.set_stencil_ref = ilo_set_stencil_ref;
990 ilo->base.set_sample_mask = ilo_set_sample_mask;
991 ilo->base.set_clip_state = ilo_set_clip_state;
992 ilo->base.set_constant_buffer = ilo_set_constant_buffer;
993 ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
994 ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
995 ilo->base.set_scissor_state = ilo_set_scissor_state;
996 ilo->base.set_viewport_state = ilo_set_viewport_state;
997 ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views;
998 ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views;
999 ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views;
1000 ilo->base.set_compute_sampler_views = ilo_set_compute_sampler_views;
1001 ilo->base.set_shader_resources = ilo_set_shader_resources;
1002 ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
1003 ilo->base.set_index_buffer = ilo_set_index_buffer;
1004
1005 ilo->base.create_stream_output_target = ilo_create_stream_output_target;
1006 ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
1007 ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
1008
1009 ilo->base.create_sampler_view = ilo_create_sampler_view;
1010 ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
1011
1012 ilo->base.create_surface = ilo_create_surface;
1013 ilo->base.surface_destroy = ilo_surface_destroy;
1014
1015 ilo->base.create_compute_state = ilo_create_compute_state;
1016 ilo->base.bind_compute_state = ilo_bind_compute_state;
1017 ilo->base.delete_compute_state = ilo_delete_compute_state;
1018 ilo->base.set_compute_resources = ilo_set_compute_resources;
1019 ilo->base.set_global_binding = ilo_set_global_binding;
1020 }