Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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