Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /* Authors:  Keith Whitwell <keithw@vmware.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. #include "i915_state.h"
  46.  
  47. /* The i915 (and related graphics cores) do not support GL_CLAMP.  The
  48.  * Intel drivers for "other operating systems" implement GL_CLAMP as
  49.  * GL_CLAMP_TO_EDGE, so the same is done here.
  50.  */
  51. static unsigned
  52. translate_wrap_mode(unsigned wrap)
  53. {
  54.    switch (wrap) {
  55.    case PIPE_TEX_WRAP_REPEAT:
  56.       return TEXCOORDMODE_WRAP;
  57.    case PIPE_TEX_WRAP_CLAMP:
  58.       return TEXCOORDMODE_CLAMP_EDGE;   /* not quite correct */
  59.    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
  60.       return TEXCOORDMODE_CLAMP_EDGE;
  61.    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
  62.       return TEXCOORDMODE_CLAMP_BORDER;
  63.    case PIPE_TEX_WRAP_MIRROR_REPEAT:
  64.       return TEXCOORDMODE_MIRROR;
  65.    default:
  66.       return TEXCOORDMODE_WRAP;
  67.    }
  68. }
  69.  
  70. static unsigned translate_img_filter( unsigned filter )
  71. {
  72.    switch (filter) {
  73.    case PIPE_TEX_FILTER_NEAREST:
  74.       return FILTER_NEAREST;
  75.    case PIPE_TEX_FILTER_LINEAR:
  76.       return FILTER_LINEAR;
  77.    default:
  78.       assert(0);
  79.       return FILTER_NEAREST;
  80.    }
  81. }
  82.  
  83. static unsigned translate_mip_filter( unsigned filter )
  84. {
  85.    switch (filter) {
  86.    case PIPE_TEX_MIPFILTER_NONE:
  87.       return MIPFILTER_NONE;
  88.    case PIPE_TEX_MIPFILTER_NEAREST:
  89.       return MIPFILTER_NEAREST;
  90.    case PIPE_TEX_MIPFILTER_LINEAR:
  91.       return MIPFILTER_LINEAR;
  92.    default:
  93.       assert(0);
  94.       return MIPFILTER_NONE;
  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.    /* We potentially do some fixup at emission for non-BGRA targets */
  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 start,
  298.                                 unsigned num,
  299.                                 void **samplers)
  300. {
  301.    struct i915_context *i915 = i915_context(pipe);
  302.    unsigned i;
  303.  
  304.    assert(start + num <= Elements(i915->vertex_samplers));
  305.  
  306.    /* Check for no-op */
  307.    if (num == i915->num_vertex_samplers &&
  308.        !memcmp(i915->vertex_samplers + start, samplers,
  309.                num * sizeof(void *)))
  310.       return;
  311.  
  312.    for (i = 0; i < num; ++i)
  313.       i915->vertex_samplers[i + start] = samplers[i];
  314.  
  315.    /* find highest non-null samplers[] entry */
  316.    {
  317.       unsigned j = MAX2(i915->num_vertex_samplers, start + num);
  318.       while (j > 0 && i915->vertex_samplers[j - 1] == NULL)
  319.          j--;
  320.       i915->num_vertex_samplers = j;
  321.    }
  322.  
  323.    draw_set_samplers(i915->draw,
  324.                      PIPE_SHADER_VERTEX,
  325.                      i915->vertex_samplers,
  326.                      i915->num_vertex_samplers);
  327. }
  328.  
  329.  
  330.  
  331. static void i915_bind_fragment_sampler_states(struct pipe_context *pipe,
  332.                                               unsigned start,
  333.                                               unsigned num,
  334.                                               void **samplers)
  335. {
  336.    struct i915_context *i915 = i915_context(pipe);
  337.    unsigned i;
  338.  
  339.    /* Check for no-op */
  340.    if (num == i915->num_samplers &&
  341.        !memcmp(i915->fragment_sampler + start, samplers,
  342.                num * sizeof(void *)))
  343.       return;
  344.  
  345.    for (i = 0; i < num; ++i)
  346.       i915->fragment_sampler[i + start] = samplers[i];
  347.  
  348.    /* find highest non-null samplers[] entry */
  349.    {
  350.       unsigned j = MAX2(i915->num_samplers, start + num);
  351.       while (j > 0 && i915->fragment_sampler[j - 1] == NULL)
  352.          j--;
  353.       i915->num_samplers = j;
  354.    }
  355.  
  356.    i915->dirty |= I915_NEW_SAMPLER;
  357. }
  358.  
  359.  
  360. static void
  361. i915_bind_sampler_states(struct pipe_context *pipe, unsigned shader,
  362.                          unsigned start, unsigned num_samplers,
  363.                          void **samplers)
  364. {
  365.    switch (shader) {
  366.    case PIPE_SHADER_VERTEX:
  367.       i915_bind_vertex_sampler_states(pipe, start, num_samplers, samplers);
  368.       break;
  369.    case PIPE_SHADER_FRAGMENT:
  370.       i915_bind_fragment_sampler_states(pipe, start, num_samplers, samplers);
  371.       break;
  372.    default:
  373.       ;
  374.    }
  375. }
  376.  
  377.  
  378. static void i915_delete_sampler_state(struct pipe_context *pipe,
  379.                                       void *sampler)
  380. {
  381.    FREE(sampler);
  382. }
  383.  
  384.  
  385. /**
  386.  * Called before drawing VBO to map vertex samplers and hand them to draw
  387.  */
  388. void
  389. i915_prepare_vertex_sampling(struct i915_context *i915)
  390. {
  391.    struct i915_winsys *iws = i915->iws;
  392.    unsigned i,j;
  393.    uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
  394.    uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
  395.    uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
  396.    unsigned num = i915->num_vertex_sampler_views;
  397.    struct pipe_sampler_view **views = i915->vertex_sampler_views;
  398.  
  399.    assert(num <= PIPE_MAX_SAMPLERS);
  400.    if (!num)
  401.       return;
  402.  
  403.    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
  404.       struct pipe_sampler_view *view = i < num ? views[i] : NULL;
  405.  
  406.       if (view) {
  407.          struct pipe_resource *tex = view->texture;
  408.          struct i915_texture *i915_tex = i915_texture(tex);
  409.          ubyte *addr;
  410.  
  411.          /* We're referencing the texture's internal data, so save a
  412.           * reference to it.
  413.           */
  414.          pipe_resource_reference(&i915->mapped_vs_tex[i], tex);
  415.  
  416.          i915->mapped_vs_tex_buffer[i] = i915_tex->buffer;
  417.          addr = iws->buffer_map(iws,
  418.                                 i915_tex->buffer,
  419.                                 FALSE /* read only */);
  420.  
  421.          /* Setup array of mipmap level pointers */
  422.          /* FIXME: handle 3D textures? */
  423.          for (j = view->u.tex.first_level; j <= tex->last_level; j++) {
  424.             mip_offsets[j] = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */);
  425.             row_stride[j] = i915_tex->stride;
  426.             img_stride[j] = 0; /* FIXME */;
  427.          }
  428.  
  429.          draw_set_mapped_texture(i915->draw,
  430.                                  PIPE_SHADER_VERTEX,
  431.                                  i,
  432.                                  tex->width0, tex->height0, tex->depth0,
  433.                                  view->u.tex.first_level, tex->last_level,
  434.                                  addr,
  435.                                  row_stride, img_stride, mip_offsets);
  436.       } else
  437.          i915->mapped_vs_tex[i] = NULL;
  438.    }
  439. }
  440.  
  441. void
  442. i915_cleanup_vertex_sampling(struct i915_context *i915)
  443. {
  444.    struct i915_winsys *iws = i915->iws;
  445.    unsigned i;
  446.    for (i = 0; i < Elements(i915->mapped_vs_tex); i++) {
  447.       if (i915->mapped_vs_tex_buffer[i]) {
  448.          iws->buffer_unmap(iws, i915->mapped_vs_tex_buffer[i]);
  449.          pipe_resource_reference(&i915->mapped_vs_tex[i], NULL);
  450.       }
  451.    }
  452. }
  453.  
  454.  
  455.  
  456. /** XXX move someday?  Or consolidate all these simple state setters
  457.  * into one file.
  458.  */
  459.  
  460. static void *
  461. i915_create_depth_stencil_state(struct pipe_context *pipe,
  462.                                 const struct pipe_depth_stencil_alpha_state *depth_stencil)
  463. {
  464.    struct i915_depth_stencil_state *cso = CALLOC_STRUCT( i915_depth_stencil_state );
  465.  
  466.    {
  467.       int testmask = depth_stencil->stencil[0].valuemask & 0xff;
  468.       int writemask = depth_stencil->stencil[0].writemask & 0xff;
  469.  
  470.       cso->stencil_modes4 |= (_3DSTATE_MODES_4_CMD |
  471.                               ENABLE_STENCIL_TEST_MASK |
  472.                               STENCIL_TEST_MASK(testmask) |
  473.                               ENABLE_STENCIL_WRITE_MASK |
  474.                               STENCIL_WRITE_MASK(writemask));
  475.    }
  476.  
  477.    if (depth_stencil->stencil[0].enabled) {
  478.       int test = i915_translate_compare_func(depth_stencil->stencil[0].func);
  479.       int fop  = i915_translate_stencil_op(depth_stencil->stencil[0].fail_op);
  480.       int dfop = i915_translate_stencil_op(depth_stencil->stencil[0].zfail_op);
  481.       int dpop = i915_translate_stencil_op(depth_stencil->stencil[0].zpass_op);
  482.  
  483.       cso->stencil_LIS5 |= (S5_STENCIL_TEST_ENABLE |
  484.                             S5_STENCIL_WRITE_ENABLE |
  485.                             (test << S5_STENCIL_TEST_FUNC_SHIFT) |
  486.                             (fop  << S5_STENCIL_FAIL_SHIFT) |
  487.                             (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) |
  488.                             (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT));
  489.    }
  490.  
  491.    if (depth_stencil->stencil[1].enabled) {
  492.       int test  = i915_translate_compare_func(depth_stencil->stencil[1].func);
  493.       int fop   = i915_translate_stencil_op(depth_stencil->stencil[1].fail_op);
  494.       int dfop  = i915_translate_stencil_op(depth_stencil->stencil[1].zfail_op);
  495.       int dpop  = i915_translate_stencil_op(depth_stencil->stencil[1].zpass_op);
  496.       int tmask = depth_stencil->stencil[1].valuemask & 0xff;
  497.       int wmask = depth_stencil->stencil[1].writemask & 0xff;
  498.  
  499.       cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
  500.                      BFO_ENABLE_STENCIL_FUNCS |
  501.                      BFO_ENABLE_STENCIL_TWO_SIDE |
  502.                      BFO_ENABLE_STENCIL_REF |
  503.                      BFO_STENCIL_TWO_SIDE |
  504.                      (test << BFO_STENCIL_TEST_SHIFT) |
  505.                      (fop  << BFO_STENCIL_FAIL_SHIFT) |
  506.                      (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
  507.                      (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT));
  508.  
  509.       cso->bfo[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS |
  510.                      BFM_ENABLE_STENCIL_TEST_MASK |
  511.                      BFM_ENABLE_STENCIL_WRITE_MASK |
  512.                      (tmask << BFM_STENCIL_TEST_MASK_SHIFT) |
  513.                      (wmask << BFM_STENCIL_WRITE_MASK_SHIFT));
  514.    }
  515.    else {
  516.       /* This actually disables two-side stencil: The bit set is a
  517.        * modify-enable bit to indicate we are changing the two-side
  518.        * setting.  Then there is a symbolic zero to show that we are
  519.        * setting the flag to zero/off.
  520.        */
  521.       cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
  522.                      BFO_ENABLE_STENCIL_TWO_SIDE |
  523.                      0);
  524.       cso->bfo[1] = 0;
  525.    }
  526.  
  527.    if (depth_stencil->depth.enabled) {
  528.       int func = i915_translate_compare_func(depth_stencil->depth.func);
  529.  
  530.       cso->depth_LIS6 |= (S6_DEPTH_TEST_ENABLE |
  531.                           (func << S6_DEPTH_TEST_FUNC_SHIFT));
  532.  
  533.       if (depth_stencil->depth.writemask)
  534.          cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE;
  535.    }
  536.  
  537.    if (depth_stencil->alpha.enabled) {
  538.       int test = i915_translate_compare_func(depth_stencil->alpha.func);
  539.       ubyte refByte = float_to_ubyte(depth_stencil->alpha.ref_value);
  540.  
  541.       cso->depth_LIS6 |= (S6_ALPHA_TEST_ENABLE |
  542.                           (test << S6_ALPHA_TEST_FUNC_SHIFT) |
  543.                           (((unsigned) refByte) << S6_ALPHA_REF_SHIFT));
  544.    }
  545.  
  546.    return cso;
  547. }
  548.  
  549. static void i915_bind_depth_stencil_state(struct pipe_context *pipe,
  550.                                           void *depth_stencil)
  551. {
  552.    struct i915_context *i915 = i915_context(pipe);
  553.  
  554.    if (i915->depth_stencil == depth_stencil)
  555.       return;
  556.  
  557.    i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil;
  558.  
  559.    i915->dirty |= I915_NEW_DEPTH_STENCIL;
  560. }
  561.  
  562. static void i915_delete_depth_stencil_state(struct pipe_context *pipe,
  563.                                             void *depth_stencil)
  564. {
  565.    FREE(depth_stencil);
  566. }
  567.  
  568.  
  569. static void i915_set_scissor_states( struct pipe_context *pipe,
  570.                                      unsigned start_slot,
  571.                                      unsigned num_scissors,
  572.                                  const struct pipe_scissor_state *scissor )
  573. {
  574.    struct i915_context *i915 = i915_context(pipe);
  575.  
  576.    memcpy( &i915->scissor, scissor, sizeof(*scissor) );
  577.    i915->dirty |= I915_NEW_SCISSOR;
  578. }
  579.  
  580.  
  581. static void i915_set_polygon_stipple( struct pipe_context *pipe,
  582.                                    const struct pipe_poly_stipple *stipple )
  583. {
  584. }
  585.  
  586.  
  587.  
  588. static void *
  589. i915_create_fs_state(struct pipe_context *pipe,
  590.                      const struct pipe_shader_state *templ)
  591. {
  592.    struct i915_context *i915 = i915_context(pipe);
  593.    struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader);
  594.    if (!ifs)
  595.       return NULL;
  596.  
  597.    ifs->draw_data = draw_create_fragment_shader(i915->draw, templ);
  598.    ifs->state.tokens = tgsi_dup_tokens(templ->tokens);
  599.  
  600.    tgsi_scan_shader(templ->tokens, &ifs->info);
  601.  
  602.    /* The shader's compiled to i915 instructions here */
  603.    i915_translate_fragment_program(i915, ifs);
  604.  
  605.    return ifs;
  606. }
  607.  
  608. static void
  609. i915_bind_fs_state(struct pipe_context *pipe, void *shader)
  610. {
  611.    struct i915_context *i915 = i915_context(pipe);
  612.  
  613.    if (i915->fs == shader)
  614.       return;
  615.  
  616.    i915->fs = (struct i915_fragment_shader*) shader;
  617.  
  618.    draw_bind_fragment_shader(i915->draw,  (i915->fs ? i915->fs->draw_data : NULL));
  619.  
  620.    i915->dirty |= I915_NEW_FS;
  621. }
  622.  
  623. static
  624. void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
  625. {
  626.    struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader;
  627.  
  628.    FREE(ifs->decl);
  629.    ifs->decl = NULL;
  630.  
  631.    FREE(ifs->program);
  632.    ifs->program = NULL;
  633.    FREE((struct tgsi_token *)ifs->state.tokens);
  634.    ifs->state.tokens = NULL;
  635.  
  636.    ifs->program_len = 0;
  637.    ifs->decl_len = 0;
  638.  
  639.    FREE(ifs);
  640. }
  641.  
  642.  
  643. static void *
  644. i915_create_vs_state(struct pipe_context *pipe,
  645.                      const struct pipe_shader_state *templ)
  646. {
  647.    struct i915_context *i915 = i915_context(pipe);
  648.  
  649.    /* just pass-through to draw module */
  650.    return draw_create_vertex_shader(i915->draw, templ);
  651. }
  652.  
  653. static void i915_bind_vs_state(struct pipe_context *pipe, void *shader)
  654. {
  655.    struct i915_context *i915 = i915_context(pipe);
  656.  
  657.    if (i915->vs == shader)
  658.       return;
  659.  
  660.    i915->vs = shader;
  661.  
  662.    /* just pass-through to draw module */
  663.    draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader);
  664.  
  665.    i915->dirty |= I915_NEW_VS;
  666. }
  667.  
  668. static void i915_delete_vs_state(struct pipe_context *pipe, void *shader)
  669. {
  670.    struct i915_context *i915 = i915_context(pipe);
  671.  
  672.    /* just pass-through to draw module */
  673.    draw_delete_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader);
  674. }
  675.  
  676. static void i915_set_constant_buffer(struct pipe_context *pipe,
  677.                                      uint shader, uint index,
  678.                                      struct pipe_constant_buffer *cb)
  679. {
  680.    struct i915_context *i915 = i915_context(pipe);
  681.    struct pipe_resource *buf = cb ? cb->buffer : NULL;
  682.    unsigned new_num = 0;
  683.    boolean diff = TRUE;
  684.  
  685.    /* XXX don't support geom shaders now */
  686.    if (shader == PIPE_SHADER_GEOMETRY)
  687.       return;
  688.  
  689.    if (cb && cb->user_buffer) {
  690.       buf = i915_user_buffer_create(pipe->screen, (void *) cb->user_buffer,
  691.                                     cb->buffer_size,
  692.                                     PIPE_BIND_CONSTANT_BUFFER);
  693.    }
  694.  
  695.    /* if we have a new buffer compare it with the old one */
  696.    if (buf) {
  697.       struct i915_buffer *ibuf = i915_buffer(buf);
  698.       struct pipe_resource *old_buf = i915->constants[shader];
  699.       struct i915_buffer *old = old_buf ? i915_buffer(old_buf) : NULL;
  700.       unsigned old_num = i915->current.num_user_constants[shader];
  701.  
  702.       new_num = ibuf->b.b.width0 / 4 * sizeof(float);
  703.  
  704.       if (old_num == new_num) {
  705.          if (old_num == 0)
  706.             diff = FALSE;
  707. #if 0
  708.          /* XXX no point in running this code since st/mesa only uses user buffers */
  709.          /* Can't compare the buffer data since they are userbuffers */
  710.          else if (old && old->free_on_destroy)
  711.             diff = memcmp(old->data, ibuf->data, ibuf->b.b.width0);
  712. #else
  713.          (void)old;
  714. #endif
  715.       }
  716.    } else {
  717.       diff = i915->current.num_user_constants[shader] != 0;
  718.    }
  719.  
  720.    pipe_resource_reference(&i915->constants[shader], buf);
  721.    i915->current.num_user_constants[shader] = new_num;
  722.  
  723.    if (diff)
  724.       i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS;
  725.  
  726.    if (cb && cb->user_buffer) {
  727.       pipe_resource_reference(&buf, NULL);
  728.    }
  729. }
  730.  
  731.  
  732. static void i915_set_fragment_sampler_views(struct pipe_context *pipe,
  733.                                             unsigned num,
  734.                                             struct pipe_sampler_view **views)
  735. {
  736.    struct i915_context *i915 = i915_context(pipe);
  737.    uint i;
  738.  
  739.    assert(num <= PIPE_MAX_SAMPLERS);
  740.  
  741.    /* Check for no-op */
  742.    if (num == i915->num_fragment_sampler_views &&
  743.        !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
  744.       return;
  745.  
  746.    for (i = 0; i < num; i++) {
  747.       /* Note: we're using pipe_sampler_view_release() here to work around
  748.        * a possible crash when the old view belongs to another context that
  749.        * was already destroyed.
  750.        */
  751.       pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]);
  752.       pipe_sampler_view_reference(&i915->fragment_sampler_views[i],
  753.                                   views[i]);
  754.    }
  755.  
  756.    for (i = num; i < i915->num_fragment_sampler_views; i++)
  757.       pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]);
  758.  
  759.    i915->num_fragment_sampler_views = num;
  760.  
  761.    i915->dirty |= I915_NEW_SAMPLER_VIEW;
  762. }
  763.  
  764. static void
  765. i915_set_vertex_sampler_views(struct pipe_context *pipe,
  766.                               unsigned num,
  767.                               struct pipe_sampler_view **views)
  768. {
  769.    struct i915_context *i915 = i915_context(pipe);
  770.    uint i;
  771.  
  772.    assert(num <= Elements(i915->vertex_sampler_views));
  773.  
  774.    /* Check for no-op */
  775.    if (num == i915->num_vertex_sampler_views &&
  776.        !memcmp(i915->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
  777.       return;
  778.    }
  779.  
  780.    for (i = 0; i < Elements(i915->vertex_sampler_views); i++) {
  781.       struct pipe_sampler_view *view = i < num ? views[i] : NULL;
  782.  
  783.       pipe_sampler_view_reference(&i915->vertex_sampler_views[i], view);
  784.    }
  785.  
  786.    i915->num_vertex_sampler_views = num;
  787.  
  788.    draw_set_sampler_views(i915->draw,
  789.                           PIPE_SHADER_VERTEX,
  790.                           i915->vertex_sampler_views,
  791.                           i915->num_vertex_sampler_views);
  792. }
  793.  
  794.  
  795. static void
  796. i915_set_sampler_views(struct pipe_context *pipe, unsigned shader,
  797.                        unsigned start, unsigned num,
  798.                        struct pipe_sampler_view **views)
  799. {
  800.    assert(start == 0);
  801.    switch (shader) {
  802.    case PIPE_SHADER_FRAGMENT:
  803.       i915_set_fragment_sampler_views(pipe, num, views);
  804.       break;
  805.    case PIPE_SHADER_VERTEX:
  806.       i915_set_vertex_sampler_views(pipe, num, views);
  807.       break;
  808.    default:
  809.       ;
  810.    }
  811. }
  812.  
  813.  
  814. struct pipe_sampler_view *
  815. i915_create_sampler_view_custom(struct pipe_context *pipe,
  816.                                 struct pipe_resource *texture,
  817.                                 const struct pipe_sampler_view *templ,
  818.                                 unsigned width0,
  819.                                 unsigned height0)
  820. {
  821.    struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
  822.  
  823.    if (view) {
  824.       *view = *templ;
  825.       view->reference.count = 1;
  826.       view->texture = NULL;
  827.       pipe_resource_reference(&view->texture, texture);
  828.       view->context = pipe;
  829.    }
  830.  
  831.    return view;
  832. }
  833.  
  834. static struct pipe_sampler_view *
  835. i915_create_sampler_view(struct pipe_context *pipe,
  836.                          struct pipe_resource *texture,
  837.                          const struct pipe_sampler_view *templ)
  838. {
  839.    struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
  840.  
  841.    if (view) {
  842.       *view = *templ;
  843.       view->reference.count = 1;
  844.       view->texture = NULL;
  845.       pipe_resource_reference(&view->texture, texture);
  846.       view->context = pipe;
  847.    }
  848.  
  849.    return view;
  850. }
  851.  
  852.  
  853. static void
  854. i915_sampler_view_destroy(struct pipe_context *pipe,
  855.                           struct pipe_sampler_view *view)
  856. {
  857.    pipe_resource_reference(&view->texture, NULL);
  858.    FREE(view);
  859. }
  860.  
  861.  
  862. static void i915_set_framebuffer_state(struct pipe_context *pipe,
  863.                                        const struct pipe_framebuffer_state *fb)
  864. {
  865.    struct i915_context *i915 = i915_context(pipe);
  866.    int i;
  867.  
  868.    i915->framebuffer.width = fb->width;
  869.    i915->framebuffer.height = fb->height;
  870.    i915->framebuffer.nr_cbufs = fb->nr_cbufs;
  871.    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
  872.       pipe_surface_reference(&i915->framebuffer.cbufs[i],
  873.                              i < fb->nr_cbufs ? fb->cbufs[i] : NULL);
  874.    }
  875.    pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf);
  876.  
  877.    i915->dirty |= I915_NEW_FRAMEBUFFER;
  878. }
  879.  
  880.  
  881.  
  882. static void i915_set_clip_state( struct pipe_context *pipe,
  883.                              const struct pipe_clip_state *clip )
  884. {
  885.    struct i915_context *i915 = i915_context(pipe);
  886.  
  887.    i915->clip = *clip;
  888.  
  889.    draw_set_clip_state(i915->draw, clip);
  890.  
  891.    i915->dirty |= I915_NEW_CLIP;
  892. }
  893.  
  894.  
  895.  
  896. /* Called when driver state tracker notices changes to the viewport
  897.  * matrix:
  898.  */
  899. static void i915_set_viewport_states( struct pipe_context *pipe,
  900.                                       unsigned start_slot,
  901.                                       unsigned num_viewports,
  902.                                      const struct pipe_viewport_state *viewport )
  903. {
  904.    struct i915_context *i915 = i915_context(pipe);
  905.  
  906.    i915->viewport = *viewport; /* struct copy */
  907.  
  908.    /* pass the viewport info to the draw module */
  909.    draw_set_viewport_states(i915->draw, start_slot, num_viewports,
  910.                             &i915->viewport);
  911.  
  912.    i915->dirty |= I915_NEW_VIEWPORT;
  913. }
  914.  
  915.  
  916. static void *
  917. i915_create_rasterizer_state(struct pipe_context *pipe,
  918.                              const struct pipe_rasterizer_state *rasterizer)
  919. {
  920.    struct i915_rasterizer_state *cso = CALLOC_STRUCT( i915_rasterizer_state );
  921.  
  922.    cso->templ = *rasterizer;
  923.    cso->color_interp = rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
  924.    cso->light_twoside = rasterizer->light_twoside;
  925.    cso->ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE;
  926.    cso->ds[1].f = rasterizer->offset_scale;
  927.    if (rasterizer->poly_stipple_enable) {
  928.       cso->st |= ST1_ENABLE;
  929.    }
  930.  
  931.    if (rasterizer->scissor)
  932.       cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT;
  933.    else
  934.       cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT;
  935.  
  936.    switch (rasterizer->cull_face) {
  937.    case PIPE_FACE_NONE:
  938.       cso->LIS4 |= S4_CULLMODE_NONE;
  939.       break;
  940.    case PIPE_FACE_FRONT:
  941.       if (rasterizer->front_ccw)
  942.          cso->LIS4 |= S4_CULLMODE_CCW;
  943.       else
  944.          cso->LIS4 |= S4_CULLMODE_CW;
  945.       break;
  946.    case PIPE_FACE_BACK:
  947.       if (rasterizer->front_ccw)
  948.          cso->LIS4 |= S4_CULLMODE_CW;
  949.       else
  950.          cso->LIS4 |= S4_CULLMODE_CCW;
  951.       break;
  952.    case PIPE_FACE_FRONT_AND_BACK:
  953.       cso->LIS4 |= S4_CULLMODE_BOTH;
  954.       break;
  955.    }
  956.  
  957.    {
  958.       int line_width = CLAMP((int)(rasterizer->line_width * 2), 1, 0xf);
  959.  
  960.       cso->LIS4 |= line_width << S4_LINE_WIDTH_SHIFT;
  961.  
  962.       if (rasterizer->line_smooth)
  963.          cso->LIS4 |= S4_LINE_ANTIALIAS_ENABLE;
  964.    }
  965.  
  966.    {
  967.       int point_size = CLAMP((int) rasterizer->point_size, 1, 0xff);
  968.  
  969.       cso->LIS4 |= point_size << S4_POINT_WIDTH_SHIFT;
  970.    }
  971.  
  972.    if (rasterizer->flatshade) {
  973.       cso->LIS4 |= (S4_FLATSHADE_ALPHA |
  974.                     S4_FLATSHADE_COLOR |
  975.                     S4_FLATSHADE_SPECULAR);
  976.    }
  977.  
  978.    cso->LIS7 = fui( rasterizer->offset_units );
  979.  
  980.  
  981.    return cso;
  982. }
  983.  
  984. static void i915_bind_rasterizer_state( struct pipe_context *pipe,
  985.                                         void *raster )
  986. {
  987.    struct i915_context *i915 = i915_context(pipe);
  988.  
  989.    if (i915->rasterizer == raster)
  990.       return;
  991.  
  992.    i915->rasterizer = (struct i915_rasterizer_state *)raster;
  993.  
  994.    /* pass-through to draw module */
  995.    draw_set_rasterizer_state(i915->draw,
  996.                            (i915->rasterizer ? &(i915->rasterizer->templ) : NULL),
  997.                            raster);
  998.  
  999.    i915->dirty |= I915_NEW_RASTERIZER;
  1000. }
  1001.  
  1002. static void i915_delete_rasterizer_state(struct pipe_context *pipe,
  1003.                                          void *raster)
  1004. {
  1005.    FREE(raster);
  1006. }
  1007.  
  1008. static void i915_set_vertex_buffers(struct pipe_context *pipe,
  1009.                                     unsigned start_slot, unsigned count,
  1010.                                     const struct pipe_vertex_buffer *buffers)
  1011. {
  1012.    struct i915_context *i915 = i915_context(pipe);
  1013.    struct draw_context *draw = i915->draw;
  1014.  
  1015.    util_set_vertex_buffers_count(i915->vertex_buffers,
  1016.                                  &i915->nr_vertex_buffers,
  1017.                                  buffers, start_slot, count);
  1018.  
  1019.    /* pass-through to draw module */
  1020.    draw_set_vertex_buffers(draw, start_slot, count, buffers);
  1021. }
  1022.  
  1023. static void *
  1024. i915_create_vertex_elements_state(struct pipe_context *pipe,
  1025.                                   unsigned count,
  1026.                                   const struct pipe_vertex_element *attribs)
  1027. {
  1028.    struct i915_velems_state *velems;
  1029.    assert(count <= PIPE_MAX_ATTRIBS);
  1030.    velems = (struct i915_velems_state *) MALLOC(sizeof(struct i915_velems_state));
  1031.    if (velems) {
  1032.       velems->count = count;
  1033.       memcpy(velems->velem, attribs, sizeof(*attribs) * count);
  1034.    }
  1035.    return velems;
  1036. }
  1037.  
  1038. static void
  1039. i915_bind_vertex_elements_state(struct pipe_context *pipe,
  1040.                                 void *velems)
  1041. {
  1042.    struct i915_context *i915 = i915_context(pipe);
  1043.    struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems;
  1044.  
  1045.    if (i915->velems == velems)
  1046.       return;
  1047.  
  1048.    i915->velems = velems;
  1049.  
  1050.    /* pass-through to draw module */
  1051.    if (i915_velems) {
  1052.       draw_set_vertex_elements(i915->draw,
  1053.             i915_velems->count, i915_velems->velem);
  1054.    }
  1055. }
  1056.  
  1057. static void
  1058. i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
  1059. {
  1060.    FREE( velems );
  1061. }
  1062.  
  1063. static void i915_set_index_buffer(struct pipe_context *pipe,
  1064.                                   const struct pipe_index_buffer *ib)
  1065. {
  1066.    struct i915_context *i915 = i915_context(pipe);
  1067.  
  1068.    if (ib)
  1069.       memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer));
  1070.    else
  1071.       memset(&i915->index_buffer, 0, sizeof(i915->index_buffer));
  1072. }
  1073.  
  1074. static void
  1075. i915_set_sample_mask(struct pipe_context *pipe,
  1076.                      unsigned sample_mask)
  1077. {
  1078. }
  1079.  
  1080. void
  1081. i915_init_state_functions( struct i915_context *i915 )
  1082. {
  1083.    i915->base.create_blend_state = i915_create_blend_state;
  1084.    i915->base.bind_blend_state = i915_bind_blend_state;
  1085.    i915->base.delete_blend_state = i915_delete_blend_state;
  1086.  
  1087.    i915->base.create_sampler_state = i915_create_sampler_state;
  1088.    i915->base.bind_sampler_states = i915_bind_sampler_states;
  1089.    i915->base.delete_sampler_state = i915_delete_sampler_state;
  1090.  
  1091.    i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
  1092.    i915->base.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state;
  1093.    i915->base.delete_depth_stencil_alpha_state = i915_delete_depth_stencil_state;
  1094.  
  1095.    i915->base.create_rasterizer_state = i915_create_rasterizer_state;
  1096.    i915->base.bind_rasterizer_state = i915_bind_rasterizer_state;
  1097.    i915->base.delete_rasterizer_state = i915_delete_rasterizer_state;
  1098.    i915->base.create_fs_state = i915_create_fs_state;
  1099.    i915->base.bind_fs_state = i915_bind_fs_state;
  1100.    i915->base.delete_fs_state = i915_delete_fs_state;
  1101.    i915->base.create_vs_state = i915_create_vs_state;
  1102.    i915->base.bind_vs_state = i915_bind_vs_state;
  1103.    i915->base.delete_vs_state = i915_delete_vs_state;
  1104.    i915->base.create_vertex_elements_state = i915_create_vertex_elements_state;
  1105.    i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state;
  1106.    i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state;
  1107.  
  1108.    i915->base.set_blend_color = i915_set_blend_color;
  1109.    i915->base.set_stencil_ref = i915_set_stencil_ref;
  1110.    i915->base.set_clip_state = i915_set_clip_state;
  1111.    i915->base.set_sample_mask = i915_set_sample_mask;
  1112.    i915->base.set_constant_buffer = i915_set_constant_buffer;
  1113.    i915->base.set_framebuffer_state = i915_set_framebuffer_state;
  1114.  
  1115.    i915->base.set_polygon_stipple = i915_set_polygon_stipple;
  1116.    i915->base.set_scissor_states = i915_set_scissor_states;
  1117.    i915->base.set_sampler_views = i915_set_sampler_views;
  1118.    i915->base.create_sampler_view = i915_create_sampler_view;
  1119.    i915->base.sampler_view_destroy = i915_sampler_view_destroy;
  1120.    i915->base.set_viewport_states = i915_set_viewport_states;
  1121.    i915->base.set_vertex_buffers = i915_set_vertex_buffers;
  1122.    i915->base.set_index_buffer = i915_set_index_buffer;
  1123. }
  1124.