ilo_state.c revision 89d1702b9b31488ae95a4364b4161b9186d5220b
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
41static void
42finalize_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
124static void
125finalize_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 */
148void
149ilo_finalize_states(struct ilo_context *ilo)
150{
151   finalize_shader_states(ilo);
152   finalize_constant_buffers(ilo);
153}
154
155static void *
156ilo_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
169static void
170ilo_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
179static void
180ilo_delete_blend_state(struct pipe_context *pipe, void  *state)
181{
182   FREE(state);
183}
184
185static void *
186ilo_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
199static void
200bind_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
247static void
248ilo_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
258static void
259ilo_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
269static void
270ilo_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
280static void
281ilo_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
293static void
294ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
295{
296   FREE(state);
297}
298
299static void *
300ilo_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
313static void
314ilo_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
323static void
324ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
325{
326   FREE(state);
327}
328
329static void *
330ilo_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
343static void
344ilo_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
353static void
354ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
355{
356   FREE(state);
357}
358
359static void *
360ilo_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
367static void
368ilo_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
377static void
378ilo_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
384static void *
385ilo_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
392static void
393ilo_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
402static void
403ilo_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
409static void *
410ilo_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
417static void
418ilo_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
427static void
428ilo_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
434static void *
435ilo_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
450static void
451ilo_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
460static void
461ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
462{
463   FREE(state);
464}
465
466static void
467ilo_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
477static void
478ilo_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
488static void
489ilo_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
499static void
500ilo_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
510static void
511ilo_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
543static void
544ilo_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
554static void
555ilo_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
565static void
566ilo_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
576static void
577ilo_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
587static void
588set_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
635static void
636ilo_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
646static void
647ilo_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
657static void
658ilo_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
668static void
669ilo_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
681static void
682ilo_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
714static void
715ilo_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
727static void
728ilo_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
749static struct pipe_stream_output_target *
750ilo_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
770static void
771ilo_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
795static void
796ilo_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
803static struct pipe_sampler_view *
804ilo_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
822static void
823ilo_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
830static struct pipe_surface *
831ilo_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
852static void
853ilo_surface_destroy(struct pipe_context *pipe,
854                    struct pipe_surface *surface)
855{
856   pipe_resource_reference(&surface->texture, NULL);
857   FREE(surface);
858}
859
860static void *
861ilo_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
868static void
869ilo_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
878static void
879ilo_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
885static void
886ilo_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
918static void
919ilo_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 */
955void
956ilo_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}
1021