Home | History | Annotate | Download | only in cso_cache
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
      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 TUNGSTEN GRAPHICS 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 <zack (at) tungstengraphics.com>
     35   * @author Keith Whitwell <keith (at) tungstengraphics.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  * Info related to samplers and sampler views.
     55  * We have one of these for fragment samplers and another for vertex samplers.
     56  */
     57 struct sampler_info
     58 {
     59    struct {
     60       void *samplers[PIPE_MAX_SAMPLERS];
     61       unsigned nr_samplers;
     62    } hw;
     63 
     64    void *samplers[PIPE_MAX_SAMPLERS];
     65    unsigned nr_samplers;
     66 
     67    void *samplers_saved[PIPE_MAX_SAMPLERS];
     68    unsigned nr_samplers_saved;
     69 
     70    struct pipe_sampler_view *views[PIPE_MAX_SAMPLERS];
     71    unsigned nr_views;
     72 
     73    struct pipe_sampler_view *views_saved[PIPE_MAX_SAMPLERS];
     74    unsigned nr_views_saved;
     75 };
     76 
     77 
     78 
     79 struct cso_context {
     80    struct pipe_context *pipe;
     81    struct cso_cache *cache;
     82    struct u_vbuf *vbuf;
     83 
     84    boolean has_geometry_shader;
     85    boolean has_streamout;
     86 
     87    struct sampler_info samplers[PIPE_SHADER_TYPES];
     88 
     89    uint nr_vertex_buffers;
     90    struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
     91 
     92    uint nr_vertex_buffers_saved;
     93    struct pipe_vertex_buffer vertex_buffers_saved[PIPE_MAX_ATTRIBS];
     94 
     95    unsigned nr_so_targets;
     96    struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
     97 
     98    unsigned nr_so_targets_saved;
     99    struct pipe_stream_output_target *so_targets_saved[PIPE_MAX_SO_BUFFERS];
    100 
    101    /** Current and saved state.
    102     * The saved state is used as a 1-deep stack.
    103     */
    104    void *blend, *blend_saved;
    105    void *depth_stencil, *depth_stencil_saved;
    106    void *rasterizer, *rasterizer_saved;
    107    void *fragment_shader, *fragment_shader_saved;
    108    void *vertex_shader, *vertex_shader_saved;
    109    void *geometry_shader, *geometry_shader_saved;
    110    void *velements, *velements_saved;
    111 
    112    struct pipe_clip_state clip;
    113    struct pipe_clip_state clip_saved;
    114 
    115    struct pipe_framebuffer_state fb, fb_saved;
    116    struct pipe_viewport_state vp, vp_saved;
    117    struct pipe_blend_color blend_color;
    118    unsigned sample_mask, sample_mask_saved;
    119    struct pipe_stencil_ref stencil_ref, stencil_ref_saved;
    120 };
    121 
    122 
    123 static boolean delete_blend_state(struct cso_context *ctx, void *state)
    124 {
    125    struct cso_blend *cso = (struct cso_blend *)state;
    126 
    127    if (ctx->blend == cso->data)
    128       return FALSE;
    129 
    130    if (cso->delete_state)
    131       cso->delete_state(cso->context, cso->data);
    132    FREE(state);
    133    return TRUE;
    134 }
    135 
    136 static boolean delete_depth_stencil_state(struct cso_context *ctx, void *state)
    137 {
    138    struct cso_depth_stencil_alpha *cso =
    139       (struct cso_depth_stencil_alpha *)state;
    140 
    141    if (ctx->depth_stencil == cso->data)
    142       return FALSE;
    143 
    144    if (cso->delete_state)
    145       cso->delete_state(cso->context, cso->data);
    146    FREE(state);
    147 
    148    return TRUE;
    149 }
    150 
    151 static boolean delete_sampler_state(struct cso_context *ctx, void *state)
    152 {
    153    struct cso_sampler *cso = (struct cso_sampler *)state;
    154    if (cso->delete_state)
    155       cso->delete_state(cso->context, cso->data);
    156    FREE(state);
    157    return TRUE;
    158 }
    159 
    160 static boolean delete_rasterizer_state(struct cso_context *ctx, void *state)
    161 {
    162    struct cso_rasterizer *cso = (struct cso_rasterizer *)state;
    163 
    164    if (ctx->rasterizer == cso->data)
    165       return FALSE;
    166    if (cso->delete_state)
    167       cso->delete_state(cso->context, cso->data);
    168    FREE(state);
    169    return TRUE;
    170 }
    171 
    172 static boolean delete_vertex_elements(struct cso_context *ctx,
    173                                       void *state)
    174 {
    175    struct cso_velements *cso = (struct cso_velements *)state;
    176 
    177    if (ctx->velements == cso->data)
    178       return FALSE;
    179 
    180    if (cso->delete_state)
    181       cso->delete_state(cso->context, cso->data);
    182    FREE(state);
    183    return TRUE;
    184 }
    185 
    186 
    187 static INLINE boolean delete_cso(struct cso_context *ctx,
    188                                  void *state, enum cso_cache_type type)
    189 {
    190    switch (type) {
    191    case CSO_BLEND:
    192       return delete_blend_state(ctx, state);
    193    case CSO_SAMPLER:
    194       return delete_sampler_state(ctx, state);
    195    case CSO_DEPTH_STENCIL_ALPHA:
    196       return delete_depth_stencil_state(ctx, state);
    197    case CSO_RASTERIZER:
    198       return delete_rasterizer_state(ctx, state);
    199    case CSO_VELEMENTS:
    200       return delete_vertex_elements(ctx, state);
    201    default:
    202       assert(0);
    203       FREE(state);
    204    }
    205    return FALSE;
    206 }
    207 
    208 static INLINE void
    209 sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
    210               int max_size, void *user_data)
    211 {
    212    struct cso_context *ctx = (struct cso_context *)user_data;
    213    /* if we're approach the maximum size, remove fourth of the entries
    214     * otherwise every subsequent call will go through the same */
    215    int hash_size = cso_hash_size(hash);
    216    int max_entries = (max_size > hash_size) ? max_size : hash_size;
    217    int to_remove =  (max_size < max_entries) * max_entries/4;
    218    struct cso_hash_iter iter = cso_hash_first_node(hash);
    219    if (hash_size > max_size)
    220       to_remove += hash_size - max_size;
    221    while (to_remove) {
    222       /*remove elements until we're good */
    223       /*fixme: currently we pick the nodes to remove at random*/
    224       void *cso = cso_hash_iter_data(iter);
    225       if (delete_cso(ctx, cso, type)) {
    226          iter = cso_hash_erase(hash, iter);
    227          --to_remove;
    228       } else
    229          iter = cso_hash_iter_next(iter);
    230    }
    231 }
    232 
    233 static void cso_init_vbuf(struct cso_context *cso)
    234 {
    235    struct u_vbuf_caps caps;
    236 
    237    u_vbuf_get_caps(cso->pipe->screen, &caps);
    238 
    239    /* Install u_vbuf if there is anything unsupported. */
    240    if (!caps.buffer_offset_unaligned ||
    241        !caps.buffer_stride_unaligned ||
    242        !caps.velem_src_offset_unaligned ||
    243        !caps.format_fixed32 ||
    244        !caps.format_float16 ||
    245        !caps.format_float64 ||
    246        !caps.format_norm32 ||
    247        !caps.format_scaled32 ||
    248        !caps.user_vertex_buffers) {
    249       cso->vbuf = u_vbuf_create(cso->pipe, &caps);
    250    }
    251 }
    252 
    253 struct cso_context *cso_create_context( struct pipe_context *pipe )
    254 {
    255    struct cso_context *ctx = CALLOC_STRUCT(cso_context);
    256    if (ctx == NULL)
    257       goto out;
    258 
    259    ctx->cache = cso_cache_create();
    260    if (ctx->cache == NULL)
    261       goto out;
    262    cso_cache_set_sanitize_callback(ctx->cache,
    263                                    sanitize_hash,
    264                                    ctx);
    265 
    266    ctx->pipe = pipe;
    267    ctx->sample_mask_saved = ~0;
    268 
    269    cso_init_vbuf(ctx);
    270 
    271    /* Enable for testing: */
    272    if (0) cso_set_maximum_cache_size( ctx->cache, 4 );
    273 
    274    if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
    275                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
    276       ctx->has_geometry_shader = TRUE;
    277    }
    278    if (pipe->screen->get_param(pipe->screen,
    279                                PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) {
    280       ctx->has_streamout = TRUE;
    281    }
    282 
    283    return ctx;
    284 
    285 out:
    286    cso_destroy_context( ctx );
    287    return NULL;
    288 }
    289 
    290 /**
    291  * Prior to context destruction, this function unbinds all state objects.
    292  */
    293 void cso_release_all( struct cso_context *ctx )
    294 {
    295    unsigned i, shader;
    296 
    297    if (ctx->pipe) {
    298       ctx->pipe->bind_blend_state( ctx->pipe, NULL );
    299       ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL );
    300       ctx->pipe->bind_fragment_sampler_states( ctx->pipe, 0, NULL );
    301       if (ctx->pipe->bind_vertex_sampler_states)
    302          ctx->pipe->bind_vertex_sampler_states(ctx->pipe, 0, NULL);
    303       ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL );
    304       ctx->pipe->bind_fs_state( ctx->pipe, NULL );
    305       ctx->pipe->bind_vs_state( ctx->pipe, NULL );
    306       ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
    307       ctx->pipe->set_fragment_sampler_views(ctx->pipe, 0, NULL);
    308       if (ctx->pipe->set_vertex_sampler_views)
    309          ctx->pipe->set_vertex_sampler_views(ctx->pipe, 0, NULL);
    310       if (ctx->pipe->set_stream_output_targets)
    311          ctx->pipe->set_stream_output_targets(ctx->pipe, 0, NULL, 0);
    312    }
    313 
    314    /* free fragment samplers, views */
    315    for (shader = 0; shader < Elements(ctx->samplers); shader++) {
    316       struct sampler_info *info = &ctx->samplers[shader];
    317       for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
    318          pipe_sampler_view_reference(&info->views[i], NULL);
    319          pipe_sampler_view_reference(&info->views_saved[i], NULL);
    320       }
    321    }
    322 
    323    util_unreference_framebuffer_state(&ctx->fb);
    324    util_unreference_framebuffer_state(&ctx->fb_saved);
    325 
    326    util_copy_vertex_buffers(ctx->vertex_buffers,
    327                             &ctx->nr_vertex_buffers,
    328                             NULL, 0);
    329    util_copy_vertex_buffers(ctx->vertex_buffers_saved,
    330                             &ctx->nr_vertex_buffers_saved,
    331                             NULL, 0);
    332 
    333    for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
    334       pipe_so_target_reference(&ctx->so_targets[i], NULL);
    335       pipe_so_target_reference(&ctx->so_targets_saved[i], NULL);
    336    }
    337 
    338    if (ctx->cache) {
    339       cso_cache_delete( ctx->cache );
    340       ctx->cache = NULL;
    341    }
    342 }
    343 
    344 
    345 /**
    346  * Free the CSO context.  NOTE: the state tracker should have previously called
    347  * cso_release_all().
    348  */
    349 void cso_destroy_context( struct cso_context *ctx )
    350 {
    351    if (ctx) {
    352       if (ctx->vbuf)
    353          u_vbuf_destroy(ctx->vbuf);
    354       FREE( ctx );
    355    }
    356 }
    357 
    358 
    359 /* Those function will either find the state of the given template
    360  * in the cache or they will create a new state from the given
    361  * template, insert it in the cache and return it.
    362  */
    363 
    364 /*
    365  * If the driver returns 0 from the create method then they will assign
    366  * the data member of the cso to be the template itself.
    367  */
    368 
    369 enum pipe_error cso_set_blend(struct cso_context *ctx,
    370                               const struct pipe_blend_state *templ)
    371 {
    372    unsigned key_size, hash_key;
    373    struct cso_hash_iter iter;
    374    void *handle;
    375 
    376    key_size = templ->independent_blend_enable ?
    377       sizeof(struct pipe_blend_state) :
    378       (char *)&(templ->rt[1]) - (char *)templ;
    379    hash_key = cso_construct_key((void*)templ, key_size);
    380    iter = cso_find_state_template(ctx->cache, hash_key, CSO_BLEND,
    381                                   (void*)templ, key_size);
    382 
    383    if (cso_hash_iter_is_null(iter)) {
    384       struct cso_blend *cso = MALLOC(sizeof(struct cso_blend));
    385       if (!cso)
    386          return PIPE_ERROR_OUT_OF_MEMORY;
    387 
    388       memset(&cso->state, 0, sizeof cso->state);
    389       memcpy(&cso->state, templ, key_size);
    390       cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state);
    391       cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state;
    392       cso->context = ctx->pipe;
    393 
    394       iter = cso_insert_state(ctx->cache, hash_key, CSO_BLEND, cso);
    395       if (cso_hash_iter_is_null(iter)) {
    396          FREE(cso);
    397          return PIPE_ERROR_OUT_OF_MEMORY;
    398       }
    399 
    400       handle = cso->data;
    401    }
    402    else {
    403       handle = ((struct cso_blend *)cso_hash_iter_data(iter))->data;
    404    }
    405 
    406    if (ctx->blend != handle) {
    407       ctx->blend = handle;
    408       ctx->pipe->bind_blend_state(ctx->pipe, handle);
    409    }
    410    return PIPE_OK;
    411 }
    412 
    413 void cso_save_blend(struct cso_context *ctx)
    414 {
    415    assert(!ctx->blend_saved);
    416    ctx->blend_saved = ctx->blend;
    417 }
    418 
    419 void cso_restore_blend(struct cso_context *ctx)
    420 {
    421    if (ctx->blend != ctx->blend_saved) {
    422       ctx->blend = ctx->blend_saved;
    423       ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend_saved);
    424    }
    425    ctx->blend_saved = NULL;
    426 }
    427 
    428 
    429 
    430 enum pipe_error
    431 cso_set_depth_stencil_alpha(struct cso_context *ctx,
    432                             const struct pipe_depth_stencil_alpha_state *templ)
    433 {
    434    unsigned key_size = sizeof(struct pipe_depth_stencil_alpha_state);
    435    unsigned hash_key = cso_construct_key((void*)templ, key_size);
    436    struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
    437                                                        hash_key,
    438                                                        CSO_DEPTH_STENCIL_ALPHA,
    439                                                        (void*)templ, key_size);
    440    void *handle;
    441 
    442    if (cso_hash_iter_is_null(iter)) {
    443       struct cso_depth_stencil_alpha *cso =
    444          MALLOC(sizeof(struct cso_depth_stencil_alpha));
    445       if (!cso)
    446          return PIPE_ERROR_OUT_OF_MEMORY;
    447 
    448       memcpy(&cso->state, templ, sizeof(*templ));
    449       cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe,
    450                                                               &cso->state);
    451       cso->delete_state =
    452          (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state;
    453       cso->context = ctx->pipe;
    454 
    455       iter = cso_insert_state(ctx->cache, hash_key,
    456                               CSO_DEPTH_STENCIL_ALPHA, cso);
    457       if (cso_hash_iter_is_null(iter)) {
    458          FREE(cso);
    459          return PIPE_ERROR_OUT_OF_MEMORY;
    460       }
    461 
    462       handle = cso->data;
    463    }
    464    else {
    465       handle = ((struct cso_depth_stencil_alpha *)
    466                 cso_hash_iter_data(iter))->data;
    467    }
    468 
    469    if (ctx->depth_stencil != handle) {
    470       ctx->depth_stencil = handle;
    471       ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, handle);
    472    }
    473    return PIPE_OK;
    474 }
    475 
    476 void cso_save_depth_stencil_alpha(struct cso_context *ctx)
    477 {
    478    assert(!ctx->depth_stencil_saved);
    479    ctx->depth_stencil_saved = ctx->depth_stencil;
    480 }
    481 
    482 void cso_restore_depth_stencil_alpha(struct cso_context *ctx)
    483 {
    484    if (ctx->depth_stencil != ctx->depth_stencil_saved) {
    485       ctx->depth_stencil = ctx->depth_stencil_saved;
    486       ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe,
    487                                                 ctx->depth_stencil_saved);
    488    }
    489    ctx->depth_stencil_saved = NULL;
    490 }
    491 
    492 
    493 
    494 enum pipe_error cso_set_rasterizer(struct cso_context *ctx,
    495                                    const struct pipe_rasterizer_state *templ)
    496 {
    497    unsigned key_size = sizeof(struct pipe_rasterizer_state);
    498    unsigned hash_key = cso_construct_key((void*)templ, key_size);
    499    struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
    500                                                        hash_key,
    501                                                        CSO_RASTERIZER,
    502                                                        (void*)templ, key_size);
    503    void *handle = NULL;
    504 
    505    if (cso_hash_iter_is_null(iter)) {
    506       struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer));
    507       if (!cso)
    508          return PIPE_ERROR_OUT_OF_MEMORY;
    509 
    510       memcpy(&cso->state, templ, sizeof(*templ));
    511       cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state);
    512       cso->delete_state =
    513          (cso_state_callback)ctx->pipe->delete_rasterizer_state;
    514       cso->context = ctx->pipe;
    515 
    516       iter = cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso);
    517       if (cso_hash_iter_is_null(iter)) {
    518          FREE(cso);
    519          return PIPE_ERROR_OUT_OF_MEMORY;
    520       }
    521 
    522       handle = cso->data;
    523    }
    524    else {
    525       handle = ((struct cso_rasterizer *)cso_hash_iter_data(iter))->data;
    526    }
    527 
    528    if (ctx->rasterizer != handle) {
    529       ctx->rasterizer = handle;
    530       ctx->pipe->bind_rasterizer_state(ctx->pipe, handle);
    531    }
    532    return PIPE_OK;
    533 }
    534 
    535 void cso_save_rasterizer(struct cso_context *ctx)
    536 {
    537    assert(!ctx->rasterizer_saved);
    538    ctx->rasterizer_saved = ctx->rasterizer;
    539 }
    540 
    541 void cso_restore_rasterizer(struct cso_context *ctx)
    542 {
    543    if (ctx->rasterizer != ctx->rasterizer_saved) {
    544       ctx->rasterizer = ctx->rasterizer_saved;
    545       ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rasterizer_saved);
    546    }
    547    ctx->rasterizer_saved = NULL;
    548 }
    549 
    550 
    551 
    552 enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx,
    553                                                void *handle )
    554 {
    555    if (ctx->fragment_shader != handle) {
    556       ctx->fragment_shader = handle;
    557       ctx->pipe->bind_fs_state(ctx->pipe, handle);
    558    }
    559    return PIPE_OK;
    560 }
    561 
    562 void cso_delete_fragment_shader(struct cso_context *ctx, void *handle )
    563 {
    564    if (handle == ctx->fragment_shader) {
    565       /* unbind before deleting */
    566       ctx->pipe->bind_fs_state(ctx->pipe, NULL);
    567       ctx->fragment_shader = NULL;
    568    }
    569    ctx->pipe->delete_fs_state(ctx->pipe, handle);
    570 }
    571 
    572 void cso_save_fragment_shader(struct cso_context *ctx)
    573 {
    574    assert(!ctx->fragment_shader_saved);
    575    ctx->fragment_shader_saved = ctx->fragment_shader;
    576 }
    577 
    578 void cso_restore_fragment_shader(struct cso_context *ctx)
    579 {
    580    if (ctx->fragment_shader_saved != ctx->fragment_shader) {
    581       ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved);
    582       ctx->fragment_shader = ctx->fragment_shader_saved;
    583    }
    584    ctx->fragment_shader_saved = NULL;
    585 }
    586 
    587 
    588 enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx,
    589                                              void *handle )
    590 {
    591    if (ctx->vertex_shader != handle) {
    592       ctx->vertex_shader = handle;
    593       ctx->pipe->bind_vs_state(ctx->pipe, handle);
    594    }
    595    return PIPE_OK;
    596 }
    597 
    598 void cso_delete_vertex_shader(struct cso_context *ctx, void *handle )
    599 {
    600    if (handle == ctx->vertex_shader) {
    601       /* unbind before deleting */
    602       ctx->pipe->bind_vs_state(ctx->pipe, NULL);
    603       ctx->vertex_shader = NULL;
    604    }
    605    ctx->pipe->delete_vs_state(ctx->pipe, handle);
    606 }
    607 
    608 void cso_save_vertex_shader(struct cso_context *ctx)
    609 {
    610    assert(!ctx->vertex_shader_saved);
    611    ctx->vertex_shader_saved = ctx->vertex_shader;
    612 }
    613 
    614 void cso_restore_vertex_shader(struct cso_context *ctx)
    615 {
    616    if (ctx->vertex_shader_saved != ctx->vertex_shader) {
    617       ctx->pipe->bind_vs_state(ctx->pipe, ctx->vertex_shader_saved);
    618       ctx->vertex_shader = ctx->vertex_shader_saved;
    619    }
    620    ctx->vertex_shader_saved = NULL;
    621 }
    622 
    623 
    624 enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
    625                                     const struct pipe_framebuffer_state *fb)
    626 {
    627    if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) {
    628       util_copy_framebuffer_state(&ctx->fb, fb);
    629       ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
    630    }
    631    return PIPE_OK;
    632 }
    633 
    634 void cso_save_framebuffer(struct cso_context *ctx)
    635 {
    636    util_copy_framebuffer_state(&ctx->fb_saved, &ctx->fb);
    637 }
    638 
    639 void cso_restore_framebuffer(struct cso_context *ctx)
    640 {
    641    if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) {
    642       util_copy_framebuffer_state(&ctx->fb, &ctx->fb_saved);
    643       ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb);
    644       util_unreference_framebuffer_state(&ctx->fb_saved);
    645    }
    646 }
    647 
    648 
    649 enum pipe_error cso_set_viewport(struct cso_context *ctx,
    650                                  const struct pipe_viewport_state *vp)
    651 {
    652    if (memcmp(&ctx->vp, vp, sizeof(*vp))) {
    653       ctx->vp = *vp;
    654       ctx->pipe->set_viewport_state(ctx->pipe, vp);
    655    }
    656    return PIPE_OK;
    657 }
    658 
    659 void cso_save_viewport(struct cso_context *ctx)
    660 {
    661    ctx->vp_saved = ctx->vp;
    662 }
    663 
    664 
    665 void cso_restore_viewport(struct cso_context *ctx)
    666 {
    667    if (memcmp(&ctx->vp, &ctx->vp_saved, sizeof(ctx->vp))) {
    668       ctx->vp = ctx->vp_saved;
    669       ctx->pipe->set_viewport_state(ctx->pipe, &ctx->vp);
    670    }
    671 }
    672 
    673 
    674 enum pipe_error cso_set_blend_color(struct cso_context *ctx,
    675                                     const struct pipe_blend_color *bc)
    676 {
    677    if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) {
    678       ctx->blend_color = *bc;
    679       ctx->pipe->set_blend_color(ctx->pipe, bc);
    680    }
    681    return PIPE_OK;
    682 }
    683 
    684 enum pipe_error cso_set_sample_mask(struct cso_context *ctx,
    685                                     unsigned sample_mask)
    686 {
    687    if (ctx->sample_mask != sample_mask) {
    688       ctx->sample_mask = sample_mask;
    689       ctx->pipe->set_sample_mask(ctx->pipe, sample_mask);
    690    }
    691    return PIPE_OK;
    692 }
    693 
    694 void cso_save_sample_mask(struct cso_context *ctx)
    695 {
    696    ctx->sample_mask_saved = ctx->sample_mask;
    697 }
    698 
    699 void cso_restore_sample_mask(struct cso_context *ctx)
    700 {
    701    cso_set_sample_mask(ctx, ctx->sample_mask_saved);
    702 }
    703 
    704 enum pipe_error cso_set_stencil_ref(struct cso_context *ctx,
    705                                     const struct pipe_stencil_ref *sr)
    706 {
    707    if (memcmp(&ctx->stencil_ref, sr, sizeof(ctx->stencil_ref))) {
    708       ctx->stencil_ref = *sr;
    709       ctx->pipe->set_stencil_ref(ctx->pipe, sr);
    710    }
    711    return PIPE_OK;
    712 }
    713 
    714 void cso_save_stencil_ref(struct cso_context *ctx)
    715 {
    716    ctx->stencil_ref_saved = ctx->stencil_ref;
    717 }
    718 
    719 
    720 void cso_restore_stencil_ref(struct cso_context *ctx)
    721 {
    722    if (memcmp(&ctx->stencil_ref, &ctx->stencil_ref_saved,
    723               sizeof(ctx->stencil_ref))) {
    724       ctx->stencil_ref = ctx->stencil_ref_saved;
    725       ctx->pipe->set_stencil_ref(ctx->pipe, &ctx->stencil_ref);
    726    }
    727 }
    728 
    729 enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
    730                                                void *handle)
    731 {
    732    assert(ctx->has_geometry_shader || !handle);
    733 
    734    if (ctx->has_geometry_shader && ctx->geometry_shader != handle) {
    735       ctx->geometry_shader = handle;
    736       ctx->pipe->bind_gs_state(ctx->pipe, handle);
    737    }
    738    return PIPE_OK;
    739 }
    740 
    741 void cso_delete_geometry_shader(struct cso_context *ctx, void *handle)
    742 {
    743     if (handle == ctx->geometry_shader) {
    744       /* unbind before deleting */
    745       ctx->pipe->bind_gs_state(ctx->pipe, NULL);
    746       ctx->geometry_shader = NULL;
    747    }
    748    ctx->pipe->delete_gs_state(ctx->pipe, handle);
    749 }
    750 
    751 void cso_save_geometry_shader(struct cso_context *ctx)
    752 {
    753    if (!ctx->has_geometry_shader) {
    754       return;
    755    }
    756 
    757    assert(!ctx->geometry_shader_saved);
    758    ctx->geometry_shader_saved = ctx->geometry_shader;
    759 }
    760 
    761 void cso_restore_geometry_shader(struct cso_context *ctx)
    762 {
    763    if (!ctx->has_geometry_shader) {
    764       return;
    765    }
    766 
    767    if (ctx->geometry_shader_saved != ctx->geometry_shader) {
    768       ctx->pipe->bind_gs_state(ctx->pipe, ctx->geometry_shader_saved);
    769       ctx->geometry_shader = ctx->geometry_shader_saved;
    770    }
    771    ctx->geometry_shader_saved = NULL;
    772 }
    773 
    774 /* clip state */
    775 
    776 static INLINE void
    777 clip_state_cpy(struct pipe_clip_state *dst,
    778                const struct pipe_clip_state *src)
    779 {
    780    memcpy(dst->ucp, src->ucp, sizeof(dst->ucp));
    781 }
    782 
    783 static INLINE int
    784 clip_state_cmp(const struct pipe_clip_state *a,
    785                const struct pipe_clip_state *b)
    786 {
    787    return memcmp(a->ucp, b->ucp, sizeof(a->ucp));
    788 }
    789 
    790 void
    791 cso_set_clip(struct cso_context *ctx,
    792              const struct pipe_clip_state *clip)
    793 {
    794    if (clip_state_cmp(&ctx->clip, clip)) {
    795       clip_state_cpy(&ctx->clip, clip);
    796       ctx->pipe->set_clip_state(ctx->pipe, clip);
    797    }
    798 }
    799 
    800 void
    801 cso_save_clip(struct cso_context *ctx)
    802 {
    803    clip_state_cpy(&ctx->clip_saved, &ctx->clip);
    804 }
    805 
    806 void
    807 cso_restore_clip(struct cso_context *ctx)
    808 {
    809    if (clip_state_cmp(&ctx->clip, &ctx->clip_saved)) {
    810       clip_state_cpy(&ctx->clip, &ctx->clip_saved);
    811       ctx->pipe->set_clip_state(ctx->pipe, &ctx->clip_saved);
    812    }
    813 }
    814 
    815 enum pipe_error
    816 cso_set_vertex_elements(struct cso_context *ctx,
    817                         unsigned count,
    818                         const struct pipe_vertex_element *states)
    819 {
    820    struct u_vbuf *vbuf = ctx->vbuf;
    821    unsigned key_size, hash_key;
    822    struct cso_hash_iter iter;
    823    void *handle;
    824    struct cso_velems_state velems_state;
    825 
    826    if (vbuf) {
    827       u_vbuf_set_vertex_elements(vbuf, count, states);
    828       return PIPE_OK;
    829    }
    830 
    831    /* Need to include the count into the stored state data too.
    832     * Otherwise first few count pipe_vertex_elements could be identical
    833     * even if count is different, and there's no guarantee the hash would
    834     * be different in that case neither.
    835     */
    836    key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned);
    837    velems_state.count = count;
    838    memcpy(velems_state.velems, states,
    839           sizeof(struct pipe_vertex_element) * count);
    840    hash_key = cso_construct_key((void*)&velems_state, key_size);
    841    iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS,
    842                                   (void*)&velems_state, key_size);
    843 
    844    if (cso_hash_iter_is_null(iter)) {
    845       struct cso_velements *cso = MALLOC(sizeof(struct cso_velements));
    846       if (!cso)
    847          return PIPE_ERROR_OUT_OF_MEMORY;
    848 
    849       memcpy(&cso->state, &velems_state, key_size);
    850       cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count,
    851                                                       &cso->state.velems[0]);
    852       cso->delete_state =
    853          (cso_state_callback) ctx->pipe->delete_vertex_elements_state;
    854       cso->context = ctx->pipe;
    855 
    856       iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso);
    857       if (cso_hash_iter_is_null(iter)) {
    858          FREE(cso);
    859          return PIPE_ERROR_OUT_OF_MEMORY;
    860       }
    861 
    862       handle = cso->data;
    863    }
    864    else {
    865       handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
    866    }
    867 
    868    if (ctx->velements != handle) {
    869       ctx->velements = handle;
    870       ctx->pipe->bind_vertex_elements_state(ctx->pipe, handle);
    871    }
    872    return PIPE_OK;
    873 }
    874 
    875 void cso_save_vertex_elements(struct cso_context *ctx)
    876 {
    877    struct u_vbuf *vbuf = ctx->vbuf;
    878 
    879    if (vbuf) {
    880       u_vbuf_save_vertex_elements(vbuf);
    881       return;
    882    }
    883 
    884    assert(!ctx->velements_saved);
    885    ctx->velements_saved = ctx->velements;
    886 }
    887 
    888 void cso_restore_vertex_elements(struct cso_context *ctx)
    889 {
    890    struct u_vbuf *vbuf = ctx->vbuf;
    891 
    892    if (vbuf) {
    893       u_vbuf_restore_vertex_elements(vbuf);
    894       return;
    895    }
    896 
    897    if (ctx->velements != ctx->velements_saved) {
    898       ctx->velements = ctx->velements_saved;
    899       ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved);
    900    }
    901    ctx->velements_saved = NULL;
    902 }
    903 
    904 /* vertex buffers */
    905 
    906 void cso_set_vertex_buffers(struct cso_context *ctx,
    907                             unsigned count,
    908                             const struct pipe_vertex_buffer *buffers)
    909 {
    910    struct u_vbuf *vbuf = ctx->vbuf;
    911 
    912    if (vbuf) {
    913       u_vbuf_set_vertex_buffers(vbuf, count, buffers);
    914       return;
    915    }
    916 
    917    if (count != ctx->nr_vertex_buffers ||
    918        memcmp(buffers, ctx->vertex_buffers,
    919               sizeof(struct pipe_vertex_buffer) * count) != 0) {
    920       util_copy_vertex_buffers(ctx->vertex_buffers, &ctx->nr_vertex_buffers,
    921                                buffers, count);
    922       ctx->pipe->set_vertex_buffers(ctx->pipe, count, buffers);
    923    }
    924 }
    925 
    926 void cso_save_vertex_buffers(struct cso_context *ctx)
    927 {
    928    struct u_vbuf *vbuf = ctx->vbuf;
    929 
    930    if (vbuf) {
    931       u_vbuf_save_vertex_buffers(vbuf);
    932       return;
    933    }
    934 
    935    util_copy_vertex_buffers(ctx->vertex_buffers_saved,
    936                             &ctx->nr_vertex_buffers_saved,
    937                             ctx->vertex_buffers,
    938                             ctx->nr_vertex_buffers);
    939 }
    940 
    941 void cso_restore_vertex_buffers(struct cso_context *ctx)
    942 {
    943    unsigned i;
    944    struct u_vbuf *vbuf = ctx->vbuf;
    945 
    946    if (vbuf) {
    947       u_vbuf_restore_vertex_buffers(vbuf);
    948       return;
    949    }
    950 
    951    util_copy_vertex_buffers(ctx->vertex_buffers,
    952                             &ctx->nr_vertex_buffers,
    953                             ctx->vertex_buffers_saved,
    954                             ctx->nr_vertex_buffers_saved);
    955 
    956    for (i = 0; i < ctx->nr_vertex_buffers_saved; i++) {
    957       pipe_resource_reference(&ctx->vertex_buffers_saved[i].buffer, NULL);
    958    }
    959    ctx->nr_vertex_buffers_saved = 0;
    960 
    961    ctx->pipe->set_vertex_buffers(ctx->pipe, ctx->nr_vertex_buffers,
    962                                  ctx->vertex_buffers);
    963 }
    964 
    965 
    966 /**************** fragment/vertex sampler view state *************************/
    967 
    968 static enum pipe_error
    969 single_sampler(struct cso_context *ctx,
    970                struct sampler_info *info,
    971                unsigned idx,
    972                const struct pipe_sampler_state *templ)
    973 {
    974    void *handle = NULL;
    975 
    976    if (templ != NULL) {
    977       unsigned key_size = sizeof(struct pipe_sampler_state);
    978       unsigned hash_key = cso_construct_key((void*)templ, key_size);
    979       struct cso_hash_iter iter =
    980          cso_find_state_template(ctx->cache,
    981                                  hash_key, CSO_SAMPLER,
    982                                  (void *) templ, key_size);
    983 
    984       if (cso_hash_iter_is_null(iter)) {
    985          struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler));
    986          if (!cso)
    987             return PIPE_ERROR_OUT_OF_MEMORY;
    988 
    989          memcpy(&cso->state, templ, sizeof(*templ));
    990          cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
    991          cso->delete_state =
    992             (cso_state_callback) ctx->pipe->delete_sampler_state;
    993          cso->context = ctx->pipe;
    994 
    995          iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso);
    996          if (cso_hash_iter_is_null(iter)) {
    997             FREE(cso);
    998             return PIPE_ERROR_OUT_OF_MEMORY;
    999          }
   1000 
   1001          handle = cso->data;
   1002       }
   1003       else {
   1004          handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data;
   1005       }
   1006    }
   1007 
   1008    info->samplers[idx] = handle;
   1009 
   1010    return PIPE_OK;
   1011 }
   1012 
   1013 enum pipe_error
   1014 cso_single_sampler(struct cso_context *ctx,
   1015                    unsigned shader_stage,
   1016                    unsigned idx,
   1017                    const struct pipe_sampler_state *templ)
   1018 {
   1019    return single_sampler(ctx, &ctx->samplers[shader_stage], idx, templ);
   1020 }
   1021 
   1022 
   1023 
   1024 static void
   1025 single_sampler_done(struct cso_context *ctx, unsigned shader_stage)
   1026 {
   1027    struct sampler_info *info = &ctx->samplers[shader_stage];
   1028    unsigned i;
   1029 
   1030    /* find highest non-null sampler */
   1031    for (i = PIPE_MAX_SAMPLERS; i > 0; i--) {
   1032       if (info->samplers[i - 1] != NULL)
   1033          break;
   1034    }
   1035 
   1036    info->nr_samplers = i;
   1037 
   1038    if (info->hw.nr_samplers != info->nr_samplers ||
   1039        memcmp(info->hw.samplers,
   1040               info->samplers,
   1041               info->nr_samplers * sizeof(void *)) != 0)
   1042    {
   1043       memcpy(info->hw.samplers,
   1044              info->samplers,
   1045              info->nr_samplers * sizeof(void *));
   1046       info->hw.nr_samplers = info->nr_samplers;
   1047 
   1048       switch (shader_stage) {
   1049       case PIPE_SHADER_FRAGMENT:
   1050          ctx->pipe->bind_fragment_sampler_states(ctx->pipe,
   1051                                                  info->nr_samplers,
   1052                                                  info->samplers);
   1053          break;
   1054       case PIPE_SHADER_VERTEX:
   1055          ctx->pipe->bind_vertex_sampler_states(ctx->pipe,
   1056                                                info->nr_samplers,
   1057                                                info->samplers);
   1058          break;
   1059       case PIPE_SHADER_GEOMETRY:
   1060          ctx->pipe->bind_geometry_sampler_states(ctx->pipe,
   1061                                                info->nr_samplers,
   1062                                                info->samplers);
   1063          break;
   1064       default:
   1065          assert(!"bad shader type in single_sampler_done()");
   1066       }
   1067    }
   1068 }
   1069 
   1070 void
   1071 cso_single_sampler_done(struct cso_context *ctx, unsigned shader_stage)
   1072 {
   1073    single_sampler_done(ctx, shader_stage);
   1074 }
   1075 
   1076 
   1077 /*
   1078  * If the function encouters any errors it will return the
   1079  * last one. Done to always try to set as many samplers
   1080  * as possible.
   1081  */
   1082 enum pipe_error
   1083 cso_set_samplers(struct cso_context *ctx,
   1084                  unsigned shader_stage,
   1085                  unsigned nr,
   1086                  const struct pipe_sampler_state **templates)
   1087 {
   1088    struct sampler_info *info = &ctx->samplers[shader_stage];
   1089    unsigned i;
   1090    enum pipe_error temp, error = PIPE_OK;
   1091 
   1092    /* TODO: fastpath
   1093     */
   1094 
   1095    for (i = 0; i < nr; i++) {
   1096       temp = single_sampler(ctx, info, i, templates[i]);
   1097       if (temp != PIPE_OK)
   1098          error = temp;
   1099    }
   1100 
   1101    for ( ; i < info->nr_samplers; i++) {
   1102       temp = single_sampler(ctx, info, i, NULL);
   1103       if (temp != PIPE_OK)
   1104          error = temp;
   1105    }
   1106 
   1107    single_sampler_done(ctx, shader_stage);
   1108 
   1109    return error;
   1110 }
   1111 
   1112 void
   1113 cso_save_samplers(struct cso_context *ctx, unsigned shader_stage)
   1114 {
   1115    struct sampler_info *info = &ctx->samplers[shader_stage];
   1116    info->nr_samplers_saved = info->nr_samplers;
   1117    memcpy(info->samplers_saved, info->samplers, sizeof(info->samplers));
   1118 }
   1119 
   1120 
   1121 void
   1122 cso_restore_samplers(struct cso_context *ctx, unsigned shader_stage)
   1123 {
   1124    struct sampler_info *info = &ctx->samplers[shader_stage];
   1125    info->nr_samplers = info->nr_samplers_saved;
   1126    memcpy(info->samplers, info->samplers_saved, sizeof(info->samplers));
   1127    single_sampler_done(ctx, shader_stage);
   1128 }
   1129 
   1130 
   1131 void
   1132 cso_set_sampler_views(struct cso_context *ctx,
   1133                       unsigned shader_stage,
   1134                       unsigned count,
   1135                       struct pipe_sampler_view **views)
   1136 {
   1137    struct sampler_info *info = &ctx->samplers[shader_stage];
   1138    unsigned i;
   1139 
   1140    /* reference new views */
   1141    for (i = 0; i < count; i++) {
   1142       pipe_sampler_view_reference(&info->views[i], views[i]);
   1143    }
   1144    /* unref extra old views, if any */
   1145    for (; i < info->nr_views; i++) {
   1146       pipe_sampler_view_reference(&info->views[i], NULL);
   1147    }
   1148 
   1149    info->nr_views = count;
   1150 
   1151    /* bind the new sampler views */
   1152    switch (shader_stage) {
   1153    case PIPE_SHADER_FRAGMENT:
   1154       ctx->pipe->set_fragment_sampler_views(ctx->pipe, count, info->views);
   1155       break;
   1156    case PIPE_SHADER_VERTEX:
   1157       ctx->pipe->set_vertex_sampler_views(ctx->pipe, count, info->views);
   1158       break;
   1159    case PIPE_SHADER_GEOMETRY:
   1160       ctx->pipe->set_geometry_sampler_views(ctx->pipe, count, info->views);
   1161       break;
   1162    default:
   1163       assert(!"bad shader type in cso_set_sampler_views()");
   1164    }
   1165 }
   1166 
   1167 
   1168 void
   1169 cso_save_sampler_views(struct cso_context *ctx, unsigned shader_stage)
   1170 {
   1171    struct sampler_info *info = &ctx->samplers[shader_stage];
   1172    unsigned i;
   1173 
   1174    info->nr_views_saved = info->nr_views;
   1175 
   1176    for (i = 0; i < info->nr_views; i++) {
   1177       assert(!info->views_saved[i]);
   1178       pipe_sampler_view_reference(&info->views_saved[i], info->views[i]);
   1179    }
   1180 }
   1181 
   1182 
   1183 void
   1184 cso_restore_sampler_views(struct cso_context *ctx, unsigned shader_stage)
   1185 {
   1186    struct sampler_info *info = &ctx->samplers[shader_stage];
   1187    unsigned i, nr_saved = info->nr_views_saved;
   1188 
   1189    for (i = 0; i < nr_saved; i++) {
   1190       pipe_sampler_view_reference(&info->views[i], NULL);
   1191       /* move the reference from one pointer to another */
   1192       info->views[i] = info->views_saved[i];
   1193       info->views_saved[i] = NULL;
   1194    }
   1195    for (; i < info->nr_views; i++) {
   1196       pipe_sampler_view_reference(&info->views[i], NULL);
   1197    }
   1198 
   1199    /* bind the old/saved sampler views */
   1200    switch (shader_stage) {
   1201    case PIPE_SHADER_FRAGMENT:
   1202       ctx->pipe->set_fragment_sampler_views(ctx->pipe, nr_saved, info->views);
   1203       break;
   1204    case PIPE_SHADER_VERTEX:
   1205       ctx->pipe->set_vertex_sampler_views(ctx->pipe, nr_saved, info->views);
   1206       break;
   1207    case PIPE_SHADER_GEOMETRY:
   1208       ctx->pipe->set_geometry_sampler_views(ctx->pipe, nr_saved, info->views);
   1209       break;
   1210    default:
   1211       assert(!"bad shader type in cso_restore_sampler_views()");
   1212    }
   1213 
   1214    info->nr_views = nr_saved;
   1215    info->nr_views_saved = 0;
   1216 }
   1217 
   1218 
   1219 void
   1220 cso_set_stream_outputs(struct cso_context *ctx,
   1221                        unsigned num_targets,
   1222                        struct pipe_stream_output_target **targets,
   1223                        unsigned append_bitmask)
   1224 {
   1225    struct pipe_context *pipe = ctx->pipe;
   1226    uint i;
   1227 
   1228    if (!ctx->has_streamout) {
   1229       assert(num_targets == 0);
   1230       return;
   1231    }
   1232 
   1233    if (ctx->nr_so_targets == 0 && num_targets == 0) {
   1234       /* Nothing to do. */
   1235       return;
   1236    }
   1237 
   1238    /* reference new targets */
   1239    for (i = 0; i < num_targets; i++) {
   1240       pipe_so_target_reference(&ctx->so_targets[i], targets[i]);
   1241    }
   1242    /* unref extra old targets, if any */
   1243    for (; i < ctx->nr_so_targets; i++) {
   1244       pipe_so_target_reference(&ctx->so_targets[i], NULL);
   1245    }
   1246 
   1247    pipe->set_stream_output_targets(pipe, num_targets, targets,
   1248                                    append_bitmask);
   1249    ctx->nr_so_targets = num_targets;
   1250 }
   1251 
   1252 void
   1253 cso_save_stream_outputs(struct cso_context *ctx)
   1254 {
   1255    uint i;
   1256 
   1257    if (!ctx->has_streamout) {
   1258       return;
   1259    }
   1260 
   1261    ctx->nr_so_targets_saved = ctx->nr_so_targets;
   1262 
   1263    for (i = 0; i < ctx->nr_so_targets; i++) {
   1264       assert(!ctx->so_targets_saved[i]);
   1265       pipe_so_target_reference(&ctx->so_targets_saved[i], ctx->so_targets[i]);
   1266    }
   1267 }
   1268 
   1269 void
   1270 cso_restore_stream_outputs(struct cso_context *ctx)
   1271 {
   1272    struct pipe_context *pipe = ctx->pipe;
   1273    uint i;
   1274 
   1275    if (!ctx->has_streamout) {
   1276       return;
   1277    }
   1278 
   1279    if (ctx->nr_so_targets == 0 && ctx->nr_so_targets_saved == 0) {
   1280       /* Nothing to do. */
   1281       return;
   1282    }
   1283 
   1284    for (i = 0; i < ctx->nr_so_targets_saved; i++) {
   1285       pipe_so_target_reference(&ctx->so_targets[i], NULL);
   1286       /* move the reference from one pointer to another */
   1287       ctx->so_targets[i] = ctx->so_targets_saved[i];
   1288       ctx->so_targets_saved[i] = NULL;
   1289    }
   1290    for (; i < ctx->nr_so_targets; i++) {
   1291       pipe_so_target_reference(&ctx->so_targets[i], NULL);
   1292    }
   1293 
   1294    /* ~0 means append */
   1295    pipe->set_stream_output_targets(pipe, ctx->nr_so_targets_saved,
   1296                                    ctx->so_targets, ~0);
   1297 
   1298    ctx->nr_so_targets = ctx->nr_so_targets_saved;
   1299    ctx->nr_so_targets_saved = 0;
   1300 }
   1301 
   1302 /* drawing */
   1303 
   1304 void
   1305 cso_set_index_buffer(struct cso_context *cso,
   1306                      const struct pipe_index_buffer *ib)
   1307 {
   1308    struct u_vbuf *vbuf = cso->vbuf;
   1309 
   1310    if (vbuf) {
   1311       u_vbuf_set_index_buffer(vbuf, ib);
   1312    } else {
   1313       struct pipe_context *pipe = cso->pipe;
   1314       pipe->set_index_buffer(pipe, ib);
   1315    }
   1316 }
   1317 
   1318 void
   1319 cso_draw_vbo(struct cso_context *cso,
   1320              const struct pipe_draw_info *info)
   1321 {
   1322    struct u_vbuf *vbuf = cso->vbuf;
   1323 
   1324    if (vbuf) {
   1325       u_vbuf_draw_vbo(vbuf, info);
   1326    } else {
   1327       struct pipe_context *pipe = cso->pipe;
   1328       pipe->draw_vbo(pipe, info);
   1329    }
   1330 }
   1331 
   1332 void
   1333 cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count)
   1334 {
   1335    struct pipe_draw_info info;
   1336 
   1337    util_draw_init_info(&info);
   1338 
   1339    info.mode = mode;
   1340    info.start = start;
   1341    info.count = count;
   1342    info.min_index = start;
   1343    info.max_index = start + count - 1;
   1344 
   1345    cso_draw_vbo(cso, &info);
   1346 }
   1347