• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28  /**
29   * @file
30   *
31   * Wrap the cso cache & hash mechanisms in a simplified
32   * pipe-driver-specific interface.
33   *
34   * @author Zack Rusin <zackr@vmware.com>
35   * @author Keith Whitwell <keithw@vmware.com>
36   */
37 
38 #include "pipe/p_state.h"
39 #include "util/u_draw.h"
40 #include "util/u_framebuffer.h"
41 #include "util/u_inlines.h"
42 #include "util/u_math.h"
43 #include "util/u_memory.h"
44 #include "util/u_vbuf.h"
45 #include "tgsi/tgsi_parse.h"
46 
47 #include "cso_cache/cso_context.h"
48 #include "cso_cache/cso_cache.h"
49 #include "cso_cache/cso_hash.h"
50 #include "cso_context.h"
51 
52 
53 /**
54  * Per-shader sampler information.
55  */
56 struct sampler_info
57 {
58    struct cso_sampler *cso_samplers[PIPE_MAX_SAMPLERS];
59    void *samplers[PIPE_MAX_SAMPLERS];
60 };
61 
62 
63 
64 struct cso_context {
65    struct pipe_context *pipe;
66    struct cso_cache *cache;
67    struct u_vbuf *vbuf;
68 
69    boolean has_geometry_shader;
70    boolean has_tessellation;
71    boolean has_compute_shader;
72    boolean has_streamout;
73 
74    unsigned saved_state;  /**< bitmask of CSO_BIT_x flags */
75 
76    struct pipe_sampler_view *fragment_views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
77    unsigned nr_fragment_views;
78 
79    struct pipe_sampler_view *fragment_views_saved[PIPE_MAX_SHADER_SAMPLER_VIEWS];
80    unsigned nr_fragment_views_saved;
81 
82    struct sampler_info fragment_samplers_saved;
83    struct sampler_info samplers[PIPE_SHADER_TYPES];
84 
85    /* Temporary number until cso_single_sampler_done is called.
86     * It tracks the highest sampler seen in cso_single_sampler.
87     */
88    int max_sampler_seen;
89 
90    struct pipe_vertex_buffer aux_vertex_buffer_current;
91    struct pipe_vertex_buffer aux_vertex_buffer_saved;
92    unsigned aux_vertex_buffer_index;
93 
94    struct pipe_constant_buffer aux_constbuf_current[PIPE_SHADER_TYPES];
95    struct pipe_constant_buffer aux_constbuf_saved[PIPE_SHADER_TYPES];
96 
97    struct pipe_image_view fragment_image0_current;
98    struct pipe_image_view fragment_image0_saved;
99 
100    unsigned nr_so_targets;
101    struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
102 
103    unsigned nr_so_targets_saved;
104    struct pipe_stream_output_target *so_targets_saved[PIPE_MAX_SO_BUFFERS];
105 
106    /** Current and saved state.
107     * The saved state is used as a 1-deep stack.
108     */
109    void *blend, *blend_saved;
110    void *depth_stencil, *depth_stencil_saved;
111    void *rasterizer, *rasterizer_saved;
112    void *fragment_shader, *fragment_shader_saved;
113    void *vertex_shader, *vertex_shader_saved;
114    void *geometry_shader, *geometry_shader_saved;
115    void *tessctrl_shader, *tessctrl_shader_saved;
116    void *tesseval_shader, *tesseval_shader_saved;
117    void *compute_shader;
118    void *velements, *velements_saved;
119    struct pipe_query *render_condition, *render_condition_saved;
120    uint render_condition_mode, render_condition_mode_saved;
121    boolean render_condition_cond, render_condition_cond_saved;
122 
123    struct pipe_framebuffer_state fb, fb_saved;
124    struct pipe_viewport_state vp, vp_saved;
125    struct pipe_blend_color blend_color;
126    unsigned sample_mask, sample_mask_saved;
127    unsigned min_samples, min_samples_saved;
128    struct pipe_stencil_ref stencil_ref, stencil_ref_saved;
129 };
130 
cso_get_pipe_context(struct cso_context * cso)131 struct pipe_context *cso_get_pipe_context(struct cso_context *cso)
132 {
133    return cso->pipe;
134 }
135 
delete_blend_state(struct cso_context * ctx,void * state)136 static boolean delete_blend_state(struct cso_context *ctx, void *state)
137 {
138    struct cso_blend *cso = (struct cso_blend *)state;
139 
140    if (ctx->blend == cso->data)
141       return FALSE;
142 
143    if (cso->delete_state)
144       cso->delete_state(cso->context, cso->data);
145    FREE(state);
146    return TRUE;
147 }
148 
delete_depth_stencil_state(struct cso_context * ctx,void * state)149 static boolean delete_depth_stencil_state(struct cso_context *ctx, void *state)
150 {
151    struct cso_depth_stencil_alpha *cso =
152       (struct cso_depth_stencil_alpha *)state;
153 
154    if (ctx->depth_stencil == cso->data)
155       return FALSE;
156 
157    if (cso->delete_state)
158       cso->delete_state(cso->context, cso->data);
159    FREE(state);
160 
161    return TRUE;
162 }
163 
delete_sampler_state(struct cso_context * ctx,void * state)164 static boolean delete_sampler_state(struct cso_context *ctx, void *state)
165 {
166    struct cso_sampler *cso = (struct cso_sampler *)state;
167    if (cso->delete_state)
168       cso->delete_state(cso->context, cso->data);
169    FREE(state);
170    return TRUE;
171 }
172 
delete_rasterizer_state(struct cso_context * ctx,void * state)173 static boolean delete_rasterizer_state(struct cso_context *ctx, void *state)
174 {
175    struct cso_rasterizer *cso = (struct cso_rasterizer *)state;
176 
177    if (ctx->rasterizer == cso->data)
178       return FALSE;
179    if (cso->delete_state)
180       cso->delete_state(cso->context, cso->data);
181    FREE(state);
182    return TRUE;
183 }
184 
delete_vertex_elements(struct cso_context * ctx,void * state)185 static boolean delete_vertex_elements(struct cso_context *ctx,
186                                       void *state)
187 {
188    struct cso_velements *cso = (struct cso_velements *)state;
189 
190    if (ctx->velements == cso->data)
191       return FALSE;
192 
193    if (cso->delete_state)
194       cso->delete_state(cso->context, cso->data);
195    FREE(state);
196    return TRUE;
197 }
198 
199 
delete_cso(struct cso_context * ctx,void * state,enum cso_cache_type type)200 static inline boolean delete_cso(struct cso_context *ctx,
201                                  void *state, enum cso_cache_type type)
202 {
203    switch (type) {
204    case CSO_BLEND:
205       return delete_blend_state(ctx, state);
206    case CSO_SAMPLER:
207       return delete_sampler_state(ctx, state);
208    case CSO_DEPTH_STENCIL_ALPHA:
209       return delete_depth_stencil_state(ctx, state);
210    case CSO_RASTERIZER:
211       return delete_rasterizer_state(ctx, state);
212    case CSO_VELEMENTS:
213       return delete_vertex_elements(ctx, state);
214    default:
215       assert(0);
216       FREE(state);
217    }
218    return FALSE;
219 }
220 
221 static inline void
sanitize_hash(struct cso_hash * hash,enum cso_cache_type type,int max_size,void * user_data)222 sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
223               int max_size, void *user_data)
224 {
225    struct cso_context *ctx = (struct cso_context *)user_data;
226    /* if we're approach the maximum size, remove fourth of the entries
227     * otherwise every subsequent call will go through the same */
228    int hash_size = cso_hash_size(hash);
229    int max_entries = (max_size > hash_size) ? max_size : hash_size;
230    int to_remove =  (max_size < max_entries) * max_entries/4;
231    struct cso_hash_iter iter;
232    struct cso_sampler **samplers_to_restore = NULL;
233    unsigned to_restore = 0;
234 
235    if (hash_size > max_size)
236       to_remove += hash_size - max_size;
237 
238    if (to_remove == 0)
239       return;
240 
241    if (type == CSO_SAMPLER) {
242       int i, j;
243 
244       samplers_to_restore = MALLOC(PIPE_SHADER_TYPES * PIPE_MAX_SAMPLERS *
245                                    sizeof(*samplers_to_restore));
246 
247       /* Temporarily remove currently bound sampler states from the hash
248        * table, to prevent them from being deleted
249        */
250       for (i = 0; i < PIPE_SHADER_TYPES; i++) {
251          for (j = 0; j < PIPE_MAX_SAMPLERS; j++) {
252             struct cso_sampler *sampler = ctx->samplers[i].cso_samplers[j];
253 
254             if (sampler && cso_hash_take(hash, sampler->hash_key))
255                samplers_to_restore[to_restore++] = sampler;
256          }
257       }
258    }
259 
260    iter = cso_hash_first_node(hash);
261    while (to_remove) {
262       /*remove elements until we're good */
263       /*fixme: currently we pick the nodes to remove at random*/
264       void *cso = cso_hash_iter_data(iter);
265 
266       if (!cso)
267          break;
268 
269       if (delete_cso(ctx, cso, type)) {
270          iter = cso_hash_erase(hash, iter);
271          --to_remove;
272       } else
273          iter = cso_hash_iter_next(iter);
274    }
275 
276    if (type == CSO_SAMPLER) {
277       /* Put currently bound sampler states back into the hash table */
278       while (to_restore--) {
279          struct cso_sampler *sampler = samplers_to_restore[to_restore];
280 
281          cso_hash_insert(hash, sampler->hash_key, sampler);
282       }
283 
284       FREE(samplers_to_restore);
285    }
286 }
287 
cso_init_vbuf(struct cso_context * cso,unsigned flags)288 static void cso_init_vbuf(struct cso_context *cso, unsigned flags)
289 {
290    struct u_vbuf_caps caps;
291 
292    /* Install u_vbuf if there is anything unsupported. */
293    if (u_vbuf_get_caps(cso->pipe->screen, &caps, flags)) {
294       cso->vbuf = u_vbuf_create(cso->pipe, &caps,
295                                 cso->aux_vertex_buffer_index);
296    }
297 }
298 
299 struct cso_context *
cso_create_context(struct pipe_context * pipe,unsigned u_vbuf_flags)300 cso_create_context(struct pipe_context *pipe, unsigned u_vbuf_flags)
301 {
302    struct cso_context *ctx = CALLOC_STRUCT(cso_context);
303    if (!ctx)
304       return NULL;
305 
306    ctx->cache = cso_cache_create();
307    if (ctx->cache == NULL)
308       goto out;
309    cso_cache_set_sanitize_callback(ctx->cache,
310                                    sanitize_hash,
311                                    ctx);
312 
313    ctx->pipe = pipe;
314    ctx->sample_mask = ~0;
315 
316    ctx->aux_vertex_buffer_index = 0; /* 0 for now */
317 
318    cso_init_vbuf(ctx, u_vbuf_flags);
319 
320    /* Enable for testing: */
321    if (0) cso_set_maximum_cache_size( ctx->cache, 4 );
322 
323    if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
324                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
325       ctx->has_geometry_shader = TRUE;
326    }
327    if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL,
328                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
329       ctx->has_tessellation = TRUE;
330    }
331    if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_COMPUTE,
332                                       PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
333       int supported_irs =
334          pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_COMPUTE,
335                                         PIPE_SHADER_CAP_SUPPORTED_IRS);
336       if (supported_irs & (1 << PIPE_SHADER_IR_TGSI)) {
337          ctx->has_compute_shader = TRUE;
338       }
339    }
340    if (pipe->screen->get_param(pipe->screen,
341                                PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) {
342       ctx->has_streamout = TRUE;
343    }
344 
345    ctx->max_sampler_seen = -1;
346    return ctx;
347 
348 out:
349    cso_destroy_context( ctx );
350    return NULL;
351 }
352 
353 /**
354  * Free the CSO context.
355  */
cso_destroy_context(struct cso_context * ctx)356 void cso_destroy_context( struct cso_context *ctx )
357 {
358    unsigned i;
359 
360    if (ctx->pipe) {
361       ctx->pipe->bind_blend_state( ctx->pipe, NULL );
362       ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL );
363 
364       {
365          static struct pipe_sampler_view *views[PIPE_MAX_SHADER_SAMPLER_VIEWS] = { NULL };
366          static void *zeros[PIPE_MAX_SAMPLERS] = { NULL };
367          struct pipe_screen *scr = ctx->pipe->screen;
368          enum pipe_shader_type sh;
369          for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
370             int maxsam = scr->get_shader_param(scr, sh,
371                                                PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS);
372             int maxview = scr->get_shader_param(scr, sh,
373                                                 PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS);
374             assert(maxsam <= PIPE_MAX_SAMPLERS);
375             assert(maxview <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
376             if (maxsam > 0) {
377                ctx->pipe->bind_sampler_states(ctx->pipe, sh, 0, maxsam, zeros);
378             }
379             if (maxview > 0) {
380                ctx->pipe->set_sampler_views(ctx->pipe, sh, 0, maxview, views);
381             }
382          }
383       }
384 
385       ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL );
386       ctx->pipe->bind_fs_state( ctx->pipe, NULL );
387       ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, NULL);
388       ctx->pipe->bind_vs_state( ctx->pipe, NULL );
389       ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, NULL);
390       if (ctx->has_geometry_shader) {
391          ctx->pipe->bind_gs_state(ctx->pipe, NULL);
392          ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_GEOMETRY, 0, NULL);
393       }
394       if (ctx->has_tessellation) {
395          ctx->pipe->bind_tcs_state(ctx->pipe, NULL);
396          ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_TESS_CTRL, 0, NULL);
397          ctx->pipe->bind_tes_state(ctx->pipe, NULL);
398          ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_TESS_EVAL, 0, NULL);
399       }
400       if (ctx->has_compute_shader) {
401          ctx->pipe->bind_compute_state(ctx->pipe, NULL);
402          ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_COMPUTE, 0, NULL);
403       }
404       ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
405 
406       if (ctx->has_streamout)
407          ctx->pipe->set_stream_output_targets(ctx->pipe, 0, NULL, NULL);
408    }
409 
410    for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
411       pipe_sampler_view_reference(&ctx->fragment_views[i], NULL);
412       pipe_sampler_view_reference(&ctx->fragment_views_saved[i], NULL);
413    }
414 
415    util_unreference_framebuffer_state(&ctx->fb);
416    util_unreference_framebuffer_state(&ctx->fb_saved);
417 
418    pipe_vertex_buffer_unreference(&ctx->aux_vertex_buffer_current);
419    pipe_vertex_buffer_unreference(&ctx->aux_vertex_buffer_saved);
420 
421    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
422       pipe_resource_reference(&ctx->aux_constbuf_current[i].buffer, NULL);
423       pipe_resource_reference(&ctx->aux_constbuf_saved[i].buffer, NULL);
424    }
425 
426    pipe_resource_reference(&ctx->fragment_image0_current.resource, NULL);
427    pipe_resource_reference(&ctx->fragment_image0_saved.resource, NULL);
428 
429    for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
430       pipe_so_target_reference(&ctx->so_targets[i], NULL);
431       pipe_so_target_reference(&ctx->so_targets_saved[i], NULL);
432    }
433 
434    if (ctx->cache) {
435       cso_cache_delete( ctx->cache );
436       ctx->cache = NULL;
437    }
438 
439    if (ctx->vbuf)
440       u_vbuf_destroy(ctx->vbuf);
441    FREE( ctx );
442 }
443 
444 
445 /* Those function will either find the state of the given template
446  * in the cache or they will create a new state from the given
447  * template, insert it in the cache and return it.
448  */
449 
450 /*
451  * If the driver returns 0 from the create method then they will assign
452  * the data member of the cso to be the template itself.
453  */
454 
cso_set_blend(struct cso_context * ctx,const struct pipe_blend_state * templ)455 enum pipe_error cso_set_blend(struct cso_context *ctx,
456                               const struct pipe_blend_state *templ)
457 {
458    unsigned key_size, hash_key;
459    struct cso_hash_iter iter;
460    void *handle;
461 
462    key_size = templ->independent_blend_enable ?
463       sizeof(struct pipe_blend_state) :
464       (char *)&(templ->rt[1]) - (char *)templ;
465    hash_key = cso_construct_key((void*)templ, key_size);
466    iter = cso_find_state_template(ctx->cache, hash_key, CSO_BLEND,
467                                   (void*)templ, key_size);
468 
469    if (cso_hash_iter_is_null(iter)) {
470       struct cso_blend *cso = MALLOC(sizeof(struct cso_blend));
471       if (!cso)
472          return PIPE_ERROR_OUT_OF_MEMORY;
473 
474       memset(&cso->state, 0, sizeof cso->state);
475       memcpy(&cso->state, templ, key_size);
476       cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state);
477       cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state;
478       cso->context = ctx->pipe;
479 
480       iter = cso_insert_state(ctx->cache, hash_key, CSO_BLEND, cso);
481       if (cso_hash_iter_is_null(iter)) {
482          FREE(cso);
483          return PIPE_ERROR_OUT_OF_MEMORY;
484       }
485 
486       handle = cso->data;
487    }
488    else {
489       handle = ((struct cso_blend *)cso_hash_iter_data(iter))->data;
490    }
491 
492    if (ctx->blend != handle) {
493       ctx->blend = handle;
494       ctx->pipe->bind_blend_state(ctx->pipe, handle);
495    }
496    return PIPE_OK;
497 }
498 
499 static void
cso_save_blend(struct cso_context * ctx)500 cso_save_blend(struct cso_context *ctx)
501 {
502    assert(!ctx->blend_saved);
503    ctx->blend_saved = ctx->blend;
504 }
505 
506 static void
cso_restore_blend(struct cso_context * ctx)507 cso_restore_blend(struct cso_context *ctx)
508 {
509    if (ctx->blend != ctx->blend_saved) {
510       ctx->blend = ctx->blend_saved;
511       ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend_saved);
512    }
513    ctx->blend_saved = NULL;
514 }
515 
516 
517 
518 enum pipe_error
cso_set_depth_stencil_alpha(struct cso_context * ctx,const struct pipe_depth_stencil_alpha_state * templ)519 cso_set_depth_stencil_alpha(struct cso_context *ctx,
520                             const struct pipe_depth_stencil_alpha_state *templ)
521 {
522    unsigned key_size = sizeof(struct pipe_depth_stencil_alpha_state);
523    unsigned hash_key = cso_construct_key((void*)templ, key_size);
524    struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
525                                                        hash_key,
526                                                        CSO_DEPTH_STENCIL_ALPHA,
527                                                        (void*)templ, key_size);
528    void *handle;
529 
530    if (cso_hash_iter_is_null(iter)) {
531       struct cso_depth_stencil_alpha *cso =
532          MALLOC(sizeof(struct cso_depth_stencil_alpha));
533       if (!cso)
534          return PIPE_ERROR_OUT_OF_MEMORY;
535 
536       memcpy(&cso->state, templ, sizeof(*templ));
537       cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe,
538                                                               &cso->state);
539       cso->delete_state =
540          (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state;
541       cso->context = ctx->pipe;
542 
543       iter = cso_insert_state(ctx->cache, hash_key,
544                               CSO_DEPTH_STENCIL_ALPHA, cso);
545       if (cso_hash_iter_is_null(iter)) {
546          FREE(cso);
547          return PIPE_ERROR_OUT_OF_MEMORY;
548       }
549 
550       handle = cso->data;
551    }
552    else {
553       handle = ((struct cso_depth_stencil_alpha *)
554                 cso_hash_iter_data(iter))->data;
555    }
556 
557    if (ctx->depth_stencil != handle) {
558       ctx->depth_stencil = handle;
559       ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, handle);
560    }
561    return PIPE_OK;
562 }
563 
564 static void
cso_save_depth_stencil_alpha(struct cso_context * ctx)565 cso_save_depth_stencil_alpha(struct cso_context *ctx)
566 {
567    assert(!ctx->depth_stencil_saved);
568    ctx->depth_stencil_saved = ctx->depth_stencil;
569 }
570 
571 static void
cso_restore_depth_stencil_alpha(struct cso_context * ctx)572 cso_restore_depth_stencil_alpha(struct cso_context *ctx)
573 {
574    if (ctx->depth_stencil != ctx->depth_stencil_saved) {
575       ctx->depth_stencil = ctx->depth_stencil_saved;
576       ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe,
577                                                 ctx->depth_stencil_saved);
578    }
579    ctx->depth_stencil_saved = NULL;
580 }
581 
582 
583 
cso_set_rasterizer(struct cso_context * ctx,const struct pipe_rasterizer_state * templ)584 enum pipe_error cso_set_rasterizer(struct cso_context *ctx,
585                                    const struct pipe_rasterizer_state *templ)
586 {
587    unsigned key_size = sizeof(struct pipe_rasterizer_state);
588    unsigned hash_key = cso_construct_key((void*)templ, key_size);
589    struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
590                                                        hash_key,
591                                                        CSO_RASTERIZER,
592                                                        (void*)templ, key_size);
593    void *handle = NULL;
594 
595    /* We can't have both point_quad_rasterization (sprites) and point_smooth
596     * (round AA points) enabled at the same time.
597     */
598    assert(!(templ->point_quad_rasterization && templ->point_smooth));
599 
600    if (cso_hash_iter_is_null(iter)) {
601       struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer));
602       if (!cso)
603          return PIPE_ERROR_OUT_OF_MEMORY;
604 
605       memcpy(&cso->state, templ, sizeof(*templ));
606       cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state);
607       cso->delete_state =
608          (cso_state_callback)ctx->pipe->delete_rasterizer_state;
609       cso->context = ctx->pipe;
610 
611       iter = cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso);
612       if (cso_hash_iter_is_null(iter)) {
613          FREE(cso);
614          return PIPE_ERROR_OUT_OF_MEMORY;
615       }
616 
617       handle = cso->data;
618    }
619    else {
620       handle = ((struct cso_rasterizer *)cso_hash_iter_data(iter))->data;
621    }
622 
623    if (ctx->rasterizer != handle) {
624       ctx->rasterizer = handle;
625       ctx->pipe->bind_rasterizer_state(ctx->pipe, handle);
626    }
627    return PIPE_OK;
628 }
629 
630 static void
cso_save_rasterizer(struct cso_context * ctx)631 cso_save_rasterizer(struct cso_context *ctx)
632 {
633    assert(!ctx->rasterizer_saved);
634    ctx->rasterizer_saved = ctx->rasterizer;
635 }
636 
637 static void
cso_restore_rasterizer(struct cso_context * ctx)638 cso_restore_rasterizer(struct cso_context *ctx)
639 {
640    if (ctx->rasterizer != ctx->rasterizer_saved) {
641       ctx->rasterizer = ctx->rasterizer_saved;
642       ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rasterizer_saved);
643    }
644    ctx->rasterizer_saved = NULL;
645 }
646 
647 
cso_set_fragment_shader_handle(struct cso_context * ctx,void * handle)648 void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle )
649 {
650    if (ctx->fragment_shader != handle) {
651       ctx->fragment_shader = handle;
652       ctx->pipe->bind_fs_state(ctx->pipe, handle);
653    }
654 }
655 
cso_delete_fragment_shader(struct cso_context * ctx,void * handle)656 void cso_delete_fragment_shader(struct cso_context *ctx, void *handle )
657 {
658    if (handle == ctx->fragment_shader) {
659       /* unbind before deleting */
660       ctx->pipe->bind_fs_state(ctx->pipe, NULL);
661       ctx->fragment_shader = NULL;
662    }
663    ctx->pipe->delete_fs_state(ctx->pipe, handle);
664 }
665 
666 static void
cso_save_fragment_shader(struct cso_context * ctx)667 cso_save_fragment_shader(struct cso_context *ctx)
668 {
669    assert(!ctx->fragment_shader_saved);
670    ctx->fragment_shader_saved = ctx->fragment_shader;
671 }
672 
673 static void
cso_restore_fragment_shader(struct cso_context * ctx)674 cso_restore_fragment_shader(struct cso_context *ctx)
675 {
676    if (ctx->fragment_shader_saved != ctx->fragment_shader) {
677       ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved);
678       ctx->fragment_shader = ctx->fragment_shader_saved;
679    }
680    ctx->fragment_shader_saved = NULL;
681 }
682 
683 
cso_set_vertex_shader_handle(struct cso_context * ctx,void * handle)684 void cso_set_vertex_shader_handle(struct cso_context *ctx, void *handle)
685 {
686    if (ctx->vertex_shader != handle) {
687       ctx->vertex_shader = handle;
688       ctx->pipe->bind_vs_state(ctx->pipe, handle);
689    }
690 }
691 
cso_delete_vertex_shader(struct cso_context * ctx,void * handle)692 void cso_delete_vertex_shader(struct cso_context *ctx, void *handle )
693 {
694    if (handle == ctx->vertex_shader) {
695       /* unbind before deleting */
696       ctx->pipe->bind_vs_state(ctx->pipe, NULL);
697       ctx->vertex_shader = NULL;
698    }
699    ctx->pipe->delete_vs_state(ctx->pipe, handle);
700 }
701 
702 static void
cso_save_vertex_shader(struct cso_context * ctx)703 cso_save_vertex_shader(struct cso_context *ctx)
704 {
705    assert(!ctx->vertex_shader_saved);
706    ctx->vertex_shader_saved = ctx->vertex_shader;
707 }
708 
709 static void
cso_restore_vertex_shader(struct cso_context * ctx)710 cso_restore_vertex_shader(struct cso_context *ctx)
711 {
712    if (ctx->vertex_shader_saved != ctx->vertex_shader) {
713       ctx->pipe->bind_vs_state(ctx->pipe, ctx->vertex_shader_saved);
714       ctx->vertex_shader = ctx->vertex_shader_saved;
715    }
716    ctx->vertex_shader_saved = NULL;
717 }
718 
719 
cso_set_framebuffer(struct cso_context * ctx,const struct pipe_framebuffer_state * fb)720 void cso_set_framebuffer(struct cso_context *ctx,
721                          const struct pipe_framebuffer_state *fb)
722 {
723    if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) {
724       util_copy_framebuffer_state(&ctx->fb, fb);
725       ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
726    }
727 }
728 
729 static void
cso_save_framebuffer(struct cso_context * ctx)730 cso_save_framebuffer(struct cso_context *ctx)
731 {
732    util_copy_framebuffer_state(&ctx->fb_saved, &ctx->fb);
733 }
734 
735 static void
cso_restore_framebuffer(struct cso_context * ctx)736 cso_restore_framebuffer(struct cso_context *ctx)
737 {
738    if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) {
739       util_copy_framebuffer_state(&ctx->fb, &ctx->fb_saved);
740       ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb);
741       util_unreference_framebuffer_state(&ctx->fb_saved);
742    }
743 }
744 
745 
cso_set_viewport(struct cso_context * ctx,const struct pipe_viewport_state * vp)746 void cso_set_viewport(struct cso_context *ctx,
747                       const struct pipe_viewport_state *vp)
748 {
749    if (memcmp(&ctx->vp, vp, sizeof(*vp))) {
750       ctx->vp = *vp;
751       ctx->pipe->set_viewport_states(ctx->pipe, 0, 1, vp);
752    }
753 }
754 
755 /**
756  * Setup viewport state for given width and height (position is always (0,0)).
757  * Invert the Y axis if 'invert' is true.
758  */
759 void
cso_set_viewport_dims(struct cso_context * ctx,float width,float height,boolean invert)760 cso_set_viewport_dims(struct cso_context *ctx,
761                       float width, float height, boolean invert)
762 {
763    struct pipe_viewport_state vp;
764    vp.scale[0] = width * 0.5f;
765    vp.scale[1] = height * (invert ? -0.5f : 0.5f);
766    vp.scale[2] = 0.5f;
767    vp.translate[0] = 0.5f * width;
768    vp.translate[1] = 0.5f * height;
769    vp.translate[2] = 0.5f;
770    cso_set_viewport(ctx, &vp);
771 }
772 
773 static void
cso_save_viewport(struct cso_context * ctx)774 cso_save_viewport(struct cso_context *ctx)
775 {
776    ctx->vp_saved = ctx->vp;
777 }
778 
779 
780 static void
cso_restore_viewport(struct cso_context * ctx)781 cso_restore_viewport(struct cso_context *ctx)
782 {
783    if (memcmp(&ctx->vp, &ctx->vp_saved, sizeof(ctx->vp))) {
784       ctx->vp = ctx->vp_saved;
785       ctx->pipe->set_viewport_states(ctx->pipe, 0, 1, &ctx->vp);
786    }
787 }
788 
789 
cso_set_blend_color(struct cso_context * ctx,const struct pipe_blend_color * bc)790 void cso_set_blend_color(struct cso_context *ctx,
791                          const struct pipe_blend_color *bc)
792 {
793    if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) {
794       ctx->blend_color = *bc;
795       ctx->pipe->set_blend_color(ctx->pipe, bc);
796    }
797 }
798 
cso_set_sample_mask(struct cso_context * ctx,unsigned sample_mask)799 void cso_set_sample_mask(struct cso_context *ctx, unsigned sample_mask)
800 {
801    if (ctx->sample_mask != sample_mask) {
802       ctx->sample_mask = sample_mask;
803       ctx->pipe->set_sample_mask(ctx->pipe, sample_mask);
804    }
805 }
806 
807 static void
cso_save_sample_mask(struct cso_context * ctx)808 cso_save_sample_mask(struct cso_context *ctx)
809 {
810    ctx->sample_mask_saved = ctx->sample_mask;
811 }
812 
813 static void
cso_restore_sample_mask(struct cso_context * ctx)814 cso_restore_sample_mask(struct cso_context *ctx)
815 {
816    cso_set_sample_mask(ctx, ctx->sample_mask_saved);
817 }
818 
cso_set_min_samples(struct cso_context * ctx,unsigned min_samples)819 void cso_set_min_samples(struct cso_context *ctx, unsigned min_samples)
820 {
821    if (ctx->min_samples != min_samples && ctx->pipe->set_min_samples) {
822       ctx->min_samples = min_samples;
823       ctx->pipe->set_min_samples(ctx->pipe, min_samples);
824    }
825 }
826 
827 static void
cso_save_min_samples(struct cso_context * ctx)828 cso_save_min_samples(struct cso_context *ctx)
829 {
830    ctx->min_samples_saved = ctx->min_samples;
831 }
832 
833 static void
cso_restore_min_samples(struct cso_context * ctx)834 cso_restore_min_samples(struct cso_context *ctx)
835 {
836    cso_set_min_samples(ctx, ctx->min_samples_saved);
837 }
838 
cso_set_stencil_ref(struct cso_context * ctx,const struct pipe_stencil_ref * sr)839 void cso_set_stencil_ref(struct cso_context *ctx,
840                          const struct pipe_stencil_ref *sr)
841 {
842    if (memcmp(&ctx->stencil_ref, sr, sizeof(ctx->stencil_ref))) {
843       ctx->stencil_ref = *sr;
844       ctx->pipe->set_stencil_ref(ctx->pipe, sr);
845    }
846 }
847 
848 static void
cso_save_stencil_ref(struct cso_context * ctx)849 cso_save_stencil_ref(struct cso_context *ctx)
850 {
851    ctx->stencil_ref_saved = ctx->stencil_ref;
852 }
853 
854 
855 static void
cso_restore_stencil_ref(struct cso_context * ctx)856 cso_restore_stencil_ref(struct cso_context *ctx)
857 {
858    if (memcmp(&ctx->stencil_ref, &ctx->stencil_ref_saved,
859               sizeof(ctx->stencil_ref))) {
860       ctx->stencil_ref = ctx->stencil_ref_saved;
861       ctx->pipe->set_stencil_ref(ctx->pipe, &ctx->stencil_ref);
862    }
863 }
864 
cso_set_render_condition(struct cso_context * ctx,struct pipe_query * query,boolean condition,enum pipe_render_cond_flag mode)865 void cso_set_render_condition(struct cso_context *ctx,
866                               struct pipe_query *query,
867                               boolean condition,
868                               enum pipe_render_cond_flag mode)
869 {
870    struct pipe_context *pipe = ctx->pipe;
871 
872    if (ctx->render_condition != query ||
873        ctx->render_condition_mode != mode ||
874        ctx->render_condition_cond != condition) {
875       pipe->render_condition(pipe, query, condition, mode);
876       ctx->render_condition = query;
877       ctx->render_condition_cond = condition;
878       ctx->render_condition_mode = mode;
879    }
880 }
881 
882 static void
cso_save_render_condition(struct cso_context * ctx)883 cso_save_render_condition(struct cso_context *ctx)
884 {
885    ctx->render_condition_saved = ctx->render_condition;
886    ctx->render_condition_cond_saved = ctx->render_condition_cond;
887    ctx->render_condition_mode_saved = ctx->render_condition_mode;
888 }
889 
890 static void
cso_restore_render_condition(struct cso_context * ctx)891 cso_restore_render_condition(struct cso_context *ctx)
892 {
893    cso_set_render_condition(ctx, ctx->render_condition_saved,
894                             ctx->render_condition_cond_saved,
895                             ctx->render_condition_mode_saved);
896 }
897 
cso_set_geometry_shader_handle(struct cso_context * ctx,void * handle)898 void cso_set_geometry_shader_handle(struct cso_context *ctx, void *handle)
899 {
900    assert(ctx->has_geometry_shader || !handle);
901 
902    if (ctx->has_geometry_shader && ctx->geometry_shader != handle) {
903       ctx->geometry_shader = handle;
904       ctx->pipe->bind_gs_state(ctx->pipe, handle);
905    }
906 }
907 
cso_delete_geometry_shader(struct cso_context * ctx,void * handle)908 void cso_delete_geometry_shader(struct cso_context *ctx, void *handle)
909 {
910    if (handle == ctx->geometry_shader) {
911       /* unbind before deleting */
912       ctx->pipe->bind_gs_state(ctx->pipe, NULL);
913       ctx->geometry_shader = NULL;
914    }
915    ctx->pipe->delete_gs_state(ctx->pipe, handle);
916 }
917 
918 static void
cso_save_geometry_shader(struct cso_context * ctx)919 cso_save_geometry_shader(struct cso_context *ctx)
920 {
921    if (!ctx->has_geometry_shader) {
922       return;
923    }
924 
925    assert(!ctx->geometry_shader_saved);
926    ctx->geometry_shader_saved = ctx->geometry_shader;
927 }
928 
929 static void
cso_restore_geometry_shader(struct cso_context * ctx)930 cso_restore_geometry_shader(struct cso_context *ctx)
931 {
932    if (!ctx->has_geometry_shader) {
933       return;
934    }
935 
936    if (ctx->geometry_shader_saved != ctx->geometry_shader) {
937       ctx->pipe->bind_gs_state(ctx->pipe, ctx->geometry_shader_saved);
938       ctx->geometry_shader = ctx->geometry_shader_saved;
939    }
940    ctx->geometry_shader_saved = NULL;
941 }
942 
cso_set_tessctrl_shader_handle(struct cso_context * ctx,void * handle)943 void cso_set_tessctrl_shader_handle(struct cso_context *ctx, void *handle)
944 {
945    assert(ctx->has_tessellation || !handle);
946 
947    if (ctx->has_tessellation && ctx->tessctrl_shader != handle) {
948       ctx->tessctrl_shader = handle;
949       ctx->pipe->bind_tcs_state(ctx->pipe, handle);
950    }
951 }
952 
cso_delete_tessctrl_shader(struct cso_context * ctx,void * handle)953 void cso_delete_tessctrl_shader(struct cso_context *ctx, void *handle)
954 {
955    if (handle == ctx->tessctrl_shader) {
956       /* unbind before deleting */
957       ctx->pipe->bind_tcs_state(ctx->pipe, NULL);
958       ctx->tessctrl_shader = NULL;
959    }
960    ctx->pipe->delete_tcs_state(ctx->pipe, handle);
961 }
962 
963 static void
cso_save_tessctrl_shader(struct cso_context * ctx)964 cso_save_tessctrl_shader(struct cso_context *ctx)
965 {
966    if (!ctx->has_tessellation) {
967       return;
968    }
969 
970    assert(!ctx->tessctrl_shader_saved);
971    ctx->tessctrl_shader_saved = ctx->tessctrl_shader;
972 }
973 
974 static void
cso_restore_tessctrl_shader(struct cso_context * ctx)975 cso_restore_tessctrl_shader(struct cso_context *ctx)
976 {
977    if (!ctx->has_tessellation) {
978       return;
979    }
980 
981    if (ctx->tessctrl_shader_saved != ctx->tessctrl_shader) {
982       ctx->pipe->bind_tcs_state(ctx->pipe, ctx->tessctrl_shader_saved);
983       ctx->tessctrl_shader = ctx->tessctrl_shader_saved;
984    }
985    ctx->tessctrl_shader_saved = NULL;
986 }
987 
cso_set_tesseval_shader_handle(struct cso_context * ctx,void * handle)988 void cso_set_tesseval_shader_handle(struct cso_context *ctx, void *handle)
989 {
990    assert(ctx->has_tessellation || !handle);
991 
992    if (ctx->has_tessellation && ctx->tesseval_shader != handle) {
993       ctx->tesseval_shader = handle;
994       ctx->pipe->bind_tes_state(ctx->pipe, handle);
995    }
996 }
997 
cso_delete_tesseval_shader(struct cso_context * ctx,void * handle)998 void cso_delete_tesseval_shader(struct cso_context *ctx, void *handle)
999 {
1000    if (handle == ctx->tesseval_shader) {
1001       /* unbind before deleting */
1002       ctx->pipe->bind_tes_state(ctx->pipe, NULL);
1003       ctx->tesseval_shader = NULL;
1004    }
1005    ctx->pipe->delete_tes_state(ctx->pipe, handle);
1006 }
1007 
1008 static void
cso_save_tesseval_shader(struct cso_context * ctx)1009 cso_save_tesseval_shader(struct cso_context *ctx)
1010 {
1011    if (!ctx->has_tessellation) {
1012       return;
1013    }
1014 
1015    assert(!ctx->tesseval_shader_saved);
1016    ctx->tesseval_shader_saved = ctx->tesseval_shader;
1017 }
1018 
1019 static void
cso_restore_tesseval_shader(struct cso_context * ctx)1020 cso_restore_tesseval_shader(struct cso_context *ctx)
1021 {
1022    if (!ctx->has_tessellation) {
1023       return;
1024    }
1025 
1026    if (ctx->tesseval_shader_saved != ctx->tesseval_shader) {
1027       ctx->pipe->bind_tes_state(ctx->pipe, ctx->tesseval_shader_saved);
1028       ctx->tesseval_shader = ctx->tesseval_shader_saved;
1029    }
1030    ctx->tesseval_shader_saved = NULL;
1031 }
1032 
cso_set_compute_shader_handle(struct cso_context * ctx,void * handle)1033 void cso_set_compute_shader_handle(struct cso_context *ctx, void *handle)
1034 {
1035    assert(ctx->has_compute_shader || !handle);
1036 
1037    if (ctx->has_compute_shader && ctx->compute_shader != handle) {
1038       ctx->compute_shader = handle;
1039       ctx->pipe->bind_compute_state(ctx->pipe, handle);
1040    }
1041 }
1042 
cso_delete_compute_shader(struct cso_context * ctx,void * handle)1043 void cso_delete_compute_shader(struct cso_context *ctx, void *handle)
1044 {
1045    if (handle == ctx->compute_shader) {
1046       /* unbind before deleting */
1047       ctx->pipe->bind_compute_state(ctx->pipe, NULL);
1048       ctx->compute_shader = NULL;
1049    }
1050    ctx->pipe->delete_compute_state(ctx->pipe, handle);
1051 }
1052 
1053 enum pipe_error
cso_set_vertex_elements(struct cso_context * ctx,unsigned count,const struct pipe_vertex_element * states)1054 cso_set_vertex_elements(struct cso_context *ctx,
1055                         unsigned count,
1056                         const struct pipe_vertex_element *states)
1057 {
1058    struct u_vbuf *vbuf = ctx->vbuf;
1059    unsigned key_size, hash_key;
1060    struct cso_hash_iter iter;
1061    void *handle;
1062    struct cso_velems_state velems_state;
1063 
1064    if (vbuf) {
1065       u_vbuf_set_vertex_elements(vbuf, count, states);
1066       return PIPE_OK;
1067    }
1068 
1069    /* Need to include the count into the stored state data too.
1070     * Otherwise first few count pipe_vertex_elements could be identical
1071     * even if count is different, and there's no guarantee the hash would
1072     * be different in that case neither.
1073     */
1074    key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned);
1075    velems_state.count = count;
1076    memcpy(velems_state.velems, states,
1077           sizeof(struct pipe_vertex_element) * count);
1078    hash_key = cso_construct_key((void*)&velems_state, key_size);
1079    iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS,
1080                                   (void*)&velems_state, key_size);
1081 
1082    if (cso_hash_iter_is_null(iter)) {
1083       struct cso_velements *cso = MALLOC(sizeof(struct cso_velements));
1084       if (!cso)
1085          return PIPE_ERROR_OUT_OF_MEMORY;
1086 
1087       memcpy(&cso->state, &velems_state, key_size);
1088       cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count,
1089                                                       &cso->state.velems[0]);
1090       cso->delete_state =
1091          (cso_state_callback) ctx->pipe->delete_vertex_elements_state;
1092       cso->context = ctx->pipe;
1093 
1094       iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso);
1095       if (cso_hash_iter_is_null(iter)) {
1096          FREE(cso);
1097          return PIPE_ERROR_OUT_OF_MEMORY;
1098       }
1099 
1100       handle = cso->data;
1101    }
1102    else {
1103       handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
1104    }
1105 
1106    if (ctx->velements != handle) {
1107       ctx->velements = handle;
1108       ctx->pipe->bind_vertex_elements_state(ctx->pipe, handle);
1109    }
1110    return PIPE_OK;
1111 }
1112 
1113 static void
cso_save_vertex_elements(struct cso_context * ctx)1114 cso_save_vertex_elements(struct cso_context *ctx)
1115 {
1116    struct u_vbuf *vbuf = ctx->vbuf;
1117 
1118    if (vbuf) {
1119       u_vbuf_save_vertex_elements(vbuf);
1120       return;
1121    }
1122 
1123    assert(!ctx->velements_saved);
1124    ctx->velements_saved = ctx->velements;
1125 }
1126 
1127 static void
cso_restore_vertex_elements(struct cso_context * ctx)1128 cso_restore_vertex_elements(struct cso_context *ctx)
1129 {
1130    struct u_vbuf *vbuf = ctx->vbuf;
1131 
1132    if (vbuf) {
1133       u_vbuf_restore_vertex_elements(vbuf);
1134       return;
1135    }
1136 
1137    if (ctx->velements != ctx->velements_saved) {
1138       ctx->velements = ctx->velements_saved;
1139       ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved);
1140    }
1141    ctx->velements_saved = NULL;
1142 }
1143 
1144 /* vertex buffers */
1145 
cso_set_vertex_buffers(struct cso_context * ctx,unsigned start_slot,unsigned count,const struct pipe_vertex_buffer * buffers)1146 void cso_set_vertex_buffers(struct cso_context *ctx,
1147                             unsigned start_slot, unsigned count,
1148                             const struct pipe_vertex_buffer *buffers)
1149 {
1150    struct u_vbuf *vbuf = ctx->vbuf;
1151 
1152    if (vbuf) {
1153       u_vbuf_set_vertex_buffers(vbuf, start_slot, count, buffers);
1154       return;
1155    }
1156 
1157    /* Save what's in the auxiliary slot, so that we can save and restore it
1158     * for meta ops. */
1159    if (start_slot <= ctx->aux_vertex_buffer_index &&
1160        start_slot+count > ctx->aux_vertex_buffer_index) {
1161       if (buffers) {
1162          const struct pipe_vertex_buffer *vb =
1163                buffers + (ctx->aux_vertex_buffer_index - start_slot);
1164 
1165          pipe_vertex_buffer_reference(&ctx->aux_vertex_buffer_current, vb);
1166       } else {
1167          pipe_vertex_buffer_unreference(&ctx->aux_vertex_buffer_current);
1168       }
1169    }
1170 
1171    ctx->pipe->set_vertex_buffers(ctx->pipe, start_slot, count, buffers);
1172 }
1173 
1174 static void
cso_save_aux_vertex_buffer_slot(struct cso_context * ctx)1175 cso_save_aux_vertex_buffer_slot(struct cso_context *ctx)
1176 {
1177    struct u_vbuf *vbuf = ctx->vbuf;
1178 
1179    if (vbuf) {
1180       u_vbuf_save_aux_vertex_buffer_slot(vbuf);
1181       return;
1182    }
1183 
1184    pipe_vertex_buffer_reference(&ctx->aux_vertex_buffer_saved,
1185                                 &ctx->aux_vertex_buffer_current);
1186 }
1187 
1188 static void
cso_restore_aux_vertex_buffer_slot(struct cso_context * ctx)1189 cso_restore_aux_vertex_buffer_slot(struct cso_context *ctx)
1190 {
1191    struct u_vbuf *vbuf = ctx->vbuf;
1192 
1193    if (vbuf) {
1194       u_vbuf_restore_aux_vertex_buffer_slot(vbuf);
1195       return;
1196    }
1197 
1198    cso_set_vertex_buffers(ctx, ctx->aux_vertex_buffer_index, 1,
1199                           &ctx->aux_vertex_buffer_saved);
1200    pipe_vertex_buffer_unreference(&ctx->aux_vertex_buffer_saved);
1201 }
1202 
cso_get_aux_vertex_buffer_slot(struct cso_context * ctx)1203 unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx)
1204 {
1205    return ctx->aux_vertex_buffer_index;
1206 }
1207 
1208 
1209 
1210 void
cso_single_sampler(struct cso_context * ctx,enum pipe_shader_type shader_stage,unsigned idx,const struct pipe_sampler_state * templ)1211 cso_single_sampler(struct cso_context *ctx, enum pipe_shader_type shader_stage,
1212                    unsigned idx, const struct pipe_sampler_state *templ)
1213 {
1214    if (templ) {
1215       unsigned key_size = sizeof(struct pipe_sampler_state);
1216       unsigned hash_key = cso_construct_key((void*)templ, key_size);
1217       struct cso_sampler *cso;
1218       struct cso_hash_iter iter =
1219          cso_find_state_template(ctx->cache,
1220                                  hash_key, CSO_SAMPLER,
1221                                  (void *) templ, key_size);
1222 
1223       if (cso_hash_iter_is_null(iter)) {
1224          cso = MALLOC(sizeof(struct cso_sampler));
1225          if (!cso)
1226             return;
1227 
1228          memcpy(&cso->state, templ, sizeof(*templ));
1229          cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
1230          cso->delete_state =
1231             (cso_state_callback) ctx->pipe->delete_sampler_state;
1232          cso->context = ctx->pipe;
1233          cso->hash_key = hash_key;
1234 
1235          iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso);
1236          if (cso_hash_iter_is_null(iter)) {
1237             FREE(cso);
1238             return;
1239          }
1240       }
1241       else {
1242          cso = cso_hash_iter_data(iter);
1243       }
1244 
1245       ctx->samplers[shader_stage].cso_samplers[idx] = cso;
1246       ctx->samplers[shader_stage].samplers[idx] = cso->data;
1247       ctx->max_sampler_seen = MAX2(ctx->max_sampler_seen, (int)idx);
1248    }
1249 }
1250 
1251 
1252 /**
1253  * Send staged sampler state to the driver.
1254  */
1255 void
cso_single_sampler_done(struct cso_context * ctx,enum pipe_shader_type shader_stage)1256 cso_single_sampler_done(struct cso_context *ctx,
1257                         enum pipe_shader_type shader_stage)
1258 {
1259    struct sampler_info *info = &ctx->samplers[shader_stage];
1260 
1261    if (ctx->max_sampler_seen == -1)
1262       return;
1263 
1264    ctx->pipe->bind_sampler_states(ctx->pipe, shader_stage, 0,
1265                                   ctx->max_sampler_seen + 1,
1266                                   info->samplers);
1267    ctx->max_sampler_seen = -1;
1268 }
1269 
1270 
1271 /*
1272  * If the function encouters any errors it will return the
1273  * last one. Done to always try to set as many samplers
1274  * as possible.
1275  */
1276 void
cso_set_samplers(struct cso_context * ctx,enum pipe_shader_type shader_stage,unsigned nr,const struct pipe_sampler_state ** templates)1277 cso_set_samplers(struct cso_context *ctx,
1278                  enum pipe_shader_type shader_stage,
1279                  unsigned nr,
1280                  const struct pipe_sampler_state **templates)
1281 {
1282    for (unsigned i = 0; i < nr; i++)
1283       cso_single_sampler(ctx, shader_stage, i, templates[i]);
1284 
1285    cso_single_sampler_done(ctx, shader_stage);
1286 }
1287 
1288 static void
cso_save_fragment_samplers(struct cso_context * ctx)1289 cso_save_fragment_samplers(struct cso_context *ctx)
1290 {
1291    struct sampler_info *info = &ctx->samplers[PIPE_SHADER_FRAGMENT];
1292    struct sampler_info *saved = &ctx->fragment_samplers_saved;
1293 
1294    memcpy(saved->cso_samplers, info->cso_samplers,
1295           sizeof(info->cso_samplers));
1296    memcpy(saved->samplers, info->samplers, sizeof(info->samplers));
1297 }
1298 
1299 
1300 static void
cso_restore_fragment_samplers(struct cso_context * ctx)1301 cso_restore_fragment_samplers(struct cso_context *ctx)
1302 {
1303    struct sampler_info *info = &ctx->samplers[PIPE_SHADER_FRAGMENT];
1304    struct sampler_info *saved = &ctx->fragment_samplers_saved;
1305 
1306    memcpy(info->cso_samplers, saved->cso_samplers,
1307           sizeof(info->cso_samplers));
1308    memcpy(info->samplers, saved->samplers, sizeof(info->samplers));
1309 
1310    for (int i = PIPE_MAX_SAMPLERS - 1; i >= 0; i--) {
1311       if (info->samplers[i]) {
1312          ctx->max_sampler_seen = i;
1313          break;
1314       }
1315    }
1316 
1317    cso_single_sampler_done(ctx, PIPE_SHADER_FRAGMENT);
1318 }
1319 
1320 
1321 void
cso_set_sampler_views(struct cso_context * ctx,enum pipe_shader_type shader_stage,unsigned count,struct pipe_sampler_view ** views)1322 cso_set_sampler_views(struct cso_context *ctx,
1323                       enum pipe_shader_type shader_stage,
1324                       unsigned count,
1325                       struct pipe_sampler_view **views)
1326 {
1327    if (shader_stage == PIPE_SHADER_FRAGMENT) {
1328       unsigned i;
1329       boolean any_change = FALSE;
1330 
1331       /* reference new views */
1332       for (i = 0; i < count; i++) {
1333          any_change |= ctx->fragment_views[i] != views[i];
1334          pipe_sampler_view_reference(&ctx->fragment_views[i], views[i]);
1335       }
1336       /* unref extra old views, if any */
1337       for (; i < ctx->nr_fragment_views; i++) {
1338          any_change |= ctx->fragment_views[i] != NULL;
1339          pipe_sampler_view_reference(&ctx->fragment_views[i], NULL);
1340       }
1341 
1342       /* bind the new sampler views */
1343       if (any_change) {
1344          ctx->pipe->set_sampler_views(ctx->pipe, shader_stage, 0,
1345                                       MAX2(ctx->nr_fragment_views, count),
1346                                       ctx->fragment_views);
1347       }
1348 
1349       ctx->nr_fragment_views = count;
1350    }
1351    else
1352       ctx->pipe->set_sampler_views(ctx->pipe, shader_stage, 0, count, views);
1353 }
1354 
1355 
1356 static void
cso_save_fragment_sampler_views(struct cso_context * ctx)1357 cso_save_fragment_sampler_views(struct cso_context *ctx)
1358 {
1359    unsigned i;
1360 
1361    ctx->nr_fragment_views_saved = ctx->nr_fragment_views;
1362 
1363    for (i = 0; i < ctx->nr_fragment_views; i++) {
1364       assert(!ctx->fragment_views_saved[i]);
1365       pipe_sampler_view_reference(&ctx->fragment_views_saved[i],
1366                                   ctx->fragment_views[i]);
1367    }
1368 }
1369 
1370 
1371 static void
cso_restore_fragment_sampler_views(struct cso_context * ctx)1372 cso_restore_fragment_sampler_views(struct cso_context *ctx)
1373 {
1374    unsigned i, nr_saved = ctx->nr_fragment_views_saved;
1375    unsigned num;
1376 
1377    for (i = 0; i < nr_saved; i++) {
1378       pipe_sampler_view_reference(&ctx->fragment_views[i], NULL);
1379       /* move the reference from one pointer to another */
1380       ctx->fragment_views[i] = ctx->fragment_views_saved[i];
1381       ctx->fragment_views_saved[i] = NULL;
1382    }
1383    for (; i < ctx->nr_fragment_views; i++) {
1384       pipe_sampler_view_reference(&ctx->fragment_views[i], NULL);
1385    }
1386 
1387    num = MAX2(ctx->nr_fragment_views, nr_saved);
1388 
1389    /* bind the old/saved sampler views */
1390    ctx->pipe->set_sampler_views(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, num,
1391                                 ctx->fragment_views);
1392 
1393    ctx->nr_fragment_views = nr_saved;
1394    ctx->nr_fragment_views_saved = 0;
1395 }
1396 
1397 
1398 void
cso_set_shader_images(struct cso_context * ctx,enum pipe_shader_type shader_stage,unsigned start,unsigned count,struct pipe_image_view * images)1399 cso_set_shader_images(struct cso_context *ctx,
1400                       enum pipe_shader_type shader_stage,
1401                       unsigned start, unsigned count,
1402                       struct pipe_image_view *images)
1403 {
1404    if (shader_stage == PIPE_SHADER_FRAGMENT && start == 0 && count >= 1) {
1405       util_copy_image_view(&ctx->fragment_image0_current, &images[0]);
1406    }
1407 
1408    ctx->pipe->set_shader_images(ctx->pipe, shader_stage, start, count, images);
1409 }
1410 
1411 
1412 static void
cso_save_fragment_image0(struct cso_context * ctx)1413 cso_save_fragment_image0(struct cso_context *ctx)
1414 {
1415    util_copy_image_view(&ctx->fragment_image0_saved,
1416                         &ctx->fragment_image0_current);
1417 }
1418 
1419 
1420 static void
cso_restore_fragment_image0(struct cso_context * ctx)1421 cso_restore_fragment_image0(struct cso_context *ctx)
1422 {
1423    cso_set_shader_images(ctx, PIPE_SHADER_FRAGMENT, 0, 1,
1424                          &ctx->fragment_image0_saved);
1425 }
1426 
1427 
1428 void
cso_set_stream_outputs(struct cso_context * ctx,unsigned num_targets,struct pipe_stream_output_target ** targets,const unsigned * offsets)1429 cso_set_stream_outputs(struct cso_context *ctx,
1430                        unsigned num_targets,
1431                        struct pipe_stream_output_target **targets,
1432                        const unsigned *offsets)
1433 {
1434    struct pipe_context *pipe = ctx->pipe;
1435    uint i;
1436 
1437    if (!ctx->has_streamout) {
1438       assert(num_targets == 0);
1439       return;
1440    }
1441 
1442    if (ctx->nr_so_targets == 0 && num_targets == 0) {
1443       /* Nothing to do. */
1444       return;
1445    }
1446 
1447    /* reference new targets */
1448    for (i = 0; i < num_targets; i++) {
1449       pipe_so_target_reference(&ctx->so_targets[i], targets[i]);
1450    }
1451    /* unref extra old targets, if any */
1452    for (; i < ctx->nr_so_targets; i++) {
1453       pipe_so_target_reference(&ctx->so_targets[i], NULL);
1454    }
1455 
1456    pipe->set_stream_output_targets(pipe, num_targets, targets,
1457                                    offsets);
1458    ctx->nr_so_targets = num_targets;
1459 }
1460 
1461 static void
cso_save_stream_outputs(struct cso_context * ctx)1462 cso_save_stream_outputs(struct cso_context *ctx)
1463 {
1464    uint i;
1465 
1466    if (!ctx->has_streamout) {
1467       return;
1468    }
1469 
1470    ctx->nr_so_targets_saved = ctx->nr_so_targets;
1471 
1472    for (i = 0; i < ctx->nr_so_targets; i++) {
1473       assert(!ctx->so_targets_saved[i]);
1474       pipe_so_target_reference(&ctx->so_targets_saved[i], ctx->so_targets[i]);
1475    }
1476 }
1477 
1478 static void
cso_restore_stream_outputs(struct cso_context * ctx)1479 cso_restore_stream_outputs(struct cso_context *ctx)
1480 {
1481    struct pipe_context *pipe = ctx->pipe;
1482    uint i;
1483    unsigned offset[PIPE_MAX_SO_BUFFERS];
1484 
1485    if (!ctx->has_streamout) {
1486       return;
1487    }
1488 
1489    if (ctx->nr_so_targets == 0 && ctx->nr_so_targets_saved == 0) {
1490       /* Nothing to do. */
1491       return;
1492    }
1493 
1494    assert(ctx->nr_so_targets_saved <= PIPE_MAX_SO_BUFFERS);
1495    for (i = 0; i < ctx->nr_so_targets_saved; i++) {
1496       pipe_so_target_reference(&ctx->so_targets[i], NULL);
1497       /* move the reference from one pointer to another */
1498       ctx->so_targets[i] = ctx->so_targets_saved[i];
1499       ctx->so_targets_saved[i] = NULL;
1500       /* -1 means append */
1501       offset[i] = (unsigned)-1;
1502    }
1503    for (; i < ctx->nr_so_targets; i++) {
1504       pipe_so_target_reference(&ctx->so_targets[i], NULL);
1505    }
1506 
1507    pipe->set_stream_output_targets(pipe, ctx->nr_so_targets_saved,
1508                                    ctx->so_targets, offset);
1509 
1510    ctx->nr_so_targets = ctx->nr_so_targets_saved;
1511    ctx->nr_so_targets_saved = 0;
1512 }
1513 
1514 /* constant buffers */
1515 
1516 void
cso_set_constant_buffer(struct cso_context * cso,enum pipe_shader_type shader_stage,unsigned index,struct pipe_constant_buffer * cb)1517 cso_set_constant_buffer(struct cso_context *cso,
1518                         enum pipe_shader_type shader_stage,
1519                         unsigned index, struct pipe_constant_buffer *cb)
1520 {
1521    struct pipe_context *pipe = cso->pipe;
1522 
1523    pipe->set_constant_buffer(pipe, shader_stage, index, cb);
1524 
1525    if (index == 0) {
1526       util_copy_constant_buffer(&cso->aux_constbuf_current[shader_stage], cb);
1527    }
1528 }
1529 
1530 void
cso_set_constant_buffer_resource(struct cso_context * cso,enum pipe_shader_type shader_stage,unsigned index,struct pipe_resource * buffer)1531 cso_set_constant_buffer_resource(struct cso_context *cso,
1532                                  enum pipe_shader_type shader_stage,
1533                                  unsigned index,
1534                                  struct pipe_resource *buffer)
1535 {
1536    if (buffer) {
1537       struct pipe_constant_buffer cb;
1538       cb.buffer = buffer;
1539       cb.buffer_offset = 0;
1540       cb.buffer_size = buffer->width0;
1541       cb.user_buffer = NULL;
1542       cso_set_constant_buffer(cso, shader_stage, index, &cb);
1543    } else {
1544       cso_set_constant_buffer(cso, shader_stage, index, NULL);
1545    }
1546 }
1547 
1548 void
cso_save_constant_buffer_slot0(struct cso_context * cso,enum pipe_shader_type shader_stage)1549 cso_save_constant_buffer_slot0(struct cso_context *cso,
1550                                enum pipe_shader_type shader_stage)
1551 {
1552    util_copy_constant_buffer(&cso->aux_constbuf_saved[shader_stage],
1553                              &cso->aux_constbuf_current[shader_stage]);
1554 }
1555 
1556 void
cso_restore_constant_buffer_slot0(struct cso_context * cso,enum pipe_shader_type shader_stage)1557 cso_restore_constant_buffer_slot0(struct cso_context *cso,
1558                                   enum pipe_shader_type shader_stage)
1559 {
1560    cso_set_constant_buffer(cso, shader_stage, 0,
1561                            &cso->aux_constbuf_saved[shader_stage]);
1562    pipe_resource_reference(&cso->aux_constbuf_saved[shader_stage].buffer,
1563                            NULL);
1564 }
1565 
1566 
1567 /**
1568  * Save all the CSO state items specified by the state_mask bitmask
1569  * of CSO_BIT_x flags.
1570  */
1571 void
cso_save_state(struct cso_context * cso,unsigned state_mask)1572 cso_save_state(struct cso_context *cso, unsigned state_mask)
1573 {
1574    assert(cso->saved_state == 0);
1575 
1576    cso->saved_state = state_mask;
1577 
1578    if (state_mask & CSO_BIT_AUX_VERTEX_BUFFER_SLOT)
1579       cso_save_aux_vertex_buffer_slot(cso);
1580    if (state_mask & CSO_BIT_BLEND)
1581       cso_save_blend(cso);
1582    if (state_mask & CSO_BIT_DEPTH_STENCIL_ALPHA)
1583       cso_save_depth_stencil_alpha(cso);
1584    if (state_mask & CSO_BIT_FRAGMENT_SAMPLERS)
1585       cso_save_fragment_samplers(cso);
1586    if (state_mask & CSO_BIT_FRAGMENT_SAMPLER_VIEWS)
1587       cso_save_fragment_sampler_views(cso);
1588    if (state_mask & CSO_BIT_FRAGMENT_SHADER)
1589       cso_save_fragment_shader(cso);
1590    if (state_mask & CSO_BIT_FRAMEBUFFER)
1591       cso_save_framebuffer(cso);
1592    if (state_mask & CSO_BIT_GEOMETRY_SHADER)
1593       cso_save_geometry_shader(cso);
1594    if (state_mask & CSO_BIT_MIN_SAMPLES)
1595       cso_save_min_samples(cso);
1596    if (state_mask & CSO_BIT_RASTERIZER)
1597       cso_save_rasterizer(cso);
1598    if (state_mask & CSO_BIT_RENDER_CONDITION)
1599       cso_save_render_condition(cso);
1600    if (state_mask & CSO_BIT_SAMPLE_MASK)
1601       cso_save_sample_mask(cso);
1602    if (state_mask & CSO_BIT_STENCIL_REF)
1603       cso_save_stencil_ref(cso);
1604    if (state_mask & CSO_BIT_STREAM_OUTPUTS)
1605       cso_save_stream_outputs(cso);
1606    if (state_mask & CSO_BIT_TESSCTRL_SHADER)
1607       cso_save_tessctrl_shader(cso);
1608    if (state_mask & CSO_BIT_TESSEVAL_SHADER)
1609       cso_save_tesseval_shader(cso);
1610    if (state_mask & CSO_BIT_VERTEX_ELEMENTS)
1611       cso_save_vertex_elements(cso);
1612    if (state_mask & CSO_BIT_VERTEX_SHADER)
1613       cso_save_vertex_shader(cso);
1614    if (state_mask & CSO_BIT_VIEWPORT)
1615       cso_save_viewport(cso);
1616    if (state_mask & CSO_BIT_PAUSE_QUERIES)
1617       cso->pipe->set_active_query_state(cso->pipe, false);
1618    if (state_mask & CSO_BIT_FRAGMENT_IMAGE0)
1619       cso_save_fragment_image0(cso);
1620 }
1621 
1622 
1623 /**
1624  * Restore the state which was saved by cso_save_state().
1625  */
1626 void
cso_restore_state(struct cso_context * cso)1627 cso_restore_state(struct cso_context *cso)
1628 {
1629    unsigned state_mask = cso->saved_state;
1630 
1631    assert(state_mask);
1632 
1633    if (state_mask & CSO_BIT_AUX_VERTEX_BUFFER_SLOT)
1634       cso_restore_aux_vertex_buffer_slot(cso);
1635    if (state_mask & CSO_BIT_BLEND)
1636       cso_restore_blend(cso);
1637    if (state_mask & CSO_BIT_DEPTH_STENCIL_ALPHA)
1638       cso_restore_depth_stencil_alpha(cso);
1639    if (state_mask & CSO_BIT_FRAGMENT_SAMPLERS)
1640       cso_restore_fragment_samplers(cso);
1641    if (state_mask & CSO_BIT_FRAGMENT_SAMPLER_VIEWS)
1642       cso_restore_fragment_sampler_views(cso);
1643    if (state_mask & CSO_BIT_FRAGMENT_SHADER)
1644       cso_restore_fragment_shader(cso);
1645    if (state_mask & CSO_BIT_FRAMEBUFFER)
1646       cso_restore_framebuffer(cso);
1647    if (state_mask & CSO_BIT_GEOMETRY_SHADER)
1648       cso_restore_geometry_shader(cso);
1649    if (state_mask & CSO_BIT_MIN_SAMPLES)
1650       cso_restore_min_samples(cso);
1651    if (state_mask & CSO_BIT_RASTERIZER)
1652       cso_restore_rasterizer(cso);
1653    if (state_mask & CSO_BIT_RENDER_CONDITION)
1654       cso_restore_render_condition(cso);
1655    if (state_mask & CSO_BIT_SAMPLE_MASK)
1656       cso_restore_sample_mask(cso);
1657    if (state_mask & CSO_BIT_STENCIL_REF)
1658       cso_restore_stencil_ref(cso);
1659    if (state_mask & CSO_BIT_STREAM_OUTPUTS)
1660       cso_restore_stream_outputs(cso);
1661    if (state_mask & CSO_BIT_TESSCTRL_SHADER)
1662       cso_restore_tessctrl_shader(cso);
1663    if (state_mask & CSO_BIT_TESSEVAL_SHADER)
1664       cso_restore_tesseval_shader(cso);
1665    if (state_mask & CSO_BIT_VERTEX_ELEMENTS)
1666       cso_restore_vertex_elements(cso);
1667    if (state_mask & CSO_BIT_VERTEX_SHADER)
1668       cso_restore_vertex_shader(cso);
1669    if (state_mask & CSO_BIT_VIEWPORT)
1670       cso_restore_viewport(cso);
1671    if (state_mask & CSO_BIT_PAUSE_QUERIES)
1672       cso->pipe->set_active_query_state(cso->pipe, true);
1673    if (state_mask & CSO_BIT_FRAGMENT_IMAGE0)
1674       cso_restore_fragment_image0(cso);
1675 
1676    cso->saved_state = 0;
1677 }
1678 
1679 
1680 
1681 /* drawing */
1682 
1683 void
cso_draw_vbo(struct cso_context * cso,const struct pipe_draw_info * info)1684 cso_draw_vbo(struct cso_context *cso,
1685              const struct pipe_draw_info *info)
1686 {
1687    struct u_vbuf *vbuf = cso->vbuf;
1688 
1689    if (vbuf) {
1690       u_vbuf_draw_vbo(vbuf, info);
1691    } else {
1692       struct pipe_context *pipe = cso->pipe;
1693       pipe->draw_vbo(pipe, info);
1694    }
1695 }
1696 
1697 void
cso_draw_arrays(struct cso_context * cso,uint mode,uint start,uint count)1698 cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count)
1699 {
1700    struct pipe_draw_info info;
1701 
1702    util_draw_init_info(&info);
1703 
1704    info.mode = mode;
1705    info.start = start;
1706    info.count = count;
1707    info.min_index = start;
1708    info.max_index = start + count - 1;
1709 
1710    cso_draw_vbo(cso, &info);
1711 }
1712 
1713 void
cso_draw_arrays_instanced(struct cso_context * cso,uint mode,uint start,uint count,uint start_instance,uint instance_count)1714 cso_draw_arrays_instanced(struct cso_context *cso, uint mode,
1715                           uint start, uint count,
1716                           uint start_instance, uint instance_count)
1717 {
1718    struct pipe_draw_info info;
1719 
1720    util_draw_init_info(&info);
1721 
1722    info.mode = mode;
1723    info.start = start;
1724    info.count = count;
1725    info.min_index = start;
1726    info.max_index = start + count - 1;
1727    info.start_instance = start_instance;
1728    info.instance_count = instance_count;
1729 
1730    cso_draw_vbo(cso, &info);
1731 }
1732