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