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