OSDN Git Service

35e2e85e4e460dbbe3eaa0c30f42634f2d6bfb98
[android-x86/external-mesa.git] / src / gallium / drivers / ilo / ilo_state.c
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
42 static void
43 finalize_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
125 static void
126 finalize_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].cso) - 1;
135
136       /* find the last cbuf */
137       while (last_cbuf >= 0 &&
138              !ilo->cbuf[sh].cso[last_cbuf].resource)
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  */
149 void
150 ilo_finalize_states(struct ilo_context *ilo)
151 {
152    finalize_shader_states(ilo);
153    finalize_constant_buffers(ilo);
154 }
155
156 static void *
157 ilo_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
171 static void
172 ilo_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
181 static void
182 ilo_delete_blend_state(struct pipe_context *pipe, void  *state)
183 {
184    FREE(state);
185 }
186
187 static void *
188 ilo_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
202 static void
203 bind_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
250 static void
251 ilo_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
261 static void
262 ilo_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
272 static void
273 ilo_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
283 static void
284 ilo_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
296 static void
297 ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
298 {
299    FREE(state);
300 }
301
302 static void *
303 ilo_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
316 static void
317 ilo_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
326 static void
327 ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
328 {
329    FREE(state);
330 }
331
332 static void *
333 ilo_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
347 static void
348 ilo_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
357 static void
358 ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
359 {
360    FREE(state);
361 }
362
363 static void *
364 ilo_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
371 static void
372 ilo_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
381 static void
382 ilo_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
388 static void *
389 ilo_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
396 static void
397 ilo_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
406 static void
407 ilo_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
413 static void *
414 ilo_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
421 static void
422 ilo_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
431 static void
432 ilo_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
438 static void *
439 ilo_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
454 static void
455 ilo_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
464 static void
465 ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
466 {
467    struct ilo_ve_state *ve = state;
468
469    FREE(ve);
470 }
471
472 static void
473 ilo_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
483 static void
484 ilo_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
494 static void
495 ilo_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
505 static void
506 ilo_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
516 static void
517 ilo_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 ilo_cbuf_cso *cbuf;
523
524    assert(shader < Elements(ilo->cbuf));
525    assert(index < Elements(ilo->cbuf[shader].cso));
526
527    cbuf = &ilo->cbuf[shader].cso[index];
528
529    if (buf) {
530       const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
531
532       pipe_resource_reference(&cbuf->resource, buf->buffer);
533
534       ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(buf->buffer),
535             buf->buffer_offset, buf->buffer_size,
536             util_format_get_blocksize(elem_format), elem_format,
537             false, false, &cbuf->surface);
538    }
539    else {
540       pipe_resource_reference(&cbuf->resource, NULL);
541       cbuf->surface.bo = NULL;
542    }
543
544    /* the correct value will be set in ilo_finalize_states() */
545    ilo->cbuf[shader].count = 0;
546
547    ilo->dirty |= ILO_DIRTY_CONSTANT_BUFFER;
548 }
549
550 static void
551 ilo_set_framebuffer_state(struct pipe_context *pipe,
552                           const struct pipe_framebuffer_state *state)
553 {
554    struct ilo_context *ilo = ilo_context(pipe);
555
556    util_copy_framebuffer_state(&ilo->fb.state, state);
557
558    if (state->nr_cbufs)
559       ilo->fb.num_samples = state->cbufs[0]->texture->nr_samples;
560    else if (state->zsbuf)
561       ilo->fb.num_samples = state->zsbuf->texture->nr_samples;
562    else
563       ilo->fb.num_samples = 1;
564
565    if (!ilo->fb.num_samples)
566       ilo->fb.num_samples = 1;
567
568    ilo->dirty |= ILO_DIRTY_FRAMEBUFFER;
569 }
570
571 static void
572 ilo_set_polygon_stipple(struct pipe_context *pipe,
573                         const struct pipe_poly_stipple *state)
574 {
575    struct ilo_context *ilo = ilo_context(pipe);
576
577    ilo->poly_stipple = *state;
578
579    ilo->dirty |= ILO_DIRTY_POLY_STIPPLE;
580 }
581
582 static void
583 ilo_set_scissor_states(struct pipe_context *pipe,
584                        unsigned start_slot,
585                        unsigned num_scissors,
586                        const struct pipe_scissor_state *scissors)
587 {
588    struct ilo_context *ilo = ilo_context(pipe);
589
590    ilo_gpe_set_scissor(ilo->dev, start_slot, num_scissors,
591          scissors, &ilo->scissor);
592
593    ilo->dirty |= ILO_DIRTY_SCISSOR;
594 }
595
596 static void
597 ilo_set_viewport_states(struct pipe_context *pipe,
598                         unsigned start_slot,
599                         unsigned num_viewports,
600                         const struct pipe_viewport_state *viewports)
601 {
602    struct ilo_context *ilo = ilo_context(pipe);
603
604    if (viewports) {
605       unsigned i;
606
607       for (i = 0; i < num_viewports; i++) {
608          ilo_gpe_set_viewport_cso(ilo->dev, &viewports[i],
609                &ilo->viewport.cso[start_slot + i]);
610       }
611
612       if (ilo->viewport.count < start_slot + num_viewports)
613          ilo->viewport.count = start_slot + num_viewports;
614
615       /* need to save viewport 0 for util_blitter */
616       if (!start_slot && num_viewports)
617          ilo->viewport.viewport0 = viewports[0];
618    }
619    else {
620       if (ilo->viewport.count <= start_slot + num_viewports &&
621           ilo->viewport.count > start_slot)
622          ilo->viewport.count = start_slot;
623    }
624
625    ilo->dirty |= ILO_DIRTY_VIEWPORT;
626 }
627
628 static void
629 set_sampler_views(struct ilo_context *ilo,
630                   unsigned shader, unsigned start, unsigned count,
631                   struct pipe_sampler_view **views, bool unset_old)
632 {
633    struct pipe_sampler_view **dst = ilo->view[shader].states;
634    unsigned i;
635
636    assert(start + count <= Elements(ilo->view[shader].states));
637
638    if (unset_old) {
639       if (!views) {
640          start = 0;
641          count = 0;
642       }
643
644       for (i = 0; i < start; i++)
645          pipe_sampler_view_reference(&dst[i], NULL);
646       for (; i < start + count; i++)
647          pipe_sampler_view_reference(&dst[i], views[i - start]);
648       for (; i < ilo->view[shader].count; i++)
649          pipe_sampler_view_reference(&dst[i], NULL);
650
651       ilo->view[shader].count = start + count;
652
653       return;
654    }
655
656    dst += start;
657    if (views) {
658       for (i = 0; i < count; i++)
659          pipe_sampler_view_reference(&dst[i], views[i]);
660    }
661    else {
662       for (i = 0; i < count; i++)
663          pipe_sampler_view_reference(&dst[i], NULL);
664    }
665
666    if (ilo->view[shader].count <= start + count) {
667       count += start;
668
669       while (count > 0 && !ilo->view[shader].states[count - 1])
670          count--;
671
672       ilo->view[shader].count = count;
673    }
674 }
675
676 static void
677 ilo_set_fragment_sampler_views(struct pipe_context *pipe,
678                                unsigned num_views,
679                                struct pipe_sampler_view **views)
680 {
681    struct ilo_context *ilo = ilo_context(pipe);
682
683    set_sampler_views(ilo, PIPE_SHADER_FRAGMENT, 0, num_views, views, true);
684    ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS;
685 }
686
687 static void
688 ilo_set_vertex_sampler_views(struct pipe_context *pipe,
689                              unsigned num_views,
690                              struct pipe_sampler_view **views)
691 {
692    struct ilo_context *ilo = ilo_context(pipe);
693
694    set_sampler_views(ilo, PIPE_SHADER_VERTEX, 0, num_views, views, true);
695    ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLER_VIEWS;
696 }
697
698 static void
699 ilo_set_geometry_sampler_views(struct pipe_context *pipe,
700                                unsigned num_views,
701                                struct pipe_sampler_view **views)
702 {
703    struct ilo_context *ilo = ilo_context(pipe);
704
705    set_sampler_views(ilo, PIPE_SHADER_GEOMETRY, 0, num_views, views, true);
706    ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS;
707 }
708
709 static void
710 ilo_set_compute_sampler_views(struct pipe_context *pipe,
711                               unsigned start_slot, unsigned num_views,
712                               struct pipe_sampler_view **views)
713 {
714    struct ilo_context *ilo = ilo_context(pipe);
715
716    set_sampler_views(ilo, PIPE_SHADER_COMPUTE,
717          start_slot, num_views, views, false);
718
719    ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLER_VIEWS;
720 }
721
722 static void
723 ilo_set_shader_resources(struct pipe_context *pipe,
724                          unsigned start, unsigned count,
725                          struct pipe_surface **surfaces)
726 {
727    struct ilo_context *ilo = ilo_context(pipe);
728    struct pipe_surface **dst = ilo->resource.states;
729    unsigned i;
730
731    assert(start + count <= Elements(ilo->resource.states));
732
733    dst += start;
734    if (surfaces) {
735       for (i = 0; i < count; i++)
736          pipe_surface_reference(&dst[i], surfaces[i]);
737    }
738    else {
739       for (i = 0; i < count; i++)
740          pipe_surface_reference(&dst[i], NULL);
741    }
742
743    if (ilo->resource.count <= start + count) {
744       count += start;
745
746       while (count > 0 && !ilo->resource.states[count - 1])
747          count--;
748
749       ilo->resource.count = count;
750    }
751
752    ilo->dirty |= ILO_DIRTY_SHADER_RESOURCES;
753 }
754
755 static void
756 ilo_set_vertex_buffers(struct pipe_context *pipe,
757                        unsigned start_slot, unsigned num_buffers,
758                        const struct pipe_vertex_buffer *buffers)
759 {
760    struct ilo_context *ilo = ilo_context(pipe);
761
762    util_set_vertex_buffers_mask(ilo->vb.states,
763          &ilo->vb.enabled_mask, buffers, start_slot, num_buffers);
764
765    ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS;
766 }
767
768 static void
769 ilo_set_index_buffer(struct pipe_context *pipe,
770                      const struct pipe_index_buffer *state)
771 {
772    struct ilo_context *ilo = ilo_context(pipe);
773
774    if (state) {
775       ilo->ib.state.index_size = state->index_size;
776       ilo->ib.state.offset = state->offset;
777       pipe_resource_reference(&ilo->ib.state.buffer, state->buffer);
778       ilo->ib.state.user_buffer = state->user_buffer;
779    }
780    else {
781       ilo->ib.state.index_size = 0;
782       ilo->ib.state.offset = 0;
783       pipe_resource_reference(&ilo->ib.state.buffer, NULL);
784       ilo->ib.state.user_buffer = NULL;
785    }
786
787    ilo->dirty |= ILO_DIRTY_INDEX_BUFFER;
788 }
789
790 static struct pipe_stream_output_target *
791 ilo_create_stream_output_target(struct pipe_context *pipe,
792                                 struct pipe_resource *res,
793                                 unsigned buffer_offset,
794                                 unsigned buffer_size)
795 {
796    struct pipe_stream_output_target *target;
797
798    target = MALLOC_STRUCT(pipe_stream_output_target);
799    assert(target);
800
801    pipe_reference_init(&target->reference, 1);
802    target->buffer = NULL;
803    pipe_resource_reference(&target->buffer, res);
804    target->context = pipe;
805    target->buffer_offset = buffer_offset;
806    target->buffer_size = buffer_size;
807
808    return target;
809 }
810
811 static void
812 ilo_set_stream_output_targets(struct pipe_context *pipe,
813                               unsigned num_targets,
814                               struct pipe_stream_output_target **targets,
815                               unsigned append_bitmask)
816 {
817    struct ilo_context *ilo = ilo_context(pipe);
818    unsigned i;
819
820    if (!targets)
821       num_targets = 0;
822
823    for (i = 0; i < num_targets; i++)
824       pipe_so_target_reference(&ilo->so.states[i], targets[i]);
825
826    for (; i < ilo->so.count; i++)
827       pipe_so_target_reference(&ilo->so.states[i], NULL);
828
829    ilo->so.count = num_targets;
830    ilo->so.append_bitmask = append_bitmask;
831
832    ilo->so.enabled = (ilo->so.count > 0);
833
834    ilo->dirty |= ILO_DIRTY_STREAM_OUTPUT_TARGETS;
835 }
836
837 static void
838 ilo_stream_output_target_destroy(struct pipe_context *pipe,
839                                  struct pipe_stream_output_target *target)
840 {
841    pipe_resource_reference(&target->buffer, NULL);
842    FREE(target);
843 }
844
845 static struct pipe_sampler_view *
846 ilo_create_sampler_view(struct pipe_context *pipe,
847                         struct pipe_resource *res,
848                         const struct pipe_sampler_view *templ)
849 {
850    struct ilo_context *ilo = ilo_context(pipe);
851    struct ilo_view_cso *view;
852
853    view = MALLOC_STRUCT(ilo_view_cso);
854    assert(view);
855
856    view->base = *templ;
857    pipe_reference_init(&view->base.reference, 1);
858    view->base.texture = NULL;
859    pipe_resource_reference(&view->base.texture, res);
860    view->base.context = pipe;
861
862    if (res->target == PIPE_BUFFER) {
863       const unsigned elem_size = util_format_get_blocksize(templ->format);
864       const unsigned first_elem = templ->u.buf.first_element;
865       const unsigned num_elems = templ->u.buf.last_element - first_elem + 1;
866
867       ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(res),
868             first_elem * elem_size, num_elems * elem_size,
869             elem_size, templ->format, false, false, &view->surface);
870    }
871    else {
872       ilo_gpe_init_view_surface_for_texture(ilo->dev, ilo_texture(res),
873             templ->format,
874             templ->u.tex.first_level,
875             templ->u.tex.last_level - templ->u.tex.first_level + 1,
876             templ->u.tex.first_layer,
877             templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
878             false, false, &view->surface);
879    }
880
881    return &view->base;
882 }
883
884 static void
885 ilo_sampler_view_destroy(struct pipe_context *pipe,
886                          struct pipe_sampler_view *view)
887 {
888    pipe_resource_reference(&view->texture, NULL);
889    FREE(view);
890 }
891
892 static struct pipe_surface *
893 ilo_create_surface(struct pipe_context *pipe,
894                    struct pipe_resource *res,
895                    const struct pipe_surface *templ)
896 {
897    struct pipe_surface *surface;
898
899    surface = MALLOC_STRUCT(pipe_surface);
900    assert(surface);
901
902    *surface = *templ;
903    pipe_reference_init(&surface->reference, 1);
904    surface->texture = NULL;
905    pipe_resource_reference(&surface->texture, res);
906
907    surface->context = pipe;
908    surface->width = u_minify(res->width0, surface->u.tex.level);
909    surface->height = u_minify(res->height0, surface->u.tex.level);
910
911    return surface;
912 }
913
914 static void
915 ilo_surface_destroy(struct pipe_context *pipe,
916                     struct pipe_surface *surface)
917 {
918    pipe_resource_reference(&surface->texture, NULL);
919    FREE(surface);
920 }
921
922 static void *
923 ilo_create_compute_state(struct pipe_context *pipe,
924                          const struct pipe_compute_state *state)
925 {
926    struct ilo_context *ilo = ilo_context(pipe);
927    return ilo_shader_state_create(ilo, PIPE_SHADER_COMPUTE, state);
928 }
929
930 static void
931 ilo_bind_compute_state(struct pipe_context *pipe, void *state)
932 {
933    struct ilo_context *ilo = ilo_context(pipe);
934
935    ilo->cs = state;
936
937    ilo->dirty |= ILO_DIRTY_COMPUTE;
938 }
939
940 static void
941 ilo_delete_compute_state(struct pipe_context *pipe, void *state)
942 {
943    struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
944    ilo_shader_state_destroy(cs);
945 }
946
947 static void
948 ilo_set_compute_resources(struct pipe_context *pipe,
949                           unsigned start, unsigned count,
950                           struct pipe_surface **surfaces)
951 {
952    struct ilo_context *ilo = ilo_context(pipe);
953    struct pipe_surface **dst = ilo->cs_resource.states;
954    unsigned i;
955
956    assert(start + count <= Elements(ilo->cs_resource.states));
957
958    dst += start;
959    if (surfaces) {
960       for (i = 0; i < count; i++)
961          pipe_surface_reference(&dst[i], surfaces[i]);
962    }
963    else {
964       for (i = 0; i < count; i++)
965          pipe_surface_reference(&dst[i], NULL);
966    }
967
968    if (ilo->cs_resource.count <= start + count) {
969       count += start;
970
971       while (count > 0 && !ilo->cs_resource.states[count - 1])
972          count--;
973
974       ilo->cs_resource.count = count;
975    }
976
977    ilo->dirty |= ILO_DIRTY_COMPUTE_RESOURCES;
978 }
979
980 static void
981 ilo_set_global_binding(struct pipe_context *pipe,
982                        unsigned start, unsigned count,
983                        struct pipe_resource **resources,
984                        uint32_t **handles)
985 {
986    struct ilo_context *ilo = ilo_context(pipe);
987    struct pipe_resource **dst = ilo->global_binding.resources;
988    unsigned i;
989
990    assert(start + count <= Elements(ilo->global_binding.resources));
991
992    dst += start;
993    if (resources) {
994       for (i = 0; i < count; i++)
995          pipe_resource_reference(&dst[i], resources[i]);
996    }
997    else {
998       for (i = 0; i < count; i++)
999          pipe_resource_reference(&dst[i], NULL);
1000    }
1001
1002    if (ilo->global_binding.count <= start + count) {
1003       count += start;
1004
1005       while (count > 0 && !ilo->global_binding.resources[count - 1])
1006          count--;
1007
1008       ilo->global_binding.count = count;
1009    }
1010
1011    ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING;
1012 }
1013
1014 /**
1015  * Initialize state-related functions.
1016  */
1017 void
1018 ilo_init_state_functions(struct ilo_context *ilo)
1019 {
1020    STATIC_ASSERT(ILO_STATE_COUNT <= 32);
1021
1022    ilo->base.create_blend_state = ilo_create_blend_state;
1023    ilo->base.bind_blend_state = ilo_bind_blend_state;
1024    ilo->base.delete_blend_state = ilo_delete_blend_state;
1025    ilo->base.create_sampler_state = ilo_create_sampler_state;
1026    ilo->base.bind_fragment_sampler_states = ilo_bind_fragment_sampler_states;
1027    ilo->base.bind_vertex_sampler_states = ilo_bind_vertex_sampler_states;
1028    ilo->base.bind_geometry_sampler_states = ilo_bind_geometry_sampler_states;
1029    ilo->base.bind_compute_sampler_states = ilo_bind_compute_sampler_states;
1030    ilo->base.delete_sampler_state = ilo_delete_sampler_state;
1031    ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
1032    ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
1033    ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
1034    ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
1035    ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
1036    ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
1037    ilo->base.create_fs_state = ilo_create_fs_state;
1038    ilo->base.bind_fs_state = ilo_bind_fs_state;
1039    ilo->base.delete_fs_state = ilo_delete_fs_state;
1040    ilo->base.create_vs_state = ilo_create_vs_state;
1041    ilo->base.bind_vs_state = ilo_bind_vs_state;
1042    ilo->base.delete_vs_state = ilo_delete_vs_state;
1043    ilo->base.create_gs_state = ilo_create_gs_state;
1044    ilo->base.bind_gs_state = ilo_bind_gs_state;
1045    ilo->base.delete_gs_state = ilo_delete_gs_state;
1046    ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
1047    ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
1048    ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
1049
1050    ilo->base.set_blend_color = ilo_set_blend_color;
1051    ilo->base.set_stencil_ref = ilo_set_stencil_ref;
1052    ilo->base.set_sample_mask = ilo_set_sample_mask;
1053    ilo->base.set_clip_state = ilo_set_clip_state;
1054    ilo->base.set_constant_buffer = ilo_set_constant_buffer;
1055    ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
1056    ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
1057    ilo->base.set_scissor_states = ilo_set_scissor_states;
1058    ilo->base.set_viewport_states = ilo_set_viewport_states;
1059    ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views;
1060    ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views;
1061    ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views;
1062    ilo->base.set_compute_sampler_views = ilo_set_compute_sampler_views;
1063    ilo->base.set_shader_resources = ilo_set_shader_resources;
1064    ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
1065    ilo->base.set_index_buffer = ilo_set_index_buffer;
1066
1067    ilo->base.create_stream_output_target = ilo_create_stream_output_target;
1068    ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
1069    ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
1070
1071    ilo->base.create_sampler_view = ilo_create_sampler_view;
1072    ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
1073
1074    ilo->base.create_surface = ilo_create_surface;
1075    ilo->base.surface_destroy = ilo_surface_destroy;
1076
1077    ilo->base.create_compute_state = ilo_create_compute_state;
1078    ilo->base.bind_compute_state = ilo_bind_compute_state;
1079    ilo->base.delete_compute_state = ilo_delete_compute_state;
1080    ilo->base.set_compute_resources = ilo_set_compute_resources;
1081    ilo->base.set_global_binding = ilo_set_global_binding;
1082 }
1083
1084 void
1085 ilo_init_states(struct ilo_context *ilo)
1086 {
1087    ilo_gpe_set_scissor_null(ilo->dev, &ilo->scissor);
1088 }
1089
1090 void
1091 ilo_cleanup_states(struct ilo_context *ilo)
1092 {
1093 }