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