Home | History | Annotate | Download | only in nv50
      1 /*
      2  * Copyright 2010 Christoph Bumiller
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20  * SOFTWARE.
     21  */
     22 
     23 #include "pipe/p_defines.h"
     24 #include "util/u_inlines.h"
     25 #include "util/u_transfer.h"
     26 
     27 #include "tgsi/tgsi_parse.h"
     28 
     29 #include "nv50_stateobj.h"
     30 #include "nv50_context.h"
     31 
     32 #include "nv50_3d.xml.h"
     33 #include "nv50_texture.xml.h"
     34 
     35 #include "nouveau/nouveau_gldefs.h"
     36 
     37 /* Caveats:
     38  *  ! pipe_sampler_state.normalized_coords is ignored - rectangle textures will
     39  *     use non-normalized coordinates, everything else won't
     40  *    (The relevant bit is in the TIC entry and not the TSC entry.)
     41  *
     42  *  ! pipe_sampler_state.seamless_cube_map is ignored - seamless filtering is
     43  *     always activated on NVA0 +
     44  *    (Give me the global bit, otherwise it's not worth the CPU work.)
     45  *
     46  *  ! pipe_sampler_state.border_color is not swizzled according to the texture
     47  *     swizzle in pipe_sampler_view
     48  *    (This will be ugly with indirect independent texture/sampler access,
     49  *     we'd have to emulate the logic in the shader. GL doesn't have that,
     50  *     D3D doesn't have swizzle, if we knew what we were implementing we'd be
     51  *     good.)
     52  *
     53  *  ! pipe_rasterizer_state.line_last_pixel is ignored - it is never drawn
     54  *
     55  *  ! pipe_rasterizer_state.flatshade_first also applies to QUADS
     56  *    (There's a GL query for that, forcing an exception is just ridiculous.)
     57  *
     58  *  ! pipe_rasterizer_state.gl_rasterization_rules is ignored - pixel centers
     59  *     are always at half integer coordinates and the top-left rule applies
     60  *    (There does not seem to be a hardware switch for this.)
     61  *
     62  *  ! pipe_rasterizer_state.sprite_coord_enable is masked with 0xff on NVC0
     63  *    (The hardware only has 8 slots meant for TexCoord and we have to assign
     64  *     in advance to maintain elegant separate shader objects.)
     65  */
     66 
     67 static INLINE uint32_t
     68 nv50_colormask(unsigned mask)
     69 {
     70    uint32_t ret = 0;
     71 
     72    if (mask & PIPE_MASK_R)
     73       ret |= 0x0001;
     74    if (mask & PIPE_MASK_G)
     75       ret |= 0x0010;
     76    if (mask & PIPE_MASK_B)
     77       ret |= 0x0100;
     78    if (mask & PIPE_MASK_A)
     79       ret |= 0x1000;
     80 
     81    return ret;
     82 }
     83 
     84 #define NV50_BLEND_FACTOR_CASE(a, b) \
     85    case PIPE_BLENDFACTOR_##a: return NV50_3D_BLEND_FACTOR_##b
     86 
     87 static INLINE uint32_t
     88 nv50_blend_fac(unsigned factor)
     89 {
     90    switch (factor) {
     91    NV50_BLEND_FACTOR_CASE(ONE, ONE);
     92    NV50_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR);
     93    NV50_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA);
     94    NV50_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA);
     95    NV50_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR);
     96    NV50_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE);
     97    NV50_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR);
     98    NV50_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA);
     99    NV50_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR);
    100    NV50_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA);
    101    NV50_BLEND_FACTOR_CASE(ZERO, ZERO);
    102    NV50_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR);
    103    NV50_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
    104    NV50_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA);
    105    NV50_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR);
    106    NV50_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR);
    107    NV50_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA);
    108    NV50_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR);
    109    NV50_BLEND_FACTOR_CASE(INV_SRC1_ALPHA, ONE_MINUS_SRC1_ALPHA);
    110    default:
    111       return NV50_3D_BLEND_FACTOR_ZERO;
    112    }
    113 }
    114 
    115 static void *
    116 nv50_blend_state_create(struct pipe_context *pipe,
    117                         const struct pipe_blend_state *cso)
    118 {
    119    struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj);
    120    int i;
    121    boolean emit_common_func = cso->rt[0].blend_enable;
    122    uint32_t ms;
    123 
    124    if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
    125       SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
    126       SB_DATA    (so, cso->independent_blend_enable);
    127    }
    128 
    129    so->pipe = *cso;
    130 
    131    SB_BEGIN_3D(so, COLOR_MASK_COMMON, 1);
    132    SB_DATA    (so, !cso->independent_blend_enable);
    133 
    134    SB_BEGIN_3D(so, BLEND_ENABLE_COMMON, 1);
    135    SB_DATA    (so, !cso->independent_blend_enable);
    136 
    137    if (cso->independent_blend_enable) {
    138       SB_BEGIN_3D(so, BLEND_ENABLE(0), 8);
    139       for (i = 0; i < 8; ++i) {
    140          SB_DATA(so, cso->rt[i].blend_enable);
    141          if (cso->rt[i].blend_enable)
    142             emit_common_func = TRUE;
    143       }
    144 
    145       if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
    146          emit_common_func = FALSE;
    147 
    148          for (i = 0; i < 8; ++i) {
    149             if (!cso->rt[i].blend_enable)
    150                continue;
    151             SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6);
    152             SB_DATA     (so, nvgl_blend_eqn(cso->rt[i].rgb_func));
    153             SB_DATA     (so, nv50_blend_fac(cso->rt[i].rgb_src_factor));
    154             SB_DATA     (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor));
    155             SB_DATA     (so, nvgl_blend_eqn(cso->rt[i].alpha_func));
    156             SB_DATA     (so, nv50_blend_fac(cso->rt[i].alpha_src_factor));
    157             SB_DATA     (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor));
    158          }
    159       }
    160    } else {
    161       SB_BEGIN_3D(so, BLEND_ENABLE(0), 1);
    162       SB_DATA    (so, cso->rt[0].blend_enable);
    163    }
    164 
    165    if (emit_common_func) {
    166       SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
    167       SB_DATA    (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
    168       SB_DATA    (so, nv50_blend_fac(cso->rt[0].rgb_src_factor));
    169       SB_DATA    (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor));
    170       SB_DATA    (so, nvgl_blend_eqn(cso->rt[0].alpha_func));
    171       SB_DATA    (so, nv50_blend_fac(cso->rt[0].alpha_src_factor));
    172       SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1);
    173       SB_DATA    (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor));
    174    }
    175 
    176    if (cso->logicop_enable) {
    177       SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2);
    178       SB_DATA    (so, 1);
    179       SB_DATA    (so, nvgl_logicop_func(cso->logicop_func));
    180    } else {
    181       SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1);
    182       SB_DATA    (so, 0);
    183    }
    184 
    185    if (cso->independent_blend_enable) {
    186       SB_BEGIN_3D(so, COLOR_MASK(0), 8);
    187       for (i = 0; i < 8; ++i)
    188          SB_DATA(so, nv50_colormask(cso->rt[i].colormask));
    189    } else {
    190       SB_BEGIN_3D(so, COLOR_MASK(0), 1);
    191       SB_DATA    (so, nv50_colormask(cso->rt[0].colormask));
    192    }
    193 
    194    ms = 0;
    195    if (cso->alpha_to_coverage)
    196       ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE;
    197    if (cso->alpha_to_one)
    198       ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE;
    199 
    200    SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1);
    201    SB_DATA    (so, ms);
    202 
    203    assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
    204    return so;
    205 }
    206 
    207 static void
    208 nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso)
    209 {
    210    struct nv50_context *nv50 = nv50_context(pipe);
    211 
    212    nv50->blend = hwcso;
    213    nv50->dirty |= NV50_NEW_BLEND;
    214 }
    215 
    216 static void
    217 nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso)
    218 {
    219    FREE(hwcso);
    220 }
    221 
    222 /* NOTE: ignoring line_last_pixel, using FALSE (set on screen init) */
    223 static void *
    224 nv50_rasterizer_state_create(struct pipe_context *pipe,
    225                              const struct pipe_rasterizer_state *cso)
    226 {
    227    struct nv50_rasterizer_stateobj *so;
    228    uint32_t reg;
    229 
    230    so = CALLOC_STRUCT(nv50_rasterizer_stateobj);
    231    if (!so)
    232       return NULL;
    233    so->pipe = *cso;
    234 
    235 #ifndef NV50_SCISSORS_CLIPPING
    236    SB_BEGIN_3D(so, SCISSOR_ENABLE(0), 1);
    237    SB_DATA    (so, cso->scissor);
    238 #endif
    239 
    240    SB_BEGIN_3D(so, SHADE_MODEL, 1);
    241    SB_DATA    (so, cso->flatshade ? NV50_3D_SHADE_MODEL_FLAT :
    242                                     NV50_3D_SHADE_MODEL_SMOOTH);
    243    SB_BEGIN_3D(so, PROVOKING_VERTEX_LAST, 1);
    244    SB_DATA    (so, !cso->flatshade_first);
    245    SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1);
    246    SB_DATA    (so, cso->light_twoside);
    247 
    248    SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1);
    249    SB_DATA    (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000);
    250 
    251    SB_BEGIN_3D(so, MULTISAMPLE_ENABLE, 1);
    252    SB_DATA    (so, cso->multisample);
    253 
    254    SB_BEGIN_3D(so, LINE_WIDTH, 1);
    255    SB_DATA    (so, fui(cso->line_width));
    256    SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1);
    257    SB_DATA    (so, cso->line_smooth);
    258 
    259    SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1);
    260    if (cso->line_stipple_enable) {
    261       SB_DATA    (so, 1);
    262       SB_BEGIN_3D(so, LINE_STIPPLE, 1);
    263       SB_DATA    (so, (cso->line_stipple_pattern << 8) |
    264                   cso->line_stipple_factor);
    265    } else {
    266       SB_DATA    (so, 0);
    267    }
    268 
    269    if (!cso->point_size_per_vertex) {
    270       SB_BEGIN_3D(so, POINT_SIZE, 1);
    271       SB_DATA    (so, fui(cso->point_size));
    272    }
    273    SB_BEGIN_3D(so, POINT_SPRITE_ENABLE, 1);
    274    SB_DATA    (so, cso->point_quad_rasterization);
    275    SB_BEGIN_3D(so, POINT_SMOOTH_ENABLE, 1);
    276    SB_DATA    (so, cso->point_smooth);
    277 
    278    SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 3);
    279    SB_DATA    (so, nvgl_polygon_mode(cso->fill_front));
    280    SB_DATA    (so, nvgl_polygon_mode(cso->fill_back));
    281    SB_DATA    (so, cso->poly_smooth);
    282 
    283    SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);
    284    SB_DATA    (so, cso->cull_face != PIPE_FACE_NONE);
    285    SB_DATA    (so, cso->front_ccw ? NV50_3D_FRONT_FACE_CCW :
    286                                     NV50_3D_FRONT_FACE_CW);
    287    switch (cso->cull_face) {
    288    case PIPE_FACE_FRONT_AND_BACK:
    289       SB_DATA(so, NV50_3D_CULL_FACE_FRONT_AND_BACK);
    290       break;
    291    case PIPE_FACE_FRONT:
    292       SB_DATA(so, NV50_3D_CULL_FACE_FRONT);
    293       break;
    294    case PIPE_FACE_BACK:
    295    default:
    296      SB_DATA(so, NV50_3D_CULL_FACE_BACK);
    297      break;
    298    }
    299 
    300    SB_BEGIN_3D(so, POLYGON_STIPPLE_ENABLE, 1);
    301    SB_DATA    (so, cso->poly_stipple_enable);
    302    SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3);
    303    SB_DATA    (so, cso->offset_point);
    304    SB_DATA    (so, cso->offset_line);
    305    SB_DATA    (so, cso->offset_tri);
    306 
    307    if (cso->offset_point || cso->offset_line || cso->offset_tri) {
    308       SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);
    309       SB_DATA    (so, fui(cso->offset_scale));
    310       SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
    311       SB_DATA    (so, fui(cso->offset_units * 2.0f));
    312       SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1);
    313       SB_DATA    (so, fui(cso->offset_clamp));
    314    }
    315 
    316    if (cso->depth_clip) {
    317       reg = 0;
    318    } else {
    319       reg =
    320          NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR |
    321          NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR |
    322          NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;
    323    }
    324 #ifndef NV50_SCISSORS_CLIPPING
    325    reg |=
    326       NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 |
    327       NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;
    328 #endif
    329    SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1);
    330    SB_DATA    (so, reg);
    331 
    332    assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
    333    return (void *)so;
    334 }
    335 
    336 static void
    337 nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
    338 {
    339    struct nv50_context *nv50 = nv50_context(pipe);
    340 
    341    nv50->rast = hwcso;
    342    nv50->dirty |= NV50_NEW_RASTERIZER;
    343 }
    344 
    345 static void
    346 nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
    347 {
    348    FREE(hwcso);
    349 }
    350 
    351 static void *
    352 nv50_zsa_state_create(struct pipe_context *pipe,
    353                       const struct pipe_depth_stencil_alpha_state *cso)
    354 {
    355    struct nv50_zsa_stateobj *so = CALLOC_STRUCT(nv50_zsa_stateobj);
    356 
    357    so->pipe = *cso;
    358 
    359    SB_BEGIN_3D(so, DEPTH_WRITE_ENABLE, 1);
    360    SB_DATA    (so, cso->depth.writemask);
    361    SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);
    362    if (cso->depth.enabled) {
    363       SB_DATA    (so, 1);
    364       SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
    365       SB_DATA    (so, nvgl_comparison_op(cso->depth.func));
    366    } else {
    367       SB_DATA    (so, 0);
    368    }
    369 
    370    if (cso->stencil[0].enabled) {
    371       SB_BEGIN_3D(so, STENCIL_ENABLE, 5);
    372       SB_DATA    (so, 1);
    373       SB_DATA    (so, nvgl_stencil_op(cso->stencil[0].fail_op));
    374       SB_DATA    (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
    375       SB_DATA    (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
    376       SB_DATA    (so, nvgl_comparison_op(cso->stencil[0].func));
    377       SB_BEGIN_3D(so, STENCIL_FRONT_MASK, 2);
    378       SB_DATA    (so, cso->stencil[0].writemask);
    379       SB_DATA    (so, cso->stencil[0].valuemask);
    380    } else {
    381       SB_BEGIN_3D(so, STENCIL_ENABLE, 1);
    382       SB_DATA    (so, 0);
    383    }
    384 
    385    if (cso->stencil[1].enabled) {
    386       assert(cso->stencil[0].enabled);
    387       SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5);
    388       SB_DATA    (so, 1);
    389       SB_DATA    (so, nvgl_stencil_op(cso->stencil[1].fail_op));
    390       SB_DATA    (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
    391       SB_DATA    (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
    392       SB_DATA    (so, nvgl_comparison_op(cso->stencil[1].func));
    393       SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2);
    394       SB_DATA    (so, cso->stencil[1].writemask);
    395       SB_DATA    (so, cso->stencil[1].valuemask);
    396    } else {
    397       SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 1);
    398       SB_DATA    (so, 0);
    399    }
    400 
    401    SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);
    402    if (cso->alpha.enabled) {
    403       SB_DATA    (so, 1);
    404       SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
    405       SB_DATA    (so, fui(cso->alpha.ref_value));
    406       SB_DATA    (so, nvgl_comparison_op(cso->alpha.func));
    407    } else {
    408       SB_DATA    (so, 0);
    409    }
    410 
    411    assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
    412    return (void *)so;
    413 }
    414 
    415 static void
    416 nv50_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
    417 {
    418    struct nv50_context *nv50 = nv50_context(pipe);
    419 
    420    nv50->zsa = hwcso;
    421    nv50->dirty |= NV50_NEW_ZSA;
    422 }
    423 
    424 static void
    425 nv50_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
    426 {
    427    FREE(hwcso);
    428 }
    429 
    430 /* ====================== SAMPLERS AND TEXTURES ================================
    431  */
    432 
    433 #define NV50_TSC_WRAP_CASE(n) \
    434     case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n
    435 
    436 static INLINE unsigned
    437 nv50_tsc_wrap_mode(unsigned wrap)
    438 {
    439    switch (wrap) {
    440    NV50_TSC_WRAP_CASE(REPEAT);
    441    NV50_TSC_WRAP_CASE(MIRROR_REPEAT);
    442    NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE);
    443    NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER);
    444    NV50_TSC_WRAP_CASE(CLAMP);
    445    NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE);
    446    NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER);
    447    NV50_TSC_WRAP_CASE(MIRROR_CLAMP);
    448    default:
    449        NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
    450        return NV50_TSC_WRAP_REPEAT;
    451    }
    452 }
    453 
    454 void *
    455 nv50_sampler_state_create(struct pipe_context *pipe,
    456                           const struct pipe_sampler_state *cso)
    457 {
    458    struct nv50_tsc_entry *so = CALLOC_STRUCT(nv50_tsc_entry);
    459    float f[2];
    460 
    461    so->id = -1;
    462 
    463    so->tsc[0] = (0x00026000 |
    464                  (nv50_tsc_wrap_mode(cso->wrap_s) << 0) |
    465                  (nv50_tsc_wrap_mode(cso->wrap_t) << 3) |
    466                  (nv50_tsc_wrap_mode(cso->wrap_r) << 6));
    467 
    468    if (nouveau_screen(pipe->screen)->class_3d >= NVE4_3D_CLASS) {
    469       if (cso->seamless_cube_map)
    470          so->tsc[1] |= NVE4_TSC_1_CUBE_SEAMLESS;
    471       if (!cso->normalized_coords)
    472          so->tsc[1] |= NVE4_TSC_1_FORCE_NONNORMALIZED_COORDS;
    473    }
    474 
    475    switch (cso->mag_img_filter) {
    476    case PIPE_TEX_FILTER_LINEAR:
    477       so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR;
    478       break;
    479    case PIPE_TEX_FILTER_NEAREST:
    480    default:
    481       so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST;
    482       break;
    483    }
    484 
    485    switch (cso->min_img_filter) {
    486    case PIPE_TEX_FILTER_LINEAR:
    487       so->tsc[1] |= NV50_TSC_1_MINF_LINEAR;
    488       break;
    489    case PIPE_TEX_FILTER_NEAREST:
    490    default:
    491       so->tsc[1] |= NV50_TSC_1_MINF_NEAREST;
    492       break;
    493    }
    494 
    495    switch (cso->min_mip_filter) {
    496    case PIPE_TEX_MIPFILTER_LINEAR:
    497       so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR;
    498       break;
    499    case PIPE_TEX_MIPFILTER_NEAREST:
    500       so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST;
    501       break;
    502    case PIPE_TEX_MIPFILTER_NONE:
    503    default:
    504       so->tsc[1] |= NV50_TSC_1_MIPF_NONE;
    505       break;
    506    }
    507 
    508    if (cso->max_anisotropy >= 16)
    509       so->tsc[0] |= (7 << 20);
    510    else
    511    if (cso->max_anisotropy >= 12)
    512       so->tsc[0] |= (6 << 20);
    513    else {
    514       so->tsc[0] |= (cso->max_anisotropy >> 1) << 20;
    515 
    516       if (cso->max_anisotropy >= 4)
    517          so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35;
    518       else
    519       if (cso->max_anisotropy >= 2)
    520          so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15;
    521    }
    522 
    523    if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
    524       /* NOTE: must be deactivated for non-shadow textures */
    525       so->tsc[0] |= (1 << 9);
    526       so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;
    527    }
    528 
    529    f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f);
    530    so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12;
    531 
    532    f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f);
    533    f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f);
    534    so->tsc[2] |=
    535       (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff);
    536 
    537    so->tsc[4] = fui(cso->border_color.f[0]);
    538    so->tsc[5] = fui(cso->border_color.f[1]);
    539    so->tsc[6] = fui(cso->border_color.f[2]);
    540    so->tsc[7] = fui(cso->border_color.f[3]);
    541 
    542    return (void *)so;
    543 }
    544 
    545 static void
    546 nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
    547 {
    548    unsigned s, i;
    549 
    550    for (s = 0; s < 3; ++s)
    551       for (i = 0; i < nv50_context(pipe)->num_samplers[s]; ++i)
    552          if (nv50_context(pipe)->samplers[s][i] == hwcso)
    553             nv50_context(pipe)->samplers[s][i] = NULL;
    554 
    555    nv50_screen_tsc_free(nv50_context(pipe)->screen, nv50_tsc_entry(hwcso));
    556 
    557    FREE(hwcso);
    558 }
    559 
    560 static INLINE void
    561 nv50_stage_sampler_states_bind(struct nv50_context *nv50, int s,
    562                                unsigned nr, void **hwcso)
    563 {
    564    unsigned i;
    565 
    566    for (i = 0; i < nr; ++i) {
    567       struct nv50_tsc_entry *old = nv50->samplers[s][i];
    568 
    569       nv50->samplers[s][i] = nv50_tsc_entry(hwcso[i]);
    570       if (old)
    571          nv50_screen_tsc_unlock(nv50->screen, old);
    572    }
    573    for (; i < nv50->num_samplers[s]; ++i)
    574       if (nv50->samplers[s][i])
    575          nv50_screen_tsc_unlock(nv50->screen, nv50->samplers[s][i]);
    576 
    577    nv50->num_samplers[s] = nr;
    578 
    579    nv50->dirty |= NV50_NEW_SAMPLERS;
    580 }
    581 
    582 static void
    583 nv50_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
    584 {
    585    nv50_stage_sampler_states_bind(nv50_context(pipe), 0, nr, s);
    586 }
    587 
    588 static void
    589 nv50_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
    590 {
    591    nv50_stage_sampler_states_bind(nv50_context(pipe), 2, nr, s);
    592 }
    593 
    594 static void
    595 nv50_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
    596 {
    597    nv50_stage_sampler_states_bind(nv50_context(pipe), 1, nr, s);
    598 }
    599 
    600 /* NOTE: only called when not referenced anywhere, won't be bound */
    601 static void
    602 nv50_sampler_view_destroy(struct pipe_context *pipe,
    603                           struct pipe_sampler_view *view)
    604 {
    605    pipe_resource_reference(&view->texture, NULL);
    606 
    607    nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view));
    608 
    609    FREE(nv50_tic_entry(view));
    610 }
    611 
    612 static INLINE void
    613 nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
    614                              unsigned nr,
    615                              struct pipe_sampler_view **views)
    616 {
    617    unsigned i;
    618 
    619    for (i = 0; i < nr; ++i) {
    620       struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
    621       if (old)
    622          nv50_screen_tic_unlock(nv50->screen, old);
    623 
    624       pipe_sampler_view_reference(&nv50->textures[s][i], views[i]);
    625    }
    626 
    627    for (i = nr; i < nv50->num_textures[s]; ++i) {
    628       struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
    629       if (!old)
    630          continue;
    631       nv50_screen_tic_unlock(nv50->screen, old);
    632 
    633       pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
    634    }
    635 
    636    nv50->num_textures[s] = nr;
    637 
    638    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
    639 
    640    nv50->dirty |= NV50_NEW_TEXTURES;
    641 }
    642 
    643 static void
    644 nv50_vp_set_sampler_views(struct pipe_context *pipe,
    645                           unsigned nr,
    646                           struct pipe_sampler_view **views)
    647 {
    648    nv50_stage_set_sampler_views(nv50_context(pipe), 0, nr, views);
    649 }
    650 
    651 static void
    652 nv50_fp_set_sampler_views(struct pipe_context *pipe,
    653                           unsigned nr,
    654                           struct pipe_sampler_view **views)
    655 {
    656    nv50_stage_set_sampler_views(nv50_context(pipe), 2, nr, views);
    657 }
    658 
    659 static void
    660 nv50_gp_set_sampler_views(struct pipe_context *pipe,
    661                           unsigned nr,
    662                           struct pipe_sampler_view **views)
    663 {
    664    nv50_stage_set_sampler_views(nv50_context(pipe), 1, nr, views);
    665 }
    666 
    667 /* ============================= SHADERS =======================================
    668  */
    669 
    670 static void *
    671 nv50_sp_state_create(struct pipe_context *pipe,
    672                      const struct pipe_shader_state *cso, unsigned type)
    673 {
    674    struct nv50_program *prog;
    675 
    676    prog = CALLOC_STRUCT(nv50_program);
    677    if (!prog)
    678       return NULL;
    679 
    680    prog->type = type;
    681    prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
    682 
    683    if (cso->stream_output.num_outputs)
    684       prog->pipe.stream_output = cso->stream_output;
    685 
    686    return (void *)prog;
    687 }
    688 
    689 static void
    690 nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso)
    691 {
    692    struct nv50_program *prog = (struct nv50_program *)hwcso;
    693 
    694    nv50_program_destroy(nv50_context(pipe), prog);
    695 
    696    FREE((void *)prog->pipe.tokens);
    697    FREE(prog);
    698 }
    699 
    700 static void *
    701 nv50_vp_state_create(struct pipe_context *pipe,
    702                      const struct pipe_shader_state *cso)
    703 {
    704    return nv50_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);
    705 }
    706 
    707 static void
    708 nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso)
    709 {
    710     struct nv50_context *nv50 = nv50_context(pipe);
    711 
    712     nv50->vertprog = hwcso;
    713     nv50->dirty |= NV50_NEW_VERTPROG;
    714 }
    715 
    716 static void *
    717 nv50_fp_state_create(struct pipe_context *pipe,
    718                      const struct pipe_shader_state *cso)
    719 {
    720    return nv50_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);
    721 }
    722 
    723 static void
    724 nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso)
    725 {
    726     struct nv50_context *nv50 = nv50_context(pipe);
    727 
    728     nv50->fragprog = hwcso;
    729     nv50->dirty |= NV50_NEW_FRAGPROG;
    730 }
    731 
    732 static void *
    733 nv50_gp_state_create(struct pipe_context *pipe,
    734                      const struct pipe_shader_state *cso)
    735 {
    736    return nv50_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);
    737 }
    738 
    739 static void
    740 nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso)
    741 {
    742     struct nv50_context *nv50 = nv50_context(pipe);
    743 
    744     nv50->gmtyprog = hwcso;
    745     nv50->dirty |= NV50_NEW_GMTYPROG;
    746 }
    747 
    748 static void
    749 nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    750                          struct pipe_constant_buffer *cb)
    751 {
    752    struct nv50_context *nv50 = nv50_context(pipe);
    753    struct pipe_resource *res = cb ? cb->buffer : NULL;
    754    const unsigned s = nv50_context_shader_stage(shader);
    755    const unsigned i = index;
    756 
    757    if (shader == PIPE_SHADER_COMPUTE)
    758       return;
    759 
    760    if (nv50->constbuf[s][i].user)
    761       nv50->constbuf[s][i].u.buf = NULL;
    762    else
    763    if (nv50->constbuf[s][i].u.buf)
    764       nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(s, i));
    765 
    766    pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res);
    767 
    768    nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE;
    769    if (nv50->constbuf[s][i].user) {
    770       nv50->constbuf[s][i].u.data = cb->user_buffer;
    771       nv50->constbuf[s][i].size = cb->buffer_size;
    772       nv50->constbuf_valid[s] |= 1 << i;
    773    } else
    774    if (res) {
    775       nv50->constbuf[s][i].offset = cb->buffer_offset;
    776       nv50->constbuf[s][i].size = align(cb->buffer_size, 0x100);
    777       nv50->constbuf_valid[s] |= 1 << i;
    778    } else {
    779       nv50->constbuf_valid[s] &= ~(1 << i);
    780    }
    781    nv50->constbuf_dirty[s] |= 1 << i;
    782 
    783    nv50->dirty |= NV50_NEW_CONSTBUF;
    784 }
    785 
    786 /* =============================================================================
    787  */
    788 
    789 static void
    790 nv50_set_blend_color(struct pipe_context *pipe,
    791                      const struct pipe_blend_color *bcol)
    792 {
    793    struct nv50_context *nv50 = nv50_context(pipe);
    794 
    795    nv50->blend_colour = *bcol;
    796    nv50->dirty |= NV50_NEW_BLEND_COLOUR;
    797 }
    798 
    799 static void
    800 nv50_set_stencil_ref(struct pipe_context *pipe,
    801                      const struct pipe_stencil_ref *sr)
    802 {
    803    struct nv50_context *nv50 = nv50_context(pipe);
    804 
    805    nv50->stencil_ref = *sr;
    806    nv50->dirty |= NV50_NEW_STENCIL_REF;
    807 }
    808 
    809 static void
    810 nv50_set_clip_state(struct pipe_context *pipe,
    811                     const struct pipe_clip_state *clip)
    812 {
    813    struct nv50_context *nv50 = nv50_context(pipe);
    814 
    815    memcpy(nv50->clip.ucp, clip->ucp, sizeof(clip->ucp));
    816 
    817    nv50->dirty |= NV50_NEW_CLIP;
    818 }
    819 
    820 static void
    821 nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
    822 {
    823    struct nv50_context *nv50 = nv50_context(pipe);
    824 
    825    nv50->sample_mask = sample_mask;
    826    nv50->dirty |= NV50_NEW_SAMPLE_MASK;
    827 }
    828 
    829 
    830 static void
    831 nv50_set_framebuffer_state(struct pipe_context *pipe,
    832                            const struct pipe_framebuffer_state *fb)
    833 {
    834    struct nv50_context *nv50 = nv50_context(pipe);
    835    unsigned i;
    836 
    837    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
    838 
    839    for (i = 0; i < fb->nr_cbufs; ++i)
    840       pipe_surface_reference(&nv50->framebuffer.cbufs[i], fb->cbufs[i]);
    841    for (; i < nv50->framebuffer.nr_cbufs; ++i)
    842       pipe_surface_reference(&nv50->framebuffer.cbufs[i], NULL);
    843 
    844    nv50->framebuffer.nr_cbufs = fb->nr_cbufs;
    845 
    846    nv50->framebuffer.width = fb->width;
    847    nv50->framebuffer.height = fb->height;
    848 
    849    pipe_surface_reference(&nv50->framebuffer.zsbuf, fb->zsbuf);
    850 
    851    nv50->dirty |= NV50_NEW_FRAMEBUFFER;
    852 }
    853 
    854 static void
    855 nv50_set_polygon_stipple(struct pipe_context *pipe,
    856                          const struct pipe_poly_stipple *stipple)
    857 {
    858    struct nv50_context *nv50 = nv50_context(pipe);
    859 
    860    nv50->stipple = *stipple;
    861    nv50->dirty |= NV50_NEW_STIPPLE;
    862 }
    863 
    864 static void
    865 nv50_set_scissor_state(struct pipe_context *pipe,
    866                        const struct pipe_scissor_state *scissor)
    867 {
    868    struct nv50_context *nv50 = nv50_context(pipe);
    869 
    870    nv50->scissor = *scissor;
    871    nv50->dirty |= NV50_NEW_SCISSOR;
    872 }
    873 
    874 static void
    875 nv50_set_viewport_state(struct pipe_context *pipe,
    876                         const struct pipe_viewport_state *vpt)
    877 {
    878    struct nv50_context *nv50 = nv50_context(pipe);
    879 
    880    nv50->viewport = *vpt;
    881    nv50->dirty |= NV50_NEW_VIEWPORT;
    882 }
    883 
    884 static void
    885 nv50_set_vertex_buffers(struct pipe_context *pipe,
    886                         unsigned count,
    887                         const struct pipe_vertex_buffer *vb)
    888 {
    889    struct nv50_context *nv50 = nv50_context(pipe);
    890    unsigned i;
    891 
    892    nv50->vbo_user = nv50->vbo_constant = 0;
    893 
    894    for (i = 0; i < count; ++i) {
    895       nv50->vtxbuf[i].stride = vb[i].stride;
    896       pipe_resource_reference(&nv50->vtxbuf[i].buffer, vb[i].buffer);
    897       if (!vb[i].buffer && vb[i].user_buffer) {
    898          nv50->vtxbuf[i].user_buffer = vb[i].user_buffer;
    899          nv50->vbo_user |= 1 << i;
    900          if (!vb[i].stride)
    901             nv50->vbo_constant |= 1 << i;
    902       } else {
    903          nv50->vtxbuf[i].buffer_offset = vb[i].buffer_offset;
    904       }
    905    }
    906    for (; i < nv50->num_vtxbufs; ++i)
    907       pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
    908 
    909    nv50->num_vtxbufs = count;
    910 
    911    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
    912 
    913    nv50->dirty |= NV50_NEW_ARRAYS;
    914 }
    915 
    916 static void
    917 nv50_set_index_buffer(struct pipe_context *pipe,
    918                       const struct pipe_index_buffer *ib)
    919 {
    920    struct nv50_context *nv50 = nv50_context(pipe);
    921 
    922    if (nv50->idxbuf.buffer)
    923       nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX);
    924 
    925    if (ib) {
    926       pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
    927       nv50->idxbuf.index_size = ib->index_size;
    928       if (ib->buffer) {
    929          nv50->idxbuf.offset = ib->offset;
    930          BCTX_REFN(nv50->bufctx_3d, INDEX, nv04_resource(ib->buffer), RD);
    931       } else {
    932          nv50->idxbuf.user_buffer = ib->user_buffer;
    933       }
    934    } else {
    935       pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
    936    }
    937 }
    938 
    939 static void
    940 nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
    941 {
    942    struct nv50_context *nv50 = nv50_context(pipe);
    943 
    944    nv50->vertex = hwcso;
    945    nv50->dirty |= NV50_NEW_VERTEX;
    946 }
    947 
    948 static struct pipe_stream_output_target *
    949 nv50_so_target_create(struct pipe_context *pipe,
    950                       struct pipe_resource *res,
    951                       unsigned offset, unsigned size)
    952 {
    953    struct nv50_so_target *targ = MALLOC_STRUCT(nv50_so_target);
    954    if (!targ)
    955       return NULL;
    956 
    957    if (nouveau_context(pipe)->screen->class_3d >= NVA0_3D_CLASS) {
    958       targ->pq = pipe->create_query(pipe,
    959                                     NVA0_QUERY_STREAM_OUTPUT_BUFFER_OFFSET);
    960       if (!targ->pq) {
    961          FREE(targ);
    962          return NULL;
    963       }
    964    } else {
    965       targ->pq = NULL;
    966    }
    967    targ->clean = TRUE;
    968 
    969    targ->pipe.buffer_size = size;
    970    targ->pipe.buffer_offset = offset;
    971    targ->pipe.context = pipe;
    972    targ->pipe.buffer = NULL;
    973    pipe_resource_reference(&targ->pipe.buffer, res);
    974    pipe_reference_init(&targ->pipe.reference, 1);
    975 
    976    return &targ->pipe;
    977 }
    978 
    979 static void
    980 nv50_so_target_destroy(struct pipe_context *pipe,
    981                        struct pipe_stream_output_target *ptarg)
    982 {
    983    struct nv50_so_target *targ = nv50_so_target(ptarg);
    984    if (targ->pq)
    985       pipe->destroy_query(pipe, targ->pq);
    986    pipe_resource_reference(&targ->pipe.buffer, NULL);
    987    FREE(targ);
    988 }
    989 
    990 static void
    991 nv50_set_stream_output_targets(struct pipe_context *pipe,
    992                                unsigned num_targets,
    993                                struct pipe_stream_output_target **targets,
    994                                unsigned append_mask)
    995 {
    996    struct nv50_context *nv50 = nv50_context(pipe);
    997    unsigned i;
    998    boolean serialize = TRUE;
    999    const boolean can_resume = nv50->screen->base.class_3d >= NVA0_3D_CLASS;
   1000 
   1001    assert(num_targets <= 4);
   1002 
   1003    for (i = 0; i < num_targets; ++i) {
   1004       const boolean changed = nv50->so_target[i] != targets[i];
   1005       if (!changed && (append_mask & (1 << i)))
   1006          continue;
   1007       nv50->so_targets_dirty |= 1 << i;
   1008 
   1009       if (can_resume && changed && nv50->so_target[i]) {
   1010          nva0_so_target_save_offset(pipe, nv50->so_target[i], i, serialize);
   1011          serialize = FALSE;
   1012       }
   1013 
   1014       if (targets[i] && !(append_mask & (1 << i)))
   1015          nv50_so_target(targets[i])->clean = TRUE;
   1016 
   1017       pipe_so_target_reference(&nv50->so_target[i], targets[i]);
   1018    }
   1019    for (; i < nv50->num_so_targets; ++i) {
   1020       if (can_resume && nv50->so_target[i]) {
   1021          nva0_so_target_save_offset(pipe, nv50->so_target[i], i, serialize);
   1022          serialize = FALSE;
   1023       }
   1024       pipe_so_target_reference(&nv50->so_target[i], NULL);
   1025       nv50->so_targets_dirty |= 1 << i;
   1026    }
   1027    nv50->num_so_targets = num_targets;
   1028 
   1029    if (nv50->so_targets_dirty)
   1030       nv50->dirty |= NV50_NEW_STRMOUT;
   1031 }
   1032 
   1033 void
   1034 nv50_init_state_functions(struct nv50_context *nv50)
   1035 {
   1036    struct pipe_context *pipe = &nv50->base.pipe;
   1037 
   1038    pipe->create_blend_state = nv50_blend_state_create;
   1039    pipe->bind_blend_state = nv50_blend_state_bind;
   1040    pipe->delete_blend_state = nv50_blend_state_delete;
   1041 
   1042    pipe->create_rasterizer_state = nv50_rasterizer_state_create;
   1043    pipe->bind_rasterizer_state = nv50_rasterizer_state_bind;
   1044    pipe->delete_rasterizer_state = nv50_rasterizer_state_delete;
   1045 
   1046    pipe->create_depth_stencil_alpha_state = nv50_zsa_state_create;
   1047    pipe->bind_depth_stencil_alpha_state = nv50_zsa_state_bind;
   1048    pipe->delete_depth_stencil_alpha_state = nv50_zsa_state_delete;
   1049 
   1050    pipe->create_sampler_state = nv50_sampler_state_create;
   1051    pipe->delete_sampler_state = nv50_sampler_state_delete;
   1052    pipe->bind_vertex_sampler_states   = nv50_vp_sampler_states_bind;
   1053    pipe->bind_fragment_sampler_states = nv50_fp_sampler_states_bind;
   1054    pipe->bind_geometry_sampler_states = nv50_gp_sampler_states_bind;
   1055 
   1056    pipe->create_sampler_view = nv50_create_sampler_view;
   1057    pipe->sampler_view_destroy = nv50_sampler_view_destroy;
   1058    pipe->set_vertex_sampler_views   = nv50_vp_set_sampler_views;
   1059    pipe->set_fragment_sampler_views = nv50_fp_set_sampler_views;
   1060    pipe->set_geometry_sampler_views = nv50_gp_set_sampler_views;
   1061 
   1062    pipe->create_vs_state = nv50_vp_state_create;
   1063    pipe->create_fs_state = nv50_fp_state_create;
   1064    pipe->create_gs_state = nv50_gp_state_create;
   1065    pipe->bind_vs_state = nv50_vp_state_bind;
   1066    pipe->bind_fs_state = nv50_fp_state_bind;
   1067    pipe->bind_gs_state = nv50_gp_state_bind;
   1068    pipe->delete_vs_state = nv50_sp_state_delete;
   1069    pipe->delete_fs_state = nv50_sp_state_delete;
   1070    pipe->delete_gs_state = nv50_sp_state_delete;
   1071 
   1072    pipe->set_blend_color = nv50_set_blend_color;
   1073    pipe->set_stencil_ref = nv50_set_stencil_ref;
   1074    pipe->set_clip_state = nv50_set_clip_state;
   1075    pipe->set_sample_mask = nv50_set_sample_mask;
   1076    pipe->set_constant_buffer = nv50_set_constant_buffer;
   1077    pipe->set_framebuffer_state = nv50_set_framebuffer_state;
   1078    pipe->set_polygon_stipple = nv50_set_polygon_stipple;
   1079    pipe->set_scissor_state = nv50_set_scissor_state;
   1080    pipe->set_viewport_state = nv50_set_viewport_state;
   1081 
   1082    pipe->create_vertex_elements_state = nv50_vertex_state_create;
   1083    pipe->delete_vertex_elements_state = nv50_vertex_state_delete;
   1084    pipe->bind_vertex_elements_state = nv50_vertex_state_bind;
   1085 
   1086    pipe->set_vertex_buffers = nv50_set_vertex_buffers;
   1087    pipe->set_index_buffer = nv50_set_index_buffer;
   1088 
   1089    pipe->create_stream_output_target = nv50_so_target_create;
   1090    pipe->stream_output_target_destroy = nv50_so_target_destroy;
   1091    pipe->set_stream_output_targets = nv50_set_stream_output_targets;
   1092 }
   1093