Subversion Repositories Kolibri OS

Rev

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

  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. /* Authors:  Keith Whitwell <keith@tungstengraphics.com>
  29.  */
  30.  
  31.  
  32. #include "draw/draw_context.h"
  33. #include "util/u_helpers.h"
  34. #include "util/u_inlines.h"
  35. #include "util/u_math.h"
  36. #include "util/u_memory.h"
  37. #include "util/u_transfer.h"
  38. #include "tgsi/tgsi_parse.h"
  39.  
  40. #include "i915_context.h"
  41. #include "i915_reg.h"
  42. #include "i915_state_inlines.h"
  43. #include "i915_fpc.h"
  44. #include "i915_resource.h"
  45.  
  46. /* The i915 (and related graphics cores) do not support GL_CLAMP.  The
  47.  * Intel drivers for "other operating systems" implement GL_CLAMP as
  48.  * GL_CLAMP_TO_EDGE, so the same is done here.
  49.  */
  50. static unsigned
  51. translate_wrap_mode(unsigned wrap)
  52. {
  53.    switch (wrap) {
  54.    case PIPE_TEX_WRAP_REPEAT:
  55.       return TEXCOORDMODE_WRAP;
  56.    case PIPE_TEX_WRAP_CLAMP:
  57.       return TEXCOORDMODE_CLAMP_EDGE;   /* not quite correct */
  58.    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
  59.       return TEXCOORDMODE_CLAMP_EDGE;
  60.    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
  61.       return TEXCOORDMODE_CLAMP_BORDER;
  62.    case PIPE_TEX_WRAP_MIRROR_REPEAT:
  63.       return TEXCOORDMODE_MIRROR;
  64.    default:
  65.       return TEXCOORDMODE_WRAP;
  66.    }
  67. }
  68.  
  69. static unsigned translate_img_filter( unsigned filter )
  70. {
  71.    switch (filter) {
  72.    case PIPE_TEX_FILTER_NEAREST:
  73.       return FILTER_NEAREST;
  74.    case PIPE_TEX_FILTER_LINEAR:
  75.       return FILTER_LINEAR;
  76.    default:
  77.       assert(0);
  78.       return FILTER_NEAREST;
  79.    }
  80. }
  81.  
  82. static unsigned translate_mip_filter( unsigned filter )
  83. {
  84.    switch (filter) {
  85.    case PIPE_TEX_MIPFILTER_NONE:
  86.       return MIPFILTER_NONE;
  87.    case PIPE_TEX_MIPFILTER_NEAREST:
  88.       return MIPFILTER_NEAREST;
  89.    case PIPE_TEX_MIPFILTER_LINEAR:
  90.       return MIPFILTER_LINEAR;
  91.    default:
  92.       assert(0);
  93.       return MIPFILTER_NONE;
  94.    }
  95. }
  96.  
  97.  
  98. /* None of this state is actually used for anything yet.
  99.  */
  100. static void *
  101. i915_create_blend_state(struct pipe_context *pipe,
  102.                         const struct pipe_blend_state *blend)
  103. {
  104.    struct i915_blend_state *cso_data = CALLOC_STRUCT( i915_blend_state );
  105.  
  106.    {
  107.       unsigned eqRGB  = blend->rt[0].rgb_func;
  108.       unsigned srcRGB = blend->rt[0].rgb_src_factor;
  109.       unsigned dstRGB = blend->rt[0].rgb_dst_factor;
  110.  
  111.       unsigned eqA    = blend->rt[0].alpha_func;
  112.       unsigned srcA   = blend->rt[0].alpha_src_factor;
  113.       unsigned dstA   = blend->rt[0].alpha_dst_factor;
  114.  
  115.       /* Special handling for MIN/MAX filter modes handled at
  116.        * state_tracker level.
  117.        */
  118.  
  119.       if (srcA != srcRGB ||
  120.           dstA != dstRGB ||
  121.           eqA != eqRGB) {
  122.  
  123.          cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
  124.                           IAB_MODIFY_ENABLE |
  125.                           IAB_ENABLE |
  126.                           IAB_MODIFY_FUNC |
  127.                           IAB_MODIFY_SRC_FACTOR |
  128.                           IAB_MODIFY_DST_FACTOR |
  129.                           SRC_ABLND_FACT(i915_translate_blend_factor(srcA)) |
  130.                           DST_ABLND_FACT(i915_translate_blend_factor(dstA)) |
  131.                           (i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT));
  132.       }
  133.       else {
  134.          cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
  135.                           IAB_MODIFY_ENABLE |
  136.                           0);
  137.       }
  138.    }
  139.  
  140.    cso_data->modes4 |= (_3DSTATE_MODES_4_CMD |
  141.                         ENABLE_LOGIC_OP_FUNC |
  142.                         LOGIC_OP_FUNC(i915_translate_logic_op(blend->logicop_func)));
  143.  
  144.    if (blend->logicop_enable)
  145.       cso_data->LIS5 |= S5_LOGICOP_ENABLE;
  146.  
  147.    if (blend->dither)
  148.       cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE;
  149.  
  150.    /* XXX here take the target fixup into account */
  151.    if ((blend->rt[0].colormask & PIPE_MASK_R) == 0)
  152.       cso_data->LIS5 |= S5_WRITEDISABLE_RED;
  153.  
  154.    if ((blend->rt[0].colormask & PIPE_MASK_G) == 0)
  155.       cso_data->LIS5 |= S5_WRITEDISABLE_GREEN;
  156.  
  157.    if ((blend->rt[0].colormask & PIPE_MASK_B) == 0)
  158.       cso_data->LIS5 |= S5_WRITEDISABLE_BLUE;
  159.  
  160.    if ((blend->rt[0].colormask & PIPE_MASK_A) == 0)
  161.       cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA;
  162.  
  163.    if (blend->rt[0].blend_enable) {
  164.       unsigned funcRGB = blend->rt[0].rgb_func;
  165.       unsigned srcRGB  = blend->rt[0].rgb_src_factor;
  166.       unsigned dstRGB  = blend->rt[0].rgb_dst_factor;
  167.  
  168.       cso_data->LIS6 |= (S6_CBUF_BLEND_ENABLE |
  169.                          SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) |
  170.                          DST_BLND_FACT(i915_translate_blend_factor(dstRGB)) |
  171.                          (i915_translate_blend_func(funcRGB) << S6_CBUF_BLEND_FUNC_SHIFT));
  172.    }
  173.  
  174.    return cso_data;
  175. }
  176.  
  177. static void i915_bind_blend_state(struct pipe_context *pipe,
  178.                                   void *blend)
  179. {
  180.    struct i915_context *i915 = i915_context(pipe);
  181.  
  182.    if (i915->blend == blend)
  183.       return;
  184.  
  185.    i915->blend = (struct i915_blend_state*)blend;
  186.  
  187.    i915->dirty |= I915_NEW_BLEND;
  188. }
  189.  
  190.  
  191. static void i915_delete_blend_state(struct pipe_context *pipe, void *blend)
  192. {
  193.    FREE(blend);
  194. }
  195.  
  196. static void i915_set_blend_color( struct pipe_context *pipe,
  197.                                   const struct pipe_blend_color *blend_color )
  198. {
  199.    struct i915_context *i915 = i915_context(pipe);
  200.  
  201.    if (!blend_color)
  202.       return;
  203.  
  204.    i915->blend_color = *blend_color;
  205.  
  206.    i915->dirty |= I915_NEW_BLEND;
  207. }
  208.  
  209. static void i915_set_stencil_ref( struct pipe_context *pipe,
  210.                                   const struct pipe_stencil_ref *stencil_ref )
  211. {
  212.    struct i915_context *i915 = i915_context(pipe);
  213.  
  214.    i915->stencil_ref = *stencil_ref;
  215.  
  216.    i915->dirty |= I915_NEW_DEPTH_STENCIL;
  217. }
  218.  
  219. static void *
  220. i915_create_sampler_state(struct pipe_context *pipe,
  221.                           const struct pipe_sampler_state *sampler)
  222. {
  223.    struct i915_sampler_state *cso = CALLOC_STRUCT( i915_sampler_state );
  224.    const unsigned ws = sampler->wrap_s;
  225.    const unsigned wt = sampler->wrap_t;
  226.    const unsigned wr = sampler->wrap_r;
  227.    unsigned minFilt, magFilt;
  228.    unsigned mipFilt;
  229.  
  230.    cso->templ = *sampler;
  231.  
  232.    mipFilt = translate_mip_filter(sampler->min_mip_filter);
  233.    minFilt = translate_img_filter( sampler->min_img_filter );
  234.    magFilt = translate_img_filter( sampler->mag_img_filter );
  235.  
  236.    if (sampler->max_anisotropy > 1)
  237.       minFilt = magFilt = FILTER_ANISOTROPIC;
  238.  
  239.    if (sampler->max_anisotropy > 2) {
  240.       cso->state[0] |= SS2_MAX_ANISO_4;
  241.    }
  242.  
  243.    {
  244.       int b = (int) (sampler->lod_bias * 16.0);
  245.       b = CLAMP(b, -256, 255);
  246.       cso->state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
  247.    }
  248.  
  249.    /* Shadow:
  250.     */
  251.    if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
  252.    {
  253.       cso->state[0] |= (SS2_SHADOW_ENABLE |
  254.                         i915_translate_shadow_compare_func(sampler->compare_func));
  255.  
  256.       minFilt = FILTER_4X4_FLAT;
  257.       magFilt = FILTER_4X4_FLAT;
  258.    }
  259.  
  260.    cso->state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
  261.                      (mipFilt << SS2_MIP_FILTER_SHIFT) |
  262.                      (magFilt << SS2_MAG_FILTER_SHIFT));
  263.  
  264.    cso->state[1] |=
  265.       ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
  266.        (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
  267.        (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));
  268.  
  269.    if (sampler->normalized_coords)
  270.       cso->state[1] |= SS3_NORMALIZED_COORDS;
  271.  
  272.    {
  273.       int minlod = (int) (16.0 * sampler->min_lod);
  274.       int maxlod = (int) (16.0 * sampler->max_lod);
  275.       minlod = CLAMP(minlod, 0, 16 * 11);
  276.       maxlod = CLAMP(maxlod, 0, 16 * 11);
  277.  
  278.       if (minlod > maxlod)
  279.          maxlod = minlod;
  280.  
  281.       cso->minlod = minlod;
  282.       cso->maxlod = maxlod;
  283.    }
  284.  
  285.    {
  286.       ubyte r = float_to_ubyte(sampler->border_color.f[0]);
  287.       ubyte g = float_to_ubyte(sampler->border_color.f[1]);
  288.       ubyte b = float_to_ubyte(sampler->border_color.f[2]);
  289.       ubyte a = float_to_ubyte(sampler->border_color.f[3]);
  290.       cso->state[2] = I915PACKCOLOR8888(r, g, b, a);
  291.    }
  292.    return cso;
  293. }
  294.  
  295. static void
  296. i915_bind_vertex_sampler_states(struct pipe_context *pipe,
  297.                                 unsigned num_samplers,
  298.                                 void **samplers)
  299. {
  300.    struct i915_context *i915 = i915_context(pipe);
  301.    unsigned i;
  302.  
  303.    assert(num_samplers <= Elements(i915->vertex_samplers));
  304.  
  305.    /* Check for no-op */
  306.    if (num_samplers == i915->num_vertex_samplers &&
  307.        !memcmp(i915->vertex_samplers, samplers, num_samplers * sizeof(void *)))
  308.       return;
  309.  
  310.    for (i = 0; i < num_samplers; ++i)
  311.       i915->vertex_samplers[i] = samplers[i];
  312.    for (i = num_samplers; i < Elements(i915->vertex_samplers); ++i)
  313.       i915->vertex_samplers[i] = NULL;
  314.  
  315.    i915->num_vertex_samplers = num_samplers;
  316.  
  317.    draw_set_samplers(i915->draw,
  318.                      PIPE_SHADER_VERTEX,
  319.                      i915->vertex_samplers,
  320.                      i915->num_vertex_samplers);
  321. }
  322.  
  323.  
  324.  
  325. static void i915_bind_fragment_sampler_states(struct pipe_context *pipe,
  326.                                      unsigned num, void **sampler)
  327. {
  328.    struct i915_context *i915 = i915_context(pipe);
  329.    unsigned i;
  330.  
  331.    /* Check for no-op */
  332.    if (num == i915->num_samplers &&
  333.        !memcmp(i915->sampler, sampler, num * sizeof(void *)))
  334.       return;
  335.  
  336.    for (i = 0; i < num; ++i)
  337.       i915->sampler[i] = sampler[i];
  338.    for (i = num; i < PIPE_MAX_SAMPLERS; ++i)
  339.       i915->sampler[i] = NULL;
  340.  
  341.    i915->num_samplers = num;
  342.  
  343.    i915->dirty |= I915_NEW_SAMPLER;
  344. }
  345.  
  346. static void i915_delete_sampler_state(struct pipe_context *pipe,
  347.                                       void *sampler)
  348. {
  349.    FREE(sampler);
  350. }
  351.  
  352.  
  353. /**
  354.  * Called before drawing VBO to map vertex samplers and hand them to draw
  355.  */
  356. void
  357. i915_prepare_vertex_sampling(struct i915_context *i915)
  358. {
  359.    struct i915_winsys *iws = i915->iws;
  360.    unsigned i,j;
  361.    uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
  362.    uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
  363.    uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
  364.    unsigned num = i915->num_vertex_sampler_views;
  365.    struct pipe_sampler_view **views = i915->vertex_sampler_views;
  366.  
  367.    assert(num <= PIPE_MAX_SAMPLERS);
  368.    if (!num)
  369.       return;
  370.  
  371.    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
  372.       struct pipe_sampler_view *view = i < num ? views[i] : NULL;
  373.  
  374.       if (view) {
  375.          struct pipe_resource *tex = view->texture;
  376.          struct i915_texture *i915_tex = i915_texture(tex);
  377.          ubyte *addr;
  378.  
  379.          /* We're referencing the texture's internal data, so save a
  380.           * reference to it.
  381.           */
  382.          pipe_resource_reference(&i915->mapped_vs_tex[i], tex);
  383.  
  384.          i915->mapped_vs_tex_buffer[i] = i915_tex->buffer;
  385.          addr = iws->buffer_map(iws,
  386.                                 i915_tex->buffer,
  387.                                 FALSE /* read only */);
  388.  
  389.          /* Setup array of mipmap level pointers */
  390.          /* FIXME: handle 3D textures? */
  391.          for (j = view->u.tex.first_level; j <= tex->last_level; j++) {
  392.             mip_offsets[j] = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */);
  393.             row_stride[j] = i915_tex->stride;
  394.             img_stride[j] = 0; /* FIXME */;
  395.          }
  396.  
  397.          draw_set_mapped_texture(i915->draw,
  398.                                  PIPE_SHADER_VERTEX,
  399.                                  i,
  400.                                  tex->width0, tex->height0, tex->depth0,
  401.                                  view->u.tex.first_level, tex->last_level,
  402.                                  addr,
  403.                                  row_stride, img_stride, mip_offsets);
  404.       } else
  405.          i915->mapped_vs_tex[i] = NULL;
  406.    }
  407. }
  408.  
  409. void
  410. i915_cleanup_vertex_sampling(struct i915_context *i915)
  411. {
  412.    struct i915_winsys *iws = i915->iws;
  413.    unsigned i;
  414.    for (i = 0; i < Elements(i915->mapped_vs_tex); i++) {
  415.       if (i915->mapped_vs_tex_buffer[i]) {
  416.          iws->buffer_unmap(iws, i915->mapped_vs_tex_buffer[i]);
  417.          pipe_resource_reference(&i915->mapped_vs_tex[i], NULL);
  418.       }
  419.    }
  420. }
  421.  
  422.  
  423.  
  424. /** XXX move someday?  Or consolidate all these simple state setters
  425.  * into one file.
  426.  */
  427.  
  428. static void *
  429. i915_create_depth_stencil_state(struct pipe_context *pipe,
  430.                                 const struct pipe_depth_stencil_alpha_state *depth_stencil)
  431. {
  432.    struct i915_depth_stencil_state *cso = CALLOC_STRUCT( i915_depth_stencil_state );
  433.  
  434.    {
  435.       int testmask = depth_stencil->stencil[0].valuemask & 0xff;
  436.       int writemask = depth_stencil->stencil[0].writemask & 0xff;
  437.  
  438.       cso->stencil_modes4 |= (_3DSTATE_MODES_4_CMD |
  439.                               ENABLE_STENCIL_TEST_MASK |
  440.                               STENCIL_TEST_MASK(testmask) |
  441.                               ENABLE_STENCIL_WRITE_MASK |
  442.                               STENCIL_WRITE_MASK(writemask));
  443.    }
  444.  
  445.    if (depth_stencil->stencil[0].enabled) {
  446.       int test = i915_translate_compare_func(depth_stencil->stencil[0].func);
  447.       int fop  = i915_translate_stencil_op(depth_stencil->stencil[0].fail_op);
  448.       int dfop = i915_translate_stencil_op(depth_stencil->stencil[0].zfail_op);
  449.       int dpop = i915_translate_stencil_op(depth_stencil->stencil[0].zpass_op);
  450.  
  451.       cso->stencil_LIS5 |= (S5_STENCIL_TEST_ENABLE |
  452.                             S5_STENCIL_WRITE_ENABLE |
  453.                             (test << S5_STENCIL_TEST_FUNC_SHIFT) |
  454.                             (fop  << S5_STENCIL_FAIL_SHIFT) |
  455.                             (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) |
  456.                             (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT));
  457.    }
  458.  
  459.    if (depth_stencil->stencil[1].enabled) {
  460.       int test  = i915_translate_compare_func(depth_stencil->stencil[1].func);
  461.       int fop   = i915_translate_stencil_op(depth_stencil->stencil[1].fail_op);
  462.       int dfop  = i915_translate_stencil_op(depth_stencil->stencil[1].zfail_op);
  463.       int dpop  = i915_translate_stencil_op(depth_stencil->stencil[1].zpass_op);
  464.       int tmask = depth_stencil->stencil[1].valuemask & 0xff;
  465.       int wmask = depth_stencil->stencil[1].writemask & 0xff;
  466.  
  467.       cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
  468.                      BFO_ENABLE_STENCIL_FUNCS |
  469.                      BFO_ENABLE_STENCIL_TWO_SIDE |
  470.                      BFO_ENABLE_STENCIL_REF |
  471.                      BFO_STENCIL_TWO_SIDE |
  472.                      (test << BFO_STENCIL_TEST_SHIFT) |
  473.                      (fop  << BFO_STENCIL_FAIL_SHIFT) |
  474.                      (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
  475.                      (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT));
  476.  
  477.       cso->bfo[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS |
  478.                      BFM_ENABLE_STENCIL_TEST_MASK |
  479.                      BFM_ENABLE_STENCIL_WRITE_MASK |
  480.                      (tmask << BFM_STENCIL_TEST_MASK_SHIFT) |
  481.                      (wmask << BFM_STENCIL_WRITE_MASK_SHIFT));
  482.    }
  483.    else {
  484.       /* This actually disables two-side stencil: The bit set is a
  485.        * modify-enable bit to indicate we are changing the two-side
  486.        * setting.  Then there is a symbolic zero to show that we are
  487.        * setting the flag to zero/off.
  488.        */
  489.       cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
  490.                      BFO_ENABLE_STENCIL_TWO_SIDE |
  491.                      0);
  492.       cso->bfo[1] = 0;
  493.    }
  494.  
  495.    if (depth_stencil->depth.enabled) {
  496.       int func = i915_translate_compare_func(depth_stencil->depth.func);
  497.  
  498.       cso->depth_LIS6 |= (S6_DEPTH_TEST_ENABLE |
  499.                           (func << S6_DEPTH_TEST_FUNC_SHIFT));
  500.  
  501.       if (depth_stencil->depth.writemask)
  502.          cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE;
  503.    }
  504.  
  505.    if (depth_stencil->alpha.enabled) {
  506.       int test = i915_translate_compare_func(depth_stencil->alpha.func);
  507.       ubyte refByte = float_to_ubyte(depth_stencil->alpha.ref_value);
  508.  
  509.       cso->depth_LIS6 |= (S6_ALPHA_TEST_ENABLE |
  510.                           (test << S6_ALPHA_TEST_FUNC_SHIFT) |
  511.                           (((unsigned) refByte) << S6_ALPHA_REF_SHIFT));
  512.    }
  513.  
  514.    return cso;
  515. }
  516.  
  517. static void i915_bind_depth_stencil_state(struct pipe_context *pipe,
  518.                                           void *depth_stencil)
  519. {
  520.    struct i915_context *i915 = i915_context(pipe);
  521.  
  522.    if (i915->depth_stencil == depth_stencil)
  523.       return;
  524.  
  525.    i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil;
  526.  
  527.    i915->dirty |= I915_NEW_DEPTH_STENCIL;
  528. }
  529.  
  530. static void i915_delete_depth_stencil_state(struct pipe_context *pipe,
  531.                                             void *depth_stencil)
  532. {
  533.    FREE(depth_stencil);
  534. }
  535.  
  536.  
  537. static void i915_set_scissor_states( struct pipe_context *pipe,
  538.                                      unsigned start_slot,
  539.                                      unsigned num_scissors,
  540.                                  const struct pipe_scissor_state *scissor )
  541. {
  542.    struct i915_context *i915 = i915_context(pipe);
  543.  
  544.    memcpy( &i915->scissor, scissor, sizeof(*scissor) );
  545.    i915->dirty |= I915_NEW_SCISSOR;
  546. }
  547.  
  548.  
  549. static void i915_set_polygon_stipple( struct pipe_context *pipe,
  550.                                    const struct pipe_poly_stipple *stipple )
  551. {
  552. }
  553.  
  554.  
  555.  
  556. static void *
  557. i915_create_fs_state(struct pipe_context *pipe,
  558.                      const struct pipe_shader_state *templ)
  559. {
  560.    struct i915_context *i915 = i915_context(pipe);
  561.    struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader);
  562.    if (!ifs)
  563.       return NULL;
  564.  
  565.    ifs->draw_data = draw_create_fragment_shader(i915->draw, templ);
  566.    ifs->state.tokens = tgsi_dup_tokens(templ->tokens);
  567.  
  568.    tgsi_scan_shader(templ->tokens, &ifs->info);
  569.  
  570.    /* The shader's compiled to i915 instructions here */
  571.    i915_translate_fragment_program(i915, ifs);
  572.  
  573.    return ifs;
  574. }
  575.  
  576. static void
  577. i915_bind_fs_state(struct pipe_context *pipe, void *shader)
  578. {
  579.    struct i915_context *i915 = i915_context(pipe);
  580.  
  581.    if (i915->fs == shader)
  582.       return;
  583.  
  584.    i915->fs = (struct i915_fragment_shader*) shader;
  585.  
  586.    draw_bind_fragment_shader(i915->draw,  (i915->fs ? i915->fs->draw_data : NULL));
  587.  
  588.    i915->dirty |= I915_NEW_FS;
  589. }
  590.  
  591. static
  592. void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
  593. {
  594.    struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader;
  595.  
  596.    FREE(ifs->decl);
  597.    ifs->decl = NULL;
  598.  
  599.    if (ifs->program) {
  600.       FREE(ifs->program);
  601.       ifs->program = NULL;
  602.       FREE((struct tgsi_token *)ifs->state.tokens);
  603.       ifs->state.tokens = NULL;
  604.    }
  605.  
  606.    ifs->program_len = 0;
  607.    ifs->decl_len = 0;
  608.  
  609.    FREE(ifs);
  610. }
  611.  
  612.  
  613. static void *
  614. i915_create_vs_state(struct pipe_context *pipe,
  615.                      const struct pipe_shader_state *templ)
  616. {
  617.    struct i915_context *i915 = i915_context(pipe);
  618.  
  619.    /* just pass-through to draw module */
  620.    return draw_create_vertex_shader(i915->draw, templ);
  621. }
  622.  
  623. static void i915_bind_vs_state(struct pipe_context *pipe, void *shader)
  624. {
  625.    struct i915_context *i915 = i915_context(pipe);
  626.  
  627.    if (i915->vs == shader)
  628.       return;
  629.  
  630.    i915->vs = shader;
  631.  
  632.    /* just pass-through to draw module */
  633.    draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader);
  634.  
  635.    i915->dirty |= I915_NEW_VS;
  636. }
  637.  
  638. static void i915_delete_vs_state(struct pipe_context *pipe, void *shader)
  639. {
  640.    struct i915_context *i915 = i915_context(pipe);
  641.  
  642.    /* just pass-through to draw module */
  643.    draw_delete_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader);
  644. }
  645.  
  646. static void i915_set_constant_buffer(struct pipe_context *pipe,
  647.                                      uint shader, uint index,
  648.                                      struct pipe_constant_buffer *cb)
  649. {
  650.    struct i915_context *i915 = i915_context(pipe);
  651.    struct pipe_resource *buf = cb ? cb->buffer : NULL;
  652.    unsigned new_num = 0;
  653.    boolean diff = TRUE;
  654.  
  655.    /* XXX don't support geom shaders now */
  656.    if (shader == PIPE_SHADER_GEOMETRY)
  657.       return;
  658.  
  659.    if (cb && cb->user_buffer) {
  660.       buf = i915_user_buffer_create(pipe->screen, (void *) cb->user_buffer,
  661.                                     cb->buffer_size,
  662.                                     PIPE_BIND_CONSTANT_BUFFER);
  663.    }
  664.  
  665.    /* if we have a new buffer compare it with the old one */
  666.    if (buf) {
  667.       struct i915_buffer *ibuf = i915_buffer(buf);
  668.       struct pipe_resource *old_buf = i915->constants[shader];
  669.       struct i915_buffer *old = old_buf ? i915_buffer(old_buf) : NULL;
  670.       unsigned old_num = i915->current.num_user_constants[shader];
  671.  
  672.       new_num = ibuf->b.b.width0 / 4 * sizeof(float);
  673.  
  674.       if (old_num == new_num) {
  675.          if (old_num == 0)
  676.             diff = FALSE;
  677. #if 0
  678.          /* XXX no point in running this code since st/mesa only uses user buffers */
  679.          /* Can't compare the buffer data since they are userbuffers */
  680.          else if (old && old->free_on_destroy)
  681.             diff = memcmp(old->data, ibuf->data, ibuf->b.b.width0);
  682. #else
  683.          (void)old;
  684. #endif
  685.       }
  686.    } else {
  687.       diff = i915->current.num_user_constants[shader] != 0;
  688.    }
  689.  
  690.    pipe_resource_reference(&i915->constants[shader], buf);
  691.    i915->current.num_user_constants[shader] = new_num;
  692.  
  693.    if (diff)
  694.       i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS;
  695.  
  696.    if (cb && cb->user_buffer) {
  697.       pipe_resource_reference(&buf, NULL);
  698.    }
  699. }
  700.  
  701.  
  702. static void i915_set_fragment_sampler_views(struct pipe_context *pipe,
  703.                                             unsigned num,
  704.                                             struct pipe_sampler_view **views)
  705. {
  706.    struct i915_context *i915 = i915_context(pipe);
  707.    uint i;
  708.  
  709.    assert(num <= PIPE_MAX_SAMPLERS);
  710.  
  711.    /* Check for no-op */
  712.    if (num == i915->num_fragment_sampler_views &&
  713.        !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
  714.       return;
  715.  
  716.    for (i = 0; i < num; i++) {
  717.       /* Note: we're using pipe_sampler_view_release() here to work around
  718.        * a possible crash when the old view belongs to another context that
  719.        * was already destroyed.
  720.        */
  721.       pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]);
  722.       pipe_sampler_view_reference(&i915->fragment_sampler_views[i],
  723.                                   views[i]);
  724.    }
  725.  
  726.    for (i = num; i < i915->num_fragment_sampler_views; i++)
  727.       pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]);
  728.  
  729.    i915->num_fragment_sampler_views = num;
  730.  
  731.    i915->dirty |= I915_NEW_SAMPLER_VIEW;
  732. }
  733.  
  734. static void
  735. i915_set_vertex_sampler_views(struct pipe_context *pipe,
  736.                               unsigned num,
  737.                               struct pipe_sampler_view **views)
  738. {
  739.    struct i915_context *i915 = i915_context(pipe);
  740.    uint i;
  741.  
  742.    assert(num <= Elements(i915->vertex_sampler_views));
  743.  
  744.    /* Check for no-op */
  745.    if (num == i915->num_vertex_sampler_views &&
  746.        !memcmp(i915->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
  747.       return;
  748.    }
  749.  
  750.    for (i = 0; i < Elements(i915->vertex_sampler_views); i++) {
  751.       struct pipe_sampler_view *view = i < num ? views[i] : NULL;
  752.  
  753.       pipe_sampler_view_reference(&i915->vertex_sampler_views[i], view);
  754.    }
  755.  
  756.    i915->num_vertex_sampler_views = num;
  757.  
  758.    draw_set_sampler_views(i915->draw,
  759.                           PIPE_SHADER_VERTEX,
  760.                           i915->vertex_sampler_views,
  761.                           i915->num_vertex_sampler_views);
  762. }
  763.  
  764.  
  765. static struct pipe_sampler_view *
  766. i915_create_sampler_view(struct pipe_context *pipe,
  767.                          struct pipe_resource *texture,
  768.                          const struct pipe_sampler_view *templ)
  769. {
  770.    struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
  771.  
  772.    if (view) {
  773.       *view = *templ;
  774.       view->reference.count = 1;
  775.       view->texture = NULL;
  776.       pipe_resource_reference(&view->texture, texture);
  777.       view->context = pipe;
  778.    }
  779.  
  780.    return view;
  781. }
  782.  
  783.  
  784. static void
  785. i915_sampler_view_destroy(struct pipe_context *pipe,
  786.                           struct pipe_sampler_view *view)
  787. {
  788.    pipe_resource_reference(&view->texture, NULL);
  789.    FREE(view);
  790. }
  791.  
  792.  
  793. static void i915_set_framebuffer_state(struct pipe_context *pipe,
  794.                                        const struct pipe_framebuffer_state *fb)
  795. {
  796.    struct i915_context *i915 = i915_context(pipe);
  797.    int i;
  798.  
  799.    i915->framebuffer.width = fb->width;
  800.    i915->framebuffer.height = fb->height;
  801.    i915->framebuffer.nr_cbufs = fb->nr_cbufs;
  802.    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
  803.       pipe_surface_reference(&i915->framebuffer.cbufs[i],
  804.                              i < fb->nr_cbufs ? fb->cbufs[i] : NULL);
  805.    }
  806.    pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf);
  807.  
  808.    i915->dirty |= I915_NEW_FRAMEBUFFER;
  809. }
  810.  
  811.  
  812.  
  813. static void i915_set_clip_state( struct pipe_context *pipe,
  814.                              const struct pipe_clip_state *clip )
  815. {
  816.    struct i915_context *i915 = i915_context(pipe);
  817.  
  818.    i915->clip = *clip;
  819.  
  820.    draw_set_clip_state(i915->draw, clip);
  821.  
  822.    i915->dirty |= I915_NEW_CLIP;
  823. }
  824.  
  825.  
  826.  
  827. /* Called when driver state tracker notices changes to the viewport
  828.  * matrix:
  829.  */
  830. static void i915_set_viewport_states( struct pipe_context *pipe,
  831.                                       unsigned start_slot,
  832.                                       unsigned num_viewports,
  833.                                      const struct pipe_viewport_state *viewport )
  834. {
  835.    struct i915_context *i915 = i915_context(pipe);
  836.  
  837.    i915->viewport = *viewport; /* struct copy */
  838.  
  839.    /* pass the viewport info to the draw module */
  840.    draw_set_viewport_states(i915->draw, start_slot, num_viewports,
  841.                             &i915->viewport);
  842.  
  843.    i915->dirty |= I915_NEW_VIEWPORT;
  844. }
  845.  
  846.  
  847. static void *
  848. i915_create_rasterizer_state(struct pipe_context *pipe,
  849.                              const struct pipe_rasterizer_state *rasterizer)
  850. {
  851.    struct i915_rasterizer_state *cso = CALLOC_STRUCT( i915_rasterizer_state );
  852.  
  853.    cso->templ = *rasterizer;
  854.    cso->color_interp = rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
  855.    cso->light_twoside = rasterizer->light_twoside;
  856.    cso->ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE;
  857.    cso->ds[1].f = rasterizer->offset_scale;
  858.    if (rasterizer->poly_stipple_enable) {
  859.       cso->st |= ST1_ENABLE;
  860.    }
  861.  
  862.    if (rasterizer->scissor)
  863.       cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT;
  864.    else
  865.       cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT;
  866.  
  867.    switch (rasterizer->cull_face) {
  868.    case PIPE_FACE_NONE:
  869.       cso->LIS4 |= S4_CULLMODE_NONE;
  870.       break;
  871.    case PIPE_FACE_FRONT:
  872.       if (rasterizer->front_ccw)
  873.          cso->LIS4 |= S4_CULLMODE_CCW;
  874.       else
  875.          cso->LIS4 |= S4_CULLMODE_CW;
  876.       break;
  877.    case PIPE_FACE_BACK:
  878.       if (rasterizer->front_ccw)
  879.          cso->LIS4 |= S4_CULLMODE_CW;
  880.       else
  881.          cso->LIS4 |= S4_CULLMODE_CCW;
  882.       break;
  883.    case PIPE_FACE_FRONT_AND_BACK:
  884.       cso->LIS4 |= S4_CULLMODE_BOTH;
  885.       break;
  886.    }
  887.  
  888.    {
  889.       int line_width = CLAMP((int)(rasterizer->line_width * 2), 1, 0xf);
  890.  
  891.       cso->LIS4 |= line_width << S4_LINE_WIDTH_SHIFT;
  892.  
  893.       if (rasterizer->line_smooth)
  894.          cso->LIS4 |= S4_LINE_ANTIALIAS_ENABLE;
  895.    }
  896.  
  897.    {
  898.       int point_size = CLAMP((int) rasterizer->point_size, 1, 0xff);
  899.  
  900.       cso->LIS4 |= point_size << S4_POINT_WIDTH_SHIFT;
  901.    }
  902.  
  903.    if (rasterizer->flatshade) {
  904.       cso->LIS4 |= (S4_FLATSHADE_ALPHA |
  905.                     S4_FLATSHADE_COLOR |
  906.                     S4_FLATSHADE_SPECULAR);
  907.    }
  908.  
  909.    cso->LIS7 = fui( rasterizer->offset_units );
  910.  
  911.  
  912.    return cso;
  913. }
  914.  
  915. static void i915_bind_rasterizer_state( struct pipe_context *pipe,
  916.                                         void *raster )
  917. {
  918.    struct i915_context *i915 = i915_context(pipe);
  919.  
  920.    if (i915->rasterizer == raster)
  921.       return;
  922.  
  923.    i915->rasterizer = (struct i915_rasterizer_state *)raster;
  924.  
  925.    /* pass-through to draw module */
  926.    draw_set_rasterizer_state(i915->draw,
  927.                            (i915->rasterizer ? &(i915->rasterizer->templ) : NULL),
  928.                            raster);
  929.  
  930.    i915->dirty |= I915_NEW_RASTERIZER;
  931. }
  932.  
  933. static void i915_delete_rasterizer_state(struct pipe_context *pipe,
  934.                                          void *raster)
  935. {
  936.    FREE(raster);
  937. }
  938.  
  939. static void i915_set_vertex_buffers(struct pipe_context *pipe,
  940.                                     unsigned start_slot, unsigned count,
  941.                                     const struct pipe_vertex_buffer *buffers)
  942. {
  943.    struct i915_context *i915 = i915_context(pipe);
  944.    struct draw_context *draw = i915->draw;
  945.  
  946.    util_set_vertex_buffers_count(i915->vertex_buffers,
  947.                                  &i915->nr_vertex_buffers,
  948.                                  buffers, start_slot, count);
  949.  
  950.    /* pass-through to draw module */
  951.    draw_set_vertex_buffers(draw, start_slot, count, buffers);
  952. }
  953.  
  954. static void *
  955. i915_create_vertex_elements_state(struct pipe_context *pipe,
  956.                                   unsigned count,
  957.                                   const struct pipe_vertex_element *attribs)
  958. {
  959.    struct i915_velems_state *velems;
  960.    assert(count <= PIPE_MAX_ATTRIBS);
  961.    velems = (struct i915_velems_state *) MALLOC(sizeof(struct i915_velems_state));
  962.    if (velems) {
  963.       velems->count = count;
  964.       memcpy(velems->velem, attribs, sizeof(*attribs) * count);
  965.    }
  966.    return velems;
  967. }
  968.  
  969. static void
  970. i915_bind_vertex_elements_state(struct pipe_context *pipe,
  971.                                 void *velems)
  972. {
  973.    struct i915_context *i915 = i915_context(pipe);
  974.    struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems;
  975.  
  976.    if (i915->velems == velems)
  977.       return;
  978.  
  979.    i915->velems = velems;
  980.  
  981.    /* pass-through to draw module */
  982.    if (i915_velems) {
  983.       draw_set_vertex_elements(i915->draw,
  984.             i915_velems->count, i915_velems->velem);
  985.    }
  986. }
  987.  
  988. static void
  989. i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
  990. {
  991.    FREE( velems );
  992. }
  993.  
  994. static void i915_set_index_buffer(struct pipe_context *pipe,
  995.                                   const struct pipe_index_buffer *ib)
  996. {
  997.    struct i915_context *i915 = i915_context(pipe);
  998.  
  999.    if (ib)
  1000.       memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer));
  1001.    else
  1002.       memset(&i915->index_buffer, 0, sizeof(i915->index_buffer));
  1003. }
  1004.  
  1005. static void
  1006. i915_set_sample_mask(struct pipe_context *pipe,
  1007.                      unsigned sample_mask)
  1008. {
  1009. }
  1010.  
  1011. void
  1012. i915_init_state_functions( struct i915_context *i915 )
  1013. {
  1014.    i915->base.create_blend_state = i915_create_blend_state;
  1015.    i915->base.bind_blend_state = i915_bind_blend_state;
  1016.    i915->base.delete_blend_state = i915_delete_blend_state;
  1017.  
  1018.    i915->base.create_sampler_state = i915_create_sampler_state;
  1019.    i915->base.bind_fragment_sampler_states = i915_bind_fragment_sampler_states;
  1020.    i915->base.bind_vertex_sampler_states = i915_bind_vertex_sampler_states;
  1021.    i915->base.delete_sampler_state = i915_delete_sampler_state;
  1022.  
  1023.    i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
  1024.    i915->base.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state;
  1025.    i915->base.delete_depth_stencil_alpha_state = i915_delete_depth_stencil_state;
  1026.  
  1027.    i915->base.create_rasterizer_state = i915_create_rasterizer_state;
  1028.    i915->base.bind_rasterizer_state = i915_bind_rasterizer_state;
  1029.    i915->base.delete_rasterizer_state = i915_delete_rasterizer_state;
  1030.    i915->base.create_fs_state = i915_create_fs_state;
  1031.    i915->base.bind_fs_state = i915_bind_fs_state;
  1032.    i915->base.delete_fs_state = i915_delete_fs_state;
  1033.    i915->base.create_vs_state = i915_create_vs_state;
  1034.    i915->base.bind_vs_state = i915_bind_vs_state;
  1035.    i915->base.delete_vs_state = i915_delete_vs_state;
  1036.    i915->base.create_vertex_elements_state = i915_create_vertex_elements_state;
  1037.    i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state;
  1038.    i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state;
  1039.  
  1040.    i915->base.set_blend_color = i915_set_blend_color;
  1041.    i915->base.set_stencil_ref = i915_set_stencil_ref;
  1042.    i915->base.set_clip_state = i915_set_clip_state;
  1043.    i915->base.set_sample_mask = i915_set_sample_mask;
  1044.    i915->base.set_constant_buffer = i915_set_constant_buffer;
  1045.    i915->base.set_framebuffer_state = i915_set_framebuffer_state;
  1046.  
  1047.    i915->base.set_polygon_stipple = i915_set_polygon_stipple;
  1048.    i915->base.set_scissor_states = i915_set_scissor_states;
  1049.    i915->base.set_fragment_sampler_views = i915_set_fragment_sampler_views;
  1050.    i915->base.set_vertex_sampler_views = i915_set_vertex_sampler_views;
  1051.    i915->base.create_sampler_view = i915_create_sampler_view;
  1052.    i915->base.sampler_view_destroy = i915_sampler_view_destroy;
  1053.    i915->base.set_viewport_states = i915_set_viewport_states;
  1054.    i915->base.set_vertex_buffers = i915_set_vertex_buffers;
  1055.    i915->base.set_index_buffer = i915_set_index_buffer;
  1056. }
  1057.