Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**********************************************************
  2.  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person
  5.  * obtaining a copy of this software and associated documentation
  6.  * files (the "Software"), to deal in the Software without
  7.  * restriction, including without limitation the rights to use, copy,
  8.  * modify, merge, publish, distribute, sublicense, and/or sell copies
  9.  * of the Software, and to permit persons to whom the Software is
  10.  * furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be
  13.  * included in all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  *
  24.  **********************************************************/
  25.  
  26. #include "util/u_format.h"
  27. #include "util/u_inlines.h"
  28. #include "util/u_memory.h"
  29. #include "pipe/p_defines.h"
  30. #include "util/u_math.h"
  31.  
  32. #include "svga_context.h"
  33. #include "svga_screen.h"
  34. #include "svga_state.h"
  35. #include "svga_cmd.h"
  36.  
  37.  
  38. struct rs_queue {
  39.    unsigned rs_count;
  40.    SVGA3dRenderState rs[SVGA3D_RS_MAX];
  41. };
  42.  
  43.  
  44. #define EMIT_RS(svga, value, token, fail)                       \
  45. do {                                                            \
  46.    assert(SVGA3D_RS_##token < Elements(svga->state.hw_draw.rs)); \
  47.    if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) {    \
  48.       svga_queue_rs( &queue, SVGA3D_RS_##token, value );        \
  49.       svga->state.hw_draw.rs[SVGA3D_RS_##token] = value;        \
  50.    }                                                            \
  51. } while (0)
  52.  
  53. #define EMIT_RS_FLOAT(svga, fvalue, token, fail)                \
  54. do {                                                            \
  55.    unsigned value = fui(fvalue);                                \
  56.    assert(SVGA3D_RS_##token < Elements(svga->state.hw_draw.rs)); \
  57.    if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) {    \
  58.       svga_queue_rs( &queue, SVGA3D_RS_##token, value );        \
  59.       svga->state.hw_draw.rs[SVGA3D_RS_##token] = value;        \
  60.    }                                                            \
  61. } while (0)
  62.  
  63.  
  64. static INLINE void
  65. svga_queue_rs( struct rs_queue *q,
  66.                unsigned rss,
  67.                unsigned value )
  68. {
  69.    q->rs[q->rs_count].state = rss;
  70.    q->rs[q->rs_count].uintValue = value;
  71.    q->rs_count++;
  72. }
  73.  
  74.  
  75. /* Compare old and new render states and emit differences between them
  76.  * to hardware.  Simplest implementation would be to emit the whole of
  77.  * the "to" state.
  78.  */
  79. static enum pipe_error
  80. emit_rss(struct svga_context *svga, unsigned dirty)
  81. {
  82.    struct svga_screen *screen = svga_screen(svga->pipe.screen);
  83.    struct rs_queue queue;
  84.    float point_size_min;
  85.  
  86.    queue.rs_count = 0;
  87.  
  88.    if (dirty & SVGA_NEW_BLEND) {
  89.       const struct svga_blend_state *curr = svga->curr.blend;
  90.  
  91.       EMIT_RS( svga, curr->rt[0].writemask, COLORWRITEENABLE, fail );
  92.       EMIT_RS( svga, curr->rt[0].blend_enable, BLENDENABLE, fail );
  93.  
  94.       if (curr->rt[0].blend_enable) {
  95.          EMIT_RS( svga, curr->rt[0].srcblend, SRCBLEND, fail );
  96.          EMIT_RS( svga, curr->rt[0].dstblend, DSTBLEND, fail );
  97.          EMIT_RS( svga, curr->rt[0].blendeq, BLENDEQUATION, fail );
  98.  
  99.          EMIT_RS( svga, curr->rt[0].separate_alpha_blend_enable,
  100.                   SEPARATEALPHABLENDENABLE, fail );
  101.  
  102.          if (curr->rt[0].separate_alpha_blend_enable) {
  103.             EMIT_RS( svga, curr->rt[0].srcblend_alpha, SRCBLENDALPHA, fail );
  104.             EMIT_RS( svga, curr->rt[0].dstblend_alpha, DSTBLENDALPHA, fail );
  105.             EMIT_RS( svga, curr->rt[0].blendeq_alpha, BLENDEQUATIONALPHA, fail );
  106.          }
  107.       }
  108.    }
  109.  
  110.    if (dirty & SVGA_NEW_BLEND_COLOR) {
  111.       uint32 color;
  112.       uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]);
  113.       uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]);
  114.       uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]);
  115.       uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]);
  116.  
  117.       color = (a << 24) | (r << 16) | (g << 8) | b;
  118.  
  119.       EMIT_RS( svga, color, BLENDCOLOR, fail );
  120.    }
  121.  
  122.    if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) {
  123.       const struct svga_depth_stencil_state *curr = svga->curr.depth;
  124.       const struct svga_rasterizer_state *rast = svga->curr.rast;
  125.  
  126.       if (!curr->stencil[0].enabled)
  127.       {
  128.          /* Stencil disabled
  129.           */
  130.          EMIT_RS( svga, FALSE, STENCILENABLE, fail );
  131.          EMIT_RS( svga, FALSE, STENCILENABLE2SIDED, fail );
  132.       }
  133.       else if (curr->stencil[0].enabled && !curr->stencil[1].enabled)
  134.       {
  135.          /* Regular stencil
  136.           */
  137.          EMIT_RS( svga, TRUE, STENCILENABLE, fail );
  138.          EMIT_RS( svga, FALSE, STENCILENABLE2SIDED, fail );
  139.  
  140.          EMIT_RS( svga, curr->stencil[0].func,  STENCILFUNC, fail );
  141.          EMIT_RS( svga, curr->stencil[0].fail,  STENCILFAIL, fail );
  142.          EMIT_RS( svga, curr->stencil[0].zfail, STENCILZFAIL, fail );
  143.          EMIT_RS( svga, curr->stencil[0].pass,  STENCILPASS, fail );
  144.  
  145.          EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail );
  146.          EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail );
  147.       }
  148.       else
  149.       {
  150.          int cw, ccw;
  151.  
  152.          /* Hardware frontwinding is always CW, so if ours is also CW,
  153.           * then our definition of front face agrees with hardware.
  154.           * Otherwise need to flip.
  155.           */
  156.          if (rast->templ.front_ccw) {
  157.             ccw = 0;
  158.             cw = 1;
  159.          }
  160.          else {
  161.             ccw = 1;
  162.             cw = 0;
  163.          }
  164.  
  165.          /* Twoside stencil
  166.           */
  167.          EMIT_RS( svga, TRUE, STENCILENABLE, fail );
  168.          EMIT_RS( svga, TRUE, STENCILENABLE2SIDED, fail );
  169.  
  170.          EMIT_RS( svga, curr->stencil[cw].func,  STENCILFUNC, fail );
  171.          EMIT_RS( svga, curr->stencil[cw].fail,  STENCILFAIL, fail );
  172.          EMIT_RS( svga, curr->stencil[cw].zfail, STENCILZFAIL, fail );
  173.          EMIT_RS( svga, curr->stencil[cw].pass,  STENCILPASS, fail );
  174.  
  175.          EMIT_RS( svga, curr->stencil[ccw].func,  CCWSTENCILFUNC, fail );
  176.          EMIT_RS( svga, curr->stencil[ccw].fail,  CCWSTENCILFAIL, fail );
  177.          EMIT_RS( svga, curr->stencil[ccw].zfail, CCWSTENCILZFAIL, fail );
  178.          EMIT_RS( svga, curr->stencil[ccw].pass,  CCWSTENCILPASS, fail );
  179.  
  180.          EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail );
  181.          EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail );
  182.       }
  183.  
  184.       EMIT_RS( svga, curr->zenable, ZENABLE, fail );
  185.       if (curr->zenable) {
  186.          EMIT_RS( svga, curr->zfunc, ZFUNC, fail );
  187.          EMIT_RS( svga, curr->zwriteenable, ZWRITEENABLE, fail );
  188.       }
  189.  
  190.       EMIT_RS( svga, curr->alphatestenable, ALPHATESTENABLE, fail );
  191.       if (curr->alphatestenable) {
  192.          EMIT_RS( svga, curr->alphafunc, ALPHAFUNC, fail );
  193.          EMIT_RS_FLOAT( svga, curr->alpharef, ALPHAREF, fail );
  194.       }
  195.    }
  196.  
  197.    if (dirty & SVGA_NEW_STENCIL_REF) {
  198.       EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail );
  199.    }
  200.  
  201.    if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
  202.    {
  203.       const struct svga_rasterizer_state *curr = svga->curr.rast;
  204.       unsigned cullmode = curr->cullmode;
  205.  
  206.       /* Shademode: still need to rearrange index list to move
  207.        * flat-shading PV first vertex.
  208.        */
  209.       EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
  210.  
  211.       /* Don't do culling while the software pipeline is active.  It
  212.        * does it for us, and additionally introduces potentially
  213.        * back-facing triangles.
  214.        */
  215.       if (svga->state.sw.need_pipeline)
  216.          cullmode = SVGA3D_FACE_NONE;
  217.  
  218.       point_size_min = util_get_min_point_size(&curr->templ);
  219.  
  220.       EMIT_RS( svga, cullmode, CULLMODE, fail );
  221.       EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
  222.       EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
  223.       EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
  224.       EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
  225.       EMIT_RS_FLOAT( svga, point_size_min, POINTSIZEMIN, fail );
  226.       EMIT_RS_FLOAT( svga, screen->maxPointSize, POINTSIZEMAX, fail );
  227.       EMIT_RS( svga, curr->pointsprite, POINTSPRITEENABLE, fail);
  228.  
  229.       /* Emit line state, when the device understands it */
  230.       if (screen->haveLineStipple)
  231.          EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
  232.       if (screen->haveLineSmooth)
  233.          EMIT_RS( svga, curr->antialiasedlineenable, ANTIALIASEDLINEENABLE, fail );
  234.       if (screen->maxLineWidth > 1.0F)
  235.          EMIT_RS_FLOAT( svga, curr->linewidth, LINEWIDTH, fail );
  236.    }
  237.  
  238.    if (dirty & (SVGA_NEW_RAST | SVGA_NEW_FRAME_BUFFER | SVGA_NEW_NEED_PIPELINE))
  239.    {
  240.       const struct svga_rasterizer_state *curr = svga->curr.rast;
  241.       float slope = 0.0;
  242.       float bias  = 0.0;
  243.  
  244.       /* Need to modify depth bias according to bound depthbuffer
  245.        * format.  Don't do hardware depthbias while the software
  246.        * pipeline is active.
  247.        */
  248.       if (!svga->state.sw.need_pipeline &&
  249.           svga->curr.framebuffer.zsbuf)
  250.       {
  251.          slope = curr->slopescaledepthbias;
  252.          bias  = svga->curr.depthscale * curr->depthbias;
  253.       }
  254.  
  255.       EMIT_RS_FLOAT( svga, slope, SLOPESCALEDEPTHBIAS, fail );
  256.       EMIT_RS_FLOAT( svga, bias, DEPTHBIAS, fail );
  257.    }
  258.  
  259.    if (dirty & SVGA_NEW_FRAME_BUFFER) {
  260.       /* XXX: we only look at the first color buffer's sRGB state */
  261.       float gamma = 1.0f;
  262.       if (svga->curr.framebuffer.cbufs[0] &&
  263.           util_format_is_srgb(svga->curr.framebuffer.cbufs[0]->format)) {
  264.          gamma = 2.2f;
  265.       }
  266.       EMIT_RS_FLOAT(svga, gamma, OUTPUTGAMMA, fail);
  267.    }
  268.  
  269.    if (dirty & SVGA_NEW_RAST) {
  270.       /* bitmask of the enabled clip planes */
  271.       unsigned enabled = svga->curr.rast->templ.clip_plane_enable;
  272.       EMIT_RS( svga, enabled, CLIPPLANEENABLE, fail );
  273.    }
  274.  
  275.    if (queue.rs_count) {
  276.       SVGA3dRenderState *rs;
  277.  
  278.       if (SVGA3D_BeginSetRenderState( svga->swc,
  279.                                       &rs,
  280.                                       queue.rs_count ) != PIPE_OK)
  281.          goto fail;
  282.  
  283.       memcpy( rs,
  284.               queue.rs,
  285.               queue.rs_count * sizeof queue.rs[0]);
  286.  
  287.       SVGA_FIFOCommitAll( svga->swc );
  288.    }
  289.  
  290.    return PIPE_OK;
  291.  
  292. fail:
  293.    /* XXX: need to poison cached hardware state on failure to ensure
  294.     * dirty state gets re-emitted.  Fix this by re-instating partial
  295.     * FIFOCommit command and only updating cached hw state once the
  296.     * initial allocation has succeeded.
  297.     */
  298.    memset(svga->state.hw_draw.rs, 0xcd, sizeof(svga->state.hw_draw.rs));
  299.  
  300.    return PIPE_ERROR_OUT_OF_MEMORY;
  301. }
  302.  
  303.  
  304. struct svga_tracked_state svga_hw_rss =
  305. {
  306.    "hw rss state",
  307.  
  308.    (SVGA_NEW_BLEND |
  309.     SVGA_NEW_BLEND_COLOR |
  310.     SVGA_NEW_DEPTH_STENCIL |
  311.     SVGA_NEW_STENCIL_REF |
  312.     SVGA_NEW_RAST |
  313.     SVGA_NEW_FRAME_BUFFER |
  314.     SVGA_NEW_NEED_PIPELINE),
  315.  
  316.    emit_rss
  317. };
  318.