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