"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/svga/svga_state_rss.c" (16 Sep 2020, 17803 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "svga_state_rss.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    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 "pipe/p_defines.h"
   27 #include "util/u_bitmask.h"
   28 #include "util/format/u_format.h"
   29 #include "util/u_inlines.h"
   30 #include "util/u_memory.h"
   31 #include "util/u_math.h"
   32 #include "util/u_memory.h"
   33 
   34 #include "svga_context.h"
   35 #include "svga_screen.h"
   36 #include "svga_state.h"
   37 #include "svga_cmd.h"
   38 #include "svga_format.h"
   39 #include "svga_shader.h"
   40 
   41 
   42 struct rs_queue {
   43    unsigned rs_count;
   44    SVGA3dRenderState rs[SVGA3D_RS_MAX];
   45 };
   46 
   47 
   48 #define EMIT_RS(svga, value, token)                       \
   49 do {                                                            \
   50    STATIC_ASSERT(SVGA3D_RS_##token < ARRAY_SIZE(svga->state.hw_draw.rs)); \
   51    if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) {    \
   52       svga_queue_rs(&queue, SVGA3D_RS_##token, value);          \
   53       svga->state.hw_draw.rs[SVGA3D_RS_##token] = value;        \
   54    }                                                            \
   55 } while (0)
   56 
   57 #define EMIT_RS_FLOAT(svga, fvalue, token)                \
   58 do {                                                            \
   59    unsigned value = fui(fvalue);                                \
   60    STATIC_ASSERT(SVGA3D_RS_##token < ARRAY_SIZE(svga->state.hw_draw.rs)); \
   61    if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) {    \
   62       svga_queue_rs(&queue, SVGA3D_RS_##token, value);          \
   63       svga->state.hw_draw.rs[SVGA3D_RS_##token] = value;        \
   64    }                                                            \
   65 } while (0)
   66 
   67 
   68 static inline void
   69 svga_queue_rs(struct rs_queue *q, unsigned rss, unsigned value)
   70 {
   71    assert(q->rs_count < ARRAY_SIZE(q->rs));
   72    q->rs[q->rs_count].state = rss;
   73    q->rs[q->rs_count].uintValue = value;
   74    q->rs_count++;
   75 }
   76 
   77 
   78 static unsigned
   79 translate_fill_mode(unsigned fill)
   80 {
   81    switch (fill) {
   82    case PIPE_POLYGON_MODE_POINT:
   83       return SVGA3D_FILLMODE_POINT;
   84    case PIPE_POLYGON_MODE_LINE:
   85       return SVGA3D_FILLMODE_LINE;
   86    case PIPE_POLYGON_MODE_FILL:
   87       return SVGA3D_FILLMODE_FILL;
   88    default:
   89       assert(!"Bad fill mode");
   90       return SVGA3D_FILLMODE_FILL;
   91    }
   92 }
   93 
   94 
   95 /* Compare old and new render states and emit differences between them
   96  * to hardware.  Simplest implementation would be to emit the whole of
   97  * the "to" state.
   98  */
   99 static enum pipe_error
  100 emit_rss_vgpu9(struct svga_context *svga, unsigned dirty)
  101 {
  102    struct svga_screen *screen = svga_screen(svga->pipe.screen);
  103    struct rs_queue queue;
  104    float point_size_min;
  105 
  106    queue.rs_count = 0;
  107 
  108    if (dirty & (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR)) {
  109       const struct svga_blend_state *curr = svga->curr.blend;
  110 
  111       EMIT_RS(svga, curr->rt[0].writemask, COLORWRITEENABLE);
  112       EMIT_RS(svga, curr->rt[0].blend_enable, BLENDENABLE);
  113 
  114       if (curr->rt[0].blend_enable) {
  115          EMIT_RS(svga, curr->rt[0].srcblend, SRCBLEND);
  116          EMIT_RS(svga, curr->rt[0].dstblend, DSTBLEND);
  117          EMIT_RS(svga, curr->rt[0].blendeq, BLENDEQUATION);
  118 
  119          EMIT_RS(svga, curr->rt[0].separate_alpha_blend_enable,
  120                   SEPARATEALPHABLENDENABLE);
  121 
  122          if (curr->rt[0].separate_alpha_blend_enable) {
  123             EMIT_RS(svga, curr->rt[0].srcblend_alpha, SRCBLENDALPHA);
  124             EMIT_RS(svga, curr->rt[0].dstblend_alpha, DSTBLENDALPHA);
  125             EMIT_RS(svga, curr->rt[0].blendeq_alpha, BLENDEQUATIONALPHA);
  126          }
  127       }
  128    }
  129 
  130    if (dirty & SVGA_NEW_BLEND_COLOR) {
  131       uint32 color;
  132       uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]);
  133       uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]);
  134       uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]);
  135       uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]);
  136 
  137       color = (a << 24) | (r << 16) | (g << 8) | b;
  138 
  139       EMIT_RS(svga, color, BLENDCOLOR);
  140    }
  141 
  142    if (dirty & (SVGA_NEW_DEPTH_STENCIL_ALPHA | SVGA_NEW_RAST)) {
  143       const struct svga_depth_stencil_state *curr = svga->curr.depth;
  144       const struct svga_rasterizer_state *rast = svga->curr.rast;
  145 
  146       if (!curr->stencil[0].enabled) {
  147          /* Stencil disabled
  148           */
  149          EMIT_RS(svga, FALSE, STENCILENABLE);
  150          EMIT_RS(svga, FALSE, STENCILENABLE2SIDED);
  151       }
  152       else if (curr->stencil[0].enabled && !curr->stencil[1].enabled) {
  153          /* Regular stencil
  154           */
  155          EMIT_RS(svga, TRUE, STENCILENABLE);
  156          EMIT_RS(svga, FALSE, STENCILENABLE2SIDED);
  157 
  158          EMIT_RS(svga, curr->stencil[0].func,  STENCILFUNC);
  159          EMIT_RS(svga, curr->stencil[0].fail,  STENCILFAIL);
  160          EMIT_RS(svga, curr->stencil[0].zfail, STENCILZFAIL);
  161          EMIT_RS(svga, curr->stencil[0].pass,  STENCILPASS);
  162 
  163          EMIT_RS(svga, curr->stencil_mask, STENCILMASK);
  164          EMIT_RS(svga, curr->stencil_writemask, STENCILWRITEMASK);
  165       }
  166       else {
  167          int cw, ccw;
  168 
  169          /* Hardware frontwinding is always CW, so if ours is also CW,
  170           * then our definition of front face agrees with hardware.
  171           * Otherwise need to flip.
  172           */
  173          if (rast->templ.front_ccw) {
  174             ccw = 0;
  175             cw = 1;
  176          }
  177          else {
  178             ccw = 1;
  179             cw = 0;
  180          }
  181 
  182          /* Twoside stencil
  183           */
  184          EMIT_RS(svga, TRUE, STENCILENABLE);
  185          EMIT_RS(svga, TRUE, STENCILENABLE2SIDED);
  186 
  187          EMIT_RS(svga, curr->stencil[cw].func,  STENCILFUNC);
  188          EMIT_RS(svga, curr->stencil[cw].fail,  STENCILFAIL);
  189          EMIT_RS(svga, curr->stencil[cw].zfail, STENCILZFAIL);
  190          EMIT_RS(svga, curr->stencil[cw].pass,  STENCILPASS);
  191 
  192          EMIT_RS(svga, curr->stencil[ccw].func,  CCWSTENCILFUNC);
  193          EMIT_RS(svga, curr->stencil[ccw].fail,  CCWSTENCILFAIL);
  194          EMIT_RS(svga, curr->stencil[ccw].zfail, CCWSTENCILZFAIL);
  195          EMIT_RS(svga, curr->stencil[ccw].pass,  CCWSTENCILPASS);
  196 
  197          EMIT_RS(svga, curr->stencil_mask, STENCILMASK);
  198          EMIT_RS(svga, curr->stencil_writemask, STENCILWRITEMASK);
  199       }
  200 
  201       EMIT_RS(svga, curr->zenable, ZENABLE);
  202       if (curr->zenable) {
  203          EMIT_RS(svga, curr->zfunc, ZFUNC);
  204          EMIT_RS(svga, curr->zwriteenable, ZWRITEENABLE);
  205       }
  206 
  207       EMIT_RS(svga, curr->alphatestenable, ALPHATESTENABLE);
  208       if (curr->alphatestenable) {
  209          EMIT_RS(svga, curr->alphafunc, ALPHAFUNC);
  210          EMIT_RS_FLOAT(svga, curr->alpharef, ALPHAREF);
  211       }
  212    }
  213 
  214    if (dirty & SVGA_NEW_STENCIL_REF) {
  215       EMIT_RS(svga, svga->curr.stencil_ref.ref_value[0], STENCILREF);
  216    }
  217 
  218    if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE)) {
  219       const struct svga_rasterizer_state *curr = svga->curr.rast;
  220       unsigned cullmode = curr->cullmode;
  221 
  222       /* Shademode: still need to rearrange index list to move
  223        * flat-shading PV first vertex.
  224        */
  225       EMIT_RS(svga, curr->shademode, SHADEMODE);
  226 
  227       EMIT_RS(svga, translate_fill_mode(curr->hw_fillmode), FILLMODE);
  228 
  229       /* Don't do culling while the software pipeline is active.  It
  230        * does it for us, and additionally introduces potentially
  231        * back-facing triangles.
  232        */
  233       if (svga->state.sw.need_pipeline)
  234          cullmode = SVGA3D_FACE_NONE;
  235 
  236       point_size_min = util_get_min_point_size(&curr->templ);
  237 
  238       EMIT_RS(svga, cullmode, CULLMODE);
  239       EMIT_RS(svga, curr->scissortestenable, SCISSORTESTENABLE);
  240       EMIT_RS(svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS);
  241       EMIT_RS(svga, curr->lastpixel, LASTPIXEL);
  242       EMIT_RS_FLOAT(svga, curr->pointsize, POINTSIZE);
  243       EMIT_RS_FLOAT(svga, point_size_min, POINTSIZEMIN);
  244       EMIT_RS_FLOAT(svga, screen->maxPointSize, POINTSIZEMAX);
  245       EMIT_RS(svga, curr->pointsprite, POINTSPRITEENABLE);
  246 
  247       /* Emit line state, when the device understands it */
  248       if (screen->haveLineStipple)
  249          EMIT_RS(svga, curr->linepattern, LINEPATTERN);
  250       if (screen->haveLineSmooth)
  251          EMIT_RS(svga, curr->antialiasedlineenable, ANTIALIASEDLINEENABLE);
  252       if (screen->maxLineWidth > 1.0F)
  253          EMIT_RS_FLOAT(svga, curr->linewidth, LINEWIDTH);
  254    }
  255 
  256    if (dirty & (SVGA_NEW_RAST |
  257                 SVGA_NEW_FRAME_BUFFER |
  258                 SVGA_NEW_NEED_PIPELINE)) {
  259       const struct svga_rasterizer_state *curr = svga->curr.rast;
  260       float slope = 0.0;
  261       float bias  = 0.0;
  262 
  263       /* Need to modify depth bias according to bound depthbuffer
  264        * format.  Don't do hardware depthbias while the software
  265        * pipeline is active.
  266        */
  267       if (!svga->state.sw.need_pipeline &&
  268           svga->curr.framebuffer.zsbuf)
  269       {
  270          slope = curr->slopescaledepthbias;
  271          bias  = svga->curr.depthscale * curr->depthbias;
  272       }
  273 
  274       EMIT_RS_FLOAT(svga, slope, SLOPESCALEDEPTHBIAS);
  275       EMIT_RS_FLOAT(svga, bias, DEPTHBIAS);
  276    }
  277 
  278    if (dirty & SVGA_NEW_FRAME_BUFFER) {
  279       /* XXX: we only look at the first color buffer's sRGB state */
  280       float gamma = 1.0f;
  281       if (svga->curr.framebuffer.cbufs[0] &&
  282           util_format_is_srgb(svga->curr.framebuffer.cbufs[0]->format)) {
  283          gamma = 2.2f;
  284       }
  285       EMIT_RS_FLOAT(svga, gamma, OUTPUTGAMMA);
  286    }
  287 
  288    if (dirty & SVGA_NEW_RAST) {
  289       /* bitmask of the enabled clip planes */
  290       unsigned enabled = svga->curr.rast->templ.clip_plane_enable;
  291       EMIT_RS(svga, enabled, CLIPPLANEENABLE);
  292    }
  293 
  294    if (queue.rs_count) {
  295       SVGA3dRenderState *rs;
  296 
  297       if (SVGA3D_BeginSetRenderState(svga->swc, &rs, queue.rs_count)
  298           != PIPE_OK) {
  299          /* XXX: need to poison cached hardware state on failure to ensure
  300           * dirty state gets re-emitted.  Fix this by re-instating partial
  301           * FIFOCommit command and only updating cached hw state once the
  302           * initial allocation has succeeded.
  303           */
  304          memset(svga->state.hw_draw.rs, 0xcd, sizeof(svga->state.hw_draw.rs));
  305 
  306          return PIPE_ERROR_OUT_OF_MEMORY;
  307       }
  308 
  309       memcpy(rs, queue.rs, queue.rs_count * sizeof queue.rs[0]);
  310 
  311       SVGA_FIFOCommitAll(svga->swc);
  312    }
  313 
  314    return PIPE_OK;
  315 }
  316 
  317 
  318 /** Returns a non-culling rasterizer state object to be used with
  319  *  point sprite.
  320  */
  321 static struct svga_rasterizer_state *
  322 get_no_cull_rasterizer_state(struct svga_context *svga)
  323 {
  324    const struct svga_rasterizer_state *r = svga->curr.rast;
  325    unsigned int aa_point = r->templ.point_smooth;
  326 
  327    if (!svga->rasterizer_no_cull[aa_point]) {
  328       struct pipe_rasterizer_state rast;
  329 
  330       memset(&rast, 0, sizeof(rast));
  331       rast.flatshade = 1;
  332       rast.front_ccw = 1;
  333       rast.point_smooth = r->templ.point_smooth;
  334 
  335       /* All rasterizer states have the same half_pixel_center,
  336        * bottom_edge_rule and clip_halfz values since they are
  337        * constant for a context. If we ever implement
  338        * GL_ARB_clip_control, the clip_halfz field would have to be observed.
  339        */
  340       rast.half_pixel_center = r->templ.half_pixel_center;
  341       rast.bottom_edge_rule = r->templ.bottom_edge_rule;
  342       rast.clip_halfz = r->templ.clip_halfz;
  343 
  344       svga->rasterizer_no_cull[aa_point] =
  345                svga->pipe.create_rasterizer_state(&svga->pipe, &rast);
  346    }
  347    return svga->rasterizer_no_cull[aa_point];
  348 }
  349 
  350 
  351 /** Returns a depth stencil state object with depth and stencil test disabled.
  352  */
  353 static struct svga_depth_stencil_state *
  354 get_no_depth_stencil_test_state(struct svga_context *svga)
  355 {
  356    if (!svga->depthstencil_disable) {
  357       struct pipe_depth_stencil_alpha_state ds = {{0}};
  358       svga->depthstencil_disable =
  359          svga->pipe.create_depth_stencil_alpha_state(&svga->pipe, &ds);
  360    }
  361    return svga->depthstencil_disable;
  362 }
  363 
  364 
  365 static enum pipe_error
  366 emit_rss_vgpu10(struct svga_context *svga, unsigned dirty)
  367 {
  368    enum pipe_error ret = PIPE_OK;
  369 
  370    svga_hwtnl_flush_retry(svga);
  371 
  372    if (dirty & (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR)) {
  373       const struct svga_blend_state *curr;
  374       float blend_factor[4];
  375 
  376       if (svga_has_any_integer_cbufs(svga)) {
  377          /* Blending is not supported in integer-valued render targets. */
  378          curr = svga->noop_blend;
  379          blend_factor[0] =
  380          blend_factor[1] =
  381          blend_factor[2] =
  382          blend_factor[3] = 0;
  383       }
  384       else {
  385          curr = svga->curr.blend;
  386 
  387          if (curr->blend_color_alpha) {
  388             blend_factor[0] =
  389             blend_factor[1] =
  390             blend_factor[2] =
  391             blend_factor[3] = svga->curr.blend_color.color[3];
  392          }
  393          else {
  394             blend_factor[0] = svga->curr.blend_color.color[0];
  395             blend_factor[1] = svga->curr.blend_color.color[1];
  396             blend_factor[2] = svga->curr.blend_color.color[2];
  397             blend_factor[3] = svga->curr.blend_color.color[3];
  398          }
  399       }
  400 
  401       /* Set/bind the blend state object */
  402       if (svga->state.hw_draw.blend_id != curr->id ||
  403           svga->state.hw_draw.blend_factor[0] != blend_factor[0] ||
  404           svga->state.hw_draw.blend_factor[1] != blend_factor[1] ||
  405           svga->state.hw_draw.blend_factor[2] != blend_factor[2] ||
  406           svga->state.hw_draw.blend_factor[3] != blend_factor[3] ||
  407           svga->state.hw_draw.blend_sample_mask != svga->curr.sample_mask) {
  408          ret = SVGA3D_vgpu10_SetBlendState(svga->swc, curr->id,
  409                                            blend_factor,
  410                                            svga->curr.sample_mask);
  411          if (ret != PIPE_OK)
  412             return ret;
  413 
  414          svga->state.hw_draw.blend_id = curr->id;
  415          svga->state.hw_draw.blend_factor[0] = blend_factor[0];
  416          svga->state.hw_draw.blend_factor[1] = blend_factor[1];
  417          svga->state.hw_draw.blend_factor[2] = blend_factor[2];
  418          svga->state.hw_draw.blend_factor[3] = blend_factor[3];
  419          svga->state.hw_draw.blend_sample_mask = svga->curr.sample_mask;
  420       }
  421    }
  422 
  423    if (svga->disable_rasterizer) {
  424       if (!svga->state.hw_draw.rasterizer_discard) {
  425          struct svga_depth_stencil_state *ds;
  426 
  427          /* If rasterization is to be disabled, disable depth and stencil
  428           * testing as well.
  429           */
  430          ds = get_no_depth_stencil_test_state(svga);
  431          if (ds->id != svga->state.hw_draw.depth_stencil_id) {
  432             ret = SVGA3D_vgpu10_SetDepthStencilState(svga->swc, ds->id, 0);
  433             if (ret != PIPE_OK)
  434                return ret;
  435 
  436             svga->state.hw_draw.depth_stencil_id = ds->id;
  437             svga->state.hw_draw.stencil_ref = 0;
  438          }
  439          svga->state.hw_draw.rasterizer_discard = TRUE;
  440       }
  441    } else {
  442       if ((dirty & (SVGA_NEW_DEPTH_STENCIL_ALPHA | SVGA_NEW_STENCIL_REF)) ||
  443           svga->state.hw_draw.rasterizer_discard) {
  444          const struct svga_depth_stencil_state *curr = svga->curr.depth;
  445          unsigned curr_ref = svga->curr.stencil_ref.ref_value[0];
  446 
  447          if (curr->id != svga->state.hw_draw.depth_stencil_id ||
  448              curr_ref != svga->state.hw_draw.stencil_ref) {
  449             /* Set/bind the depth/stencil state object */
  450             ret = SVGA3D_vgpu10_SetDepthStencilState(svga->swc, curr->id,
  451                                                      curr_ref);
  452             if (ret != PIPE_OK)
  453                return ret;
  454 
  455             svga->state.hw_draw.depth_stencil_id = curr->id;
  456             svga->state.hw_draw.stencil_ref = curr_ref;
  457          }
  458       }
  459 
  460       if (dirty & (SVGA_NEW_REDUCED_PRIMITIVE | SVGA_NEW_RAST)) {
  461          const struct svga_rasterizer_state *rast;
  462 
  463          if (svga->curr.reduced_prim == PIPE_PRIM_POINTS &&
  464              svga->curr.gs && svga->curr.gs->wide_point) {
  465 
  466             /* If we are drawing a point sprite, we will need to
  467              * bind a non-culling rasterizer state object
  468              */
  469             rast = get_no_cull_rasterizer_state(svga);
  470          }
  471          else {
  472             rast = svga->curr.rast;
  473          }
  474 
  475          if (svga->state.hw_draw.rasterizer_id != rast->id) {
  476             /* Set/bind the rasterizer state object */
  477             ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, rast->id);
  478             if (ret != PIPE_OK)
  479                return ret;
  480             svga->state.hw_draw.rasterizer_id = rast->id;
  481          }
  482       }
  483       svga->state.hw_draw.rasterizer_discard = FALSE;
  484    }
  485    return PIPE_OK;
  486 }
  487 
  488 
  489 static enum pipe_error
  490 emit_rss(struct svga_context *svga, unsigned dirty)
  491 {
  492    if (svga_have_vgpu10(svga)) {
  493       return emit_rss_vgpu10(svga, dirty);
  494    }
  495    else {
  496       return emit_rss_vgpu9(svga, dirty);
  497    }
  498 }
  499 
  500 
  501 struct svga_tracked_state svga_hw_rss =
  502 {
  503    "hw rss state",
  504 
  505    (SVGA_NEW_BLEND |
  506     SVGA_NEW_BLEND_COLOR |
  507     SVGA_NEW_DEPTH_STENCIL_ALPHA |
  508     SVGA_NEW_STENCIL_REF |
  509     SVGA_NEW_RAST |
  510     SVGA_NEW_FRAME_BUFFER |
  511     SVGA_NEW_NEED_PIPELINE |
  512     SVGA_NEW_FS |
  513     SVGA_NEW_REDUCED_PRIMITIVE),
  514 
  515    emit_rss
  516 };