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