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