ilo_state.c revision eaabb4ead07ae043ecc789024028e225ebd0f318
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_states(struct pipe_context *pipe,
567                       unsigned start_slot,
568                       unsigned num_scissors,
569                       const struct pipe_scissor_state *state)
570{
571   struct ilo_context *ilo = ilo_context(pipe);
572
573   ilo->scissor = *state;
574
575   ilo->dirty |= ILO_DIRTY_SCISSOR;
576}
577
578static void
579ilo_set_viewport_states(struct pipe_context *pipe,
580                        unsigned start_slot,
581                        unsigned num_viewports,
582                        const struct pipe_viewport_state *state)
583{
584   struct ilo_context *ilo = ilo_context(pipe);
585
586   ilo->viewport = *state;
587
588   ilo->dirty |= ILO_DIRTY_VIEWPORT;
589}
590
591static void
592set_sampler_views(struct ilo_context *ilo,
593                  unsigned shader, unsigned start, unsigned count,
594                  struct pipe_sampler_view **views, bool unset_old)
595{
596   struct pipe_sampler_view **dst = ilo->sampler_views[shader].views;
597   unsigned i;
598
599   assert(start + count <= Elements(ilo->sampler_views[shader].views));
600
601   if (unset_old) {
602      if (!views) {
603         start = 0;
604         count = 0;
605      }
606
607      for (i = 0; i < start; i++)
608         pipe_sampler_view_reference(&dst[i], NULL);
609      for (; i < start + count; i++)
610         pipe_sampler_view_reference(&dst[i], views[i - start]);
611      for (; i < ilo->sampler_views[shader].num_views; i++)
612         pipe_sampler_view_reference(&dst[i], NULL);
613
614      ilo->sampler_views[shader].num_views = start + count;
615
616      return;
617   }
618
619   dst += start;
620   if (views) {
621      for (i = 0; i < count; i++)
622         pipe_sampler_view_reference(&dst[i], views[i]);
623   }
624   else {
625      for (i = 0; i < count; i++)
626         pipe_sampler_view_reference(&dst[i], NULL);
627   }
628
629   if (ilo->sampler_views[shader].num_views <= start + count) {
630      count += start;
631
632      while (count > 0 && !ilo->sampler_views[shader].views[count - 1])
633         count--;
634
635      ilo->sampler_views[shader].num_views = count;
636   }
637}
638
639static void
640ilo_set_fragment_sampler_views(struct pipe_context *pipe,
641                               unsigned num_views,
642                               struct pipe_sampler_view **views)
643{
644   struct ilo_context *ilo = ilo_context(pipe);
645
646   set_sampler_views(ilo, PIPE_SHADER_FRAGMENT, 0, num_views, views, true);
647   ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS;
648}
649
650static void
651ilo_set_vertex_sampler_views(struct pipe_context *pipe,
652                             unsigned num_views,
653                             struct pipe_sampler_view **views)
654{
655   struct ilo_context *ilo = ilo_context(pipe);
656
657   set_sampler_views(ilo, PIPE_SHADER_VERTEX, 0, num_views, views, true);
658   ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLER_VIEWS;
659}
660
661static void
662ilo_set_geometry_sampler_views(struct pipe_context *pipe,
663                               unsigned num_views,
664                               struct pipe_sampler_view **views)
665{
666   struct ilo_context *ilo = ilo_context(pipe);
667
668   set_sampler_views(ilo, PIPE_SHADER_GEOMETRY, 0, num_views, views, true);
669   ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS;
670}
671
672static void
673ilo_set_compute_sampler_views(struct pipe_context *pipe,
674                              unsigned start_slot, 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_COMPUTE,
680         start_slot, num_views, views, false);
681
682   ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLER_VIEWS;
683}
684
685static void
686ilo_set_shader_resources(struct pipe_context *pipe,
687                         unsigned start, unsigned count,
688                         struct pipe_surface **surfaces)
689{
690   struct ilo_context *ilo = ilo_context(pipe);
691   struct pipe_surface **dst = ilo->shader_resources.surfaces;
692   unsigned i;
693
694   assert(start + count <= Elements(ilo->shader_resources.surfaces));
695
696   dst += start;
697   if (surfaces) {
698      for (i = 0; i < count; i++)
699         pipe_surface_reference(&dst[i], surfaces[i]);
700   }
701   else {
702      for (i = 0; i < count; i++)
703         pipe_surface_reference(&dst[i], NULL);
704   }
705
706   if (ilo->shader_resources.num_surfaces <= start + count) {
707      count += start;
708
709      while (count > 0 && !ilo->shader_resources.surfaces[count - 1])
710         count--;
711
712      ilo->shader_resources.num_surfaces = count;
713   }
714
715   ilo->dirty |= ILO_DIRTY_SHADER_RESOURCES;
716}
717
718static void
719ilo_set_vertex_buffers(struct pipe_context *pipe,
720                       unsigned start_slot, unsigned num_buffers,
721                       const struct pipe_vertex_buffer *buffers)
722{
723   struct ilo_context *ilo = ilo_context(pipe);
724
725   util_set_vertex_buffers_count(ilo->vertex_buffers.buffers,
726         &ilo->vertex_buffers.num_buffers, buffers, start_slot, num_buffers);
727
728   ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS;
729}
730
731static void
732ilo_set_index_buffer(struct pipe_context *pipe,
733                     const struct pipe_index_buffer *state)
734{
735   struct ilo_context *ilo = ilo_context(pipe);
736
737   if (state) {
738      ilo->index_buffer.index_size = state->index_size;
739      ilo->index_buffer.offset = state->offset;
740      pipe_resource_reference(&ilo->index_buffer.buffer, state->buffer);
741      ilo->index_buffer.user_buffer = state->user_buffer;
742   }
743   else {
744      ilo->index_buffer.index_size = 0;
745      ilo->index_buffer.offset = 0;
746      pipe_resource_reference(&ilo->index_buffer.buffer, NULL);
747      ilo->index_buffer.user_buffer = NULL;
748   }
749
750   ilo->dirty |= ILO_DIRTY_INDEX_BUFFER;
751}
752
753static struct pipe_stream_output_target *
754ilo_create_stream_output_target(struct pipe_context *pipe,
755                                struct pipe_resource *res,
756                                unsigned buffer_offset,
757                                unsigned buffer_size)
758{
759   struct pipe_stream_output_target *target;
760
761   target = MALLOC_STRUCT(pipe_stream_output_target);
762   assert(target);
763
764   pipe_reference_init(&target->reference, 1);
765   target->buffer = NULL;
766   pipe_resource_reference(&target->buffer, res);
767   target->context = pipe;
768   target->buffer_offset = buffer_offset;
769   target->buffer_size = buffer_size;
770
771   return target;
772}
773
774static void
775ilo_set_stream_output_targets(struct pipe_context *pipe,
776                              unsigned num_targets,
777                              struct pipe_stream_output_target **targets,
778                              unsigned append_bitmask)
779{
780   struct ilo_context *ilo = ilo_context(pipe);
781   unsigned i;
782
783   if (!targets)
784      num_targets = 0;
785
786   for (i = 0; i < num_targets; i++) {
787      pipe_so_target_reference(&ilo->stream_output_targets.targets[i],
788                               targets[i]);
789   }
790   for (; i < ilo->stream_output_targets.num_targets; i++)
791      pipe_so_target_reference(&ilo->stream_output_targets.targets[i], NULL);
792
793   ilo->stream_output_targets.num_targets = num_targets;
794   ilo->stream_output_targets.append_bitmask = append_bitmask;
795
796   ilo->dirty |= ILO_DIRTY_STREAM_OUTPUT_TARGETS;
797}
798
799static void
800ilo_stream_output_target_destroy(struct pipe_context *pipe,
801                                 struct pipe_stream_output_target *target)
802{
803   pipe_resource_reference(&target->buffer, NULL);
804   FREE(target);
805}
806
807static struct pipe_sampler_view *
808ilo_create_sampler_view(struct pipe_context *pipe,
809                        struct pipe_resource *res,
810                        const struct pipe_sampler_view *templ)
811{
812   struct pipe_sampler_view *view;
813
814   view = MALLOC_STRUCT(pipe_sampler_view);
815   assert(view);
816
817   *view = *templ;
818   pipe_reference_init(&view->reference, 1);
819   view->texture = NULL;
820   pipe_resource_reference(&view->texture, res);
821   view->context = pipe;
822
823   return view;
824}
825
826static void
827ilo_sampler_view_destroy(struct pipe_context *pipe,
828                         struct pipe_sampler_view *view)
829{
830   pipe_resource_reference(&view->texture, NULL);
831   FREE(view);
832}
833
834static struct pipe_surface *
835ilo_create_surface(struct pipe_context *pipe,
836                   struct pipe_resource *res,
837                   const struct pipe_surface *templ)
838{
839   struct pipe_surface *surface;
840
841   surface = MALLOC_STRUCT(pipe_surface);
842   assert(surface);
843
844   *surface = *templ;
845   pipe_reference_init(&surface->reference, 1);
846   surface->texture = NULL;
847   pipe_resource_reference(&surface->texture, res);
848
849   surface->context = pipe;
850   surface->width = u_minify(res->width0, surface->u.tex.level);
851   surface->height = u_minify(res->height0, surface->u.tex.level);
852
853   return surface;
854}
855
856static void
857ilo_surface_destroy(struct pipe_context *pipe,
858                    struct pipe_surface *surface)
859{
860   pipe_resource_reference(&surface->texture, NULL);
861   FREE(surface);
862}
863
864static void *
865ilo_create_compute_state(struct pipe_context *pipe,
866                         const struct pipe_compute_state *state)
867{
868   struct ilo_context *ilo = ilo_context(pipe);
869   return ilo_shader_state_create(ilo, PIPE_SHADER_COMPUTE, state);
870}
871
872static void
873ilo_bind_compute_state(struct pipe_context *pipe, void *state)
874{
875   struct ilo_context *ilo = ilo_context(pipe);
876
877   ilo->compute = state;
878
879   ilo->dirty |= ILO_DIRTY_COMPUTE;
880}
881
882static void
883ilo_delete_compute_state(struct pipe_context *pipe, void *state)
884{
885   struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
886   ilo_shader_state_destroy(cs);
887}
888
889static void
890ilo_set_compute_resources(struct pipe_context *pipe,
891                          unsigned start, unsigned count,
892                          struct pipe_surface **surfaces)
893{
894   struct ilo_context *ilo = ilo_context(pipe);
895   struct pipe_surface **dst = ilo->compute_resources.surfaces;
896   unsigned i;
897
898   assert(start + count <= Elements(ilo->compute_resources.surfaces));
899
900   dst += start;
901   if (surfaces) {
902      for (i = 0; i < count; i++)
903         pipe_surface_reference(&dst[i], surfaces[i]);
904   }
905   else {
906      for (i = 0; i < count; i++)
907         pipe_surface_reference(&dst[i], NULL);
908   }
909
910   if (ilo->compute_resources.num_surfaces <= start + count) {
911      count += start;
912
913      while (count > 0 && !ilo->compute_resources.surfaces[count - 1])
914         count--;
915
916      ilo->compute_resources.num_surfaces = count;
917   }
918
919   ilo->dirty |= ILO_DIRTY_COMPUTE_RESOURCES;
920}
921
922static void
923ilo_set_global_binding(struct pipe_context *pipe,
924                       unsigned start, unsigned count,
925                       struct pipe_resource **resources,
926                       uint32_t **handles)
927{
928   struct ilo_context *ilo = ilo_context(pipe);
929   struct pipe_resource **dst = ilo->global_binding.resources;
930   unsigned i;
931
932   assert(start + count <= Elements(ilo->global_binding.resources));
933
934   dst += start;
935   if (resources) {
936      for (i = 0; i < count; i++)
937         pipe_resource_reference(&dst[i], resources[i]);
938   }
939   else {
940      for (i = 0; i < count; i++)
941         pipe_resource_reference(&dst[i], NULL);
942   }
943
944   if (ilo->global_binding.num_resources <= start + count) {
945      count += start;
946
947      while (count > 0 && !ilo->global_binding.resources[count - 1])
948         count--;
949
950      ilo->global_binding.num_resources = count;
951   }
952
953   ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING;
954}
955
956/**
957 * Initialize state-related functions.
958 */
959void
960ilo_init_state_functions(struct ilo_context *ilo)
961{
962   STATIC_ASSERT(ILO_STATE_COUNT <= 32);
963
964   ilo->base.create_blend_state = ilo_create_blend_state;
965   ilo->base.bind_blend_state = ilo_bind_blend_state;
966   ilo->base.delete_blend_state = ilo_delete_blend_state;
967   ilo->base.create_sampler_state = ilo_create_sampler_state;
968   ilo->base.bind_fragment_sampler_states = ilo_bind_fragment_sampler_states;
969   ilo->base.bind_vertex_sampler_states = ilo_bind_vertex_sampler_states;
970   ilo->base.bind_geometry_sampler_states = ilo_bind_geometry_sampler_states;
971   ilo->base.bind_compute_sampler_states = ilo_bind_compute_sampler_states;
972   ilo->base.delete_sampler_state = ilo_delete_sampler_state;
973   ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
974   ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
975   ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
976   ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
977   ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
978   ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
979   ilo->base.create_fs_state = ilo_create_fs_state;
980   ilo->base.bind_fs_state = ilo_bind_fs_state;
981   ilo->base.delete_fs_state = ilo_delete_fs_state;
982   ilo->base.create_vs_state = ilo_create_vs_state;
983   ilo->base.bind_vs_state = ilo_bind_vs_state;
984   ilo->base.delete_vs_state = ilo_delete_vs_state;
985   ilo->base.create_gs_state = ilo_create_gs_state;
986   ilo->base.bind_gs_state = ilo_bind_gs_state;
987   ilo->base.delete_gs_state = ilo_delete_gs_state;
988   ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
989   ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
990   ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
991
992   ilo->base.set_blend_color = ilo_set_blend_color;
993   ilo->base.set_stencil_ref = ilo_set_stencil_ref;
994   ilo->base.set_sample_mask = ilo_set_sample_mask;
995   ilo->base.set_clip_state = ilo_set_clip_state;
996   ilo->base.set_constant_buffer = ilo_set_constant_buffer;
997   ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
998   ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
999   ilo->base.set_scissor_states = ilo_set_scissor_states;
1000   ilo->base.set_viewport_states = ilo_set_viewport_states;
1001   ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views;
1002   ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views;
1003   ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views;
1004   ilo->base.set_compute_sampler_views = ilo_set_compute_sampler_views;
1005   ilo->base.set_shader_resources = ilo_set_shader_resources;
1006   ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
1007   ilo->base.set_index_buffer = ilo_set_index_buffer;
1008
1009   ilo->base.create_stream_output_target = ilo_create_stream_output_target;
1010   ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
1011   ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
1012
1013   ilo->base.create_sampler_view = ilo_create_sampler_view;
1014   ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
1015
1016   ilo->base.create_surface = ilo_create_surface;
1017   ilo->base.surface_destroy = ilo_surface_destroy;
1018
1019   ilo->base.create_compute_state = ilo_create_compute_state;
1020   ilo->base.bind_compute_state = ilo_bind_compute_state;
1021   ilo->base.delete_compute_state = ilo_delete_compute_state;
1022   ilo->base.set_compute_resources = ilo_set_compute_resources;
1023   ilo->base.set_global_binding = ilo_set_global_binding;
1024}
1025