[Mesa-dev] [PATCH] swr: fix provoking vertex

Brian Paul brianp at vmware.com
Fri Jun 3 17:28:38 UTC 2016


On 06/03/2016 10:52 AM, Tim Rowley wrote:
> Use rasterizer provoking vertex API.
>
> Fix rasterizer provoking vertex for tristrips and quad list/strips.
> ---
>   .../drivers/swr/rasterizer/core/frontend.cpp       | 38 ++++++++++++++++++++--
>   src/gallium/drivers/swr/swr_draw.cpp               | 30 +++++++++++++++++
>   src/gallium/drivers/swr/swr_screen.cpp             |  2 +-
>   src/gallium/drivers/swr/swr_shader.cpp             | 12 +++----
>   src/gallium/drivers/swr/swr_shader.h               |  1 -
>   src/gallium/drivers/swr/swr_state.cpp              |  5 ++-
>   src/gallium/drivers/swr/swr_state.h                |  1 +
>   7 files changed, 77 insertions(+), 12 deletions(-)
>
> diff --git a/src/gallium/drivers/swr/rasterizer/core/frontend.cpp b/src/gallium/drivers/swr/rasterizer/core/frontend.cpp
> index ef90a24..17334e5 100644
> --- a/src/gallium/drivers/swr/rasterizer/core/frontend.cpp
> +++ b/src/gallium/drivers/swr/rasterizer/core/frontend.cpp
> @@ -1467,6 +1467,7 @@ INLINE void ProcessAttributes(
>       uint32_t mapIdx = 0;
>       LONG constantInterpMask = pDC->pState->state.backendState.constantInterpolationMask;
>       const uint32_t provokingVertex = pDC->pState->state.frontendState.topologyProvokingVertex;
> +    const PRIMITIVE_TOPOLOGY topo = pDC->pState->state.topology;
>
>       while (_BitScanForward(&slot, linkageMask))
>       {
> @@ -1476,18 +1477,51 @@ INLINE void ProcessAttributes(
>           uint32_t inputSlot = VERTEX_ATTRIB_START_SLOT + pLinkageMap[mapIdx];
>
>           __m128 attrib[3];    // triangle attribs (always 4 wide)
> -        pa.AssembleSingle(inputSlot, triIndex, attrib);
>
>           if (_bittest(&constantInterpMask, mapIdx))
>           {
> +            uint32_t vid;
> +            uint32_t tristripProvokingVertex[] = {0, 2, 1};
> +            int32_t quadProvokingTri[2][4] = {{0, 0, 0, 1}, {0, -1, 0, 0}};
> +            uint32_t quadProvokingVertex[2][4] = {{0, 1, 2, 2}, {0, 1, 1, 2}};
> +            int32_t qstripProvokingTri[2][4] = {{0, 0, 0, 1}, {-1, 0, 0, 0}};
> +            uint32_t qstripProvokingVertex[2][4] = {{0, 1, 2, 1}, {0, 0, 2, 1}};

I don't know any of this code, but declaring those arrays static const 
would avoid run-time initializations.

-Brian

> +
> +            switch (topo) {
> +            case TOP_QUAD_LIST:
> +                pa.AssembleSingle(inputSlot,
> +                                  triIndex + quadProvokingTri[triIndex & 1][provokingVertex],
> +                                  attrib);
> +                vid = quadProvokingVertex[triIndex & 1][provokingVertex];
> +                break;
> +            case TOP_QUAD_STRIP:
> +                pa.AssembleSingle(inputSlot,
> +                                  triIndex + qstripProvokingTri[triIndex & 1][provokingVertex],
> +                                  attrib);
> +                vid = qstripProvokingVertex[triIndex & 1][provokingVertex];
> +                break;
> +            case TOP_TRIANGLE_STRIP:
> +               pa.AssembleSingle(inputSlot, triIndex, attrib);
> +               vid = (triIndex & 1)
> +                   ? tristripProvokingVertex[provokingVertex]
> +                   : provokingVertex;
> +               break;
> +            default:
> +                pa.AssembleSingle(inputSlot, triIndex, attrib);
> +                vid = provokingVertex;
> +                break;
> +            }
> +
>               for (uint32_t i = 0; i < NumVerts; ++i)
>               {
> -                _mm_store_ps(pBuffer, attrib[provokingVertex]);
> +                _mm_store_ps(pBuffer, attrib[vid]);
>                   pBuffer += 4;
>               }
>           }
>           else
>           {
> +            pa.AssembleSingle(inputSlot, triIndex, attrib);
> +
>               for (uint32_t i = 0; i < NumVerts; ++i)
>               {
>                   _mm_store_ps(pBuffer, attrib[i]);
> diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp
> index 7a4c896..ab8d275 100644
> --- a/src/gallium/drivers/swr/swr_draw.cpp
> +++ b/src/gallium/drivers/swr/swr_draw.cpp
> @@ -162,6 +162,36 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
>      /* Set up frontend state
>       * XXX setup provokingVertex & topologyProvokingVertex */
>      SWR_FRONTEND_STATE feState = {0};
> +   if (ctx->rasterizer->flatshade_first) {
> +      feState.provokingVertex = {1, 0, 0};
> +   } else {
> +      feState.provokingVertex = {2, 1, 2};
> +   }
> +
> +   switch (info->mode) {
> +   case PIPE_PRIM_TRIANGLE_FAN:
> +      feState.topologyProvokingVertex = feState.provokingVertex.triFan;
> +      break;
> +   case PIPE_PRIM_TRIANGLE_STRIP:
> +   case PIPE_PRIM_TRIANGLES:
> +      feState.topologyProvokingVertex = feState.provokingVertex.triStripList;
> +      break;
> +   case PIPE_PRIM_QUAD_STRIP:
> +   case PIPE_PRIM_QUADS:
> +      if (ctx->rasterizer->flatshade_first)
> +         feState.topologyProvokingVertex = 0;
> +      else
> +         feState.topologyProvokingVertex = 3;
> +      break;
> +   case PIPE_PRIM_LINES:
> +   case PIPE_PRIM_LINE_LOOP:
> +   case PIPE_PRIM_LINE_STRIP:
> +      feState.topologyProvokingVertex = feState.provokingVertex.lineStripList;
> +      break;
> +   default:
> +      feState.topologyProvokingVertex = 0;
> +   }
> +
>      feState.bEnableCutIndex = info->primitive_restart;
>      SwrSetFrontendState(ctx->swrContext, &feState);
>
> diff --git a/src/gallium/drivers/swr/swr_screen.cpp b/src/gallium/drivers/swr/swr_screen.cpp
> index 0772274..fcf12fd 100644
> --- a/src/gallium/drivers/swr/swr_screen.cpp
> +++ b/src/gallium/drivers/swr/swr_screen.cpp
> @@ -239,7 +239,7 @@ swr_get_param(struct pipe_screen *screen, enum pipe_cap param)
>      case PIPE_CAP_GLSL_FEATURE_LEVEL:
>         return 330;
>      case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
> -      return 0;
> +      return 1;
>      case PIPE_CAP_COMPUTE:
>         return 0;
>      case PIPE_CAP_USER_VERTEX_BUFFERS:
> diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp
> index f693f51..f26467e 100644
> --- a/src/gallium/drivers/swr/swr_shader.cpp
> +++ b/src/gallium/drivers/swr/swr_shader.cpp
> @@ -102,7 +102,6 @@ swr_generate_fs_key(struct swr_jit_fs_key &key,
>
>      key.nr_cbufs = ctx->framebuffer.nr_cbufs;
>      key.light_twoside = ctx->rasterizer->light_twoside;
> -   key.flatshade = ctx->rasterizer->flatshade;
>      memcpy(&key.vs_output_semantic_name,
>             &ctx->vs->info.base.output_semantic_name,
>             sizeof(key.vs_output_semantic_name));
> @@ -351,15 +350,13 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
>         GEP(hPrivateData, {0, swr_draw_context_num_constantsFS});
>      const_sizes_ptr->setName("num_fs_constants");
>
> -   // xxx should check for flat shading versus interpolation
> -
> -
>      // load *pAttribs, *pPerspAttribs
>      Value *pRawAttribs = LOAD(pPS, {0, SWR_PS_CONTEXT_pAttribs}, "pRawAttribs");
>      Value *pPerspAttribs =
>         LOAD(pPS, {0, SWR_PS_CONTEXT_pPerspAttribs}, "pPerspAttribs");
>
>      swr_fs->constantMask = 0;
> +   swr_fs->flatConstantMask = 0;
>      swr_fs->pointSpriteMask = 0;
>
>      for (int attrib = 0; attrib < PIPE_MAX_SHADER_INPUTS; attrib++) {
> @@ -457,6 +454,8 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
>
>         if (interpMode == TGSI_INTERPOLATE_CONSTANT) {
>            swr_fs->constantMask |= 1 << linkedAttrib;
> +      } else if (interpMode == TGSI_INTERPOLATE_COLOR) {
> +         swr_fs->flatConstantMask |= 1 << linkedAttrib;
>         }
>
>         for (int channel = 0; channel < TGSI_NUM_CHANNELS; channel++) {
> @@ -484,6 +483,8 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
>
>                  if (interpMode == TGSI_INTERPOLATE_CONSTANT) {
>                     swr_fs->constantMask |= 1 << bcolorAttrib;
> +               } else if (interpMode == TGSI_INTERPOLATE_COLOR) {
> +                  swr_fs->flatConstantMask |= 1 << bcolorAttrib;
>                  }
>               }
>
> @@ -493,9 +494,6 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
>
>               if (interpMode == TGSI_INTERPOLATE_CONSTANT) {
>                  inputs[attrib][channel] = wrap(va);
> -            } else if ((interpMode == TGSI_INTERPOLATE_COLOR) &&
> -                       (key.flatshade == true)) {
> -               inputs[attrib][channel] = wrap(vc);
>               } else {
>                  Value *vk = FSUB(FSUB(VIMMED1(1.0f), vi), vj);
>
> diff --git a/src/gallium/drivers/swr/swr_shader.h b/src/gallium/drivers/swr/swr_shader.h
> index 11d50c3..1b604b5 100644
> --- a/src/gallium/drivers/swr/swr_shader.h
> +++ b/src/gallium/drivers/swr/swr_shader.h
> @@ -51,7 +51,6 @@ struct swr_jit_sampler_key {
>   struct swr_jit_fs_key : swr_jit_sampler_key {
>      unsigned nr_cbufs;
>      unsigned light_twoside;
> -   unsigned flatshade;
>      ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
>      ubyte vs_output_semantic_idx[PIPE_MAX_SHADER_OUTPUTS];
>   };
> diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp
> index f9326f3..f50537f 100644
> --- a/src/gallium/drivers/swr/swr_state.cpp
> +++ b/src/gallium/drivers/swr/swr_state.cpp
> @@ -1351,7 +1351,10 @@ swr_update_derived(struct pipe_context *pipe,
>      SWR_BACKEND_STATE backendState = {0};
>      backendState.numAttributes = 1;
>      backendState.numComponents[0] = 4;
> -   backendState.constantInterpolationMask = ctx->fs->constantMask;
> +   backendState.constantInterpolationMask =
> +      ctx->rasterizer->flatshade ?
> +      ctx->fs->flatConstantMask :
> +      ctx->fs->constantMask;
>      backendState.pointSpriteTexCoordMask = ctx->fs->pointSpriteMask;
>
>      SwrSetBackendState(ctx->swrContext, &backendState);
> diff --git a/src/gallium/drivers/swr/swr_state.h b/src/gallium/drivers/swr/swr_state.h
> index 82ee20f..cb69964 100644
> --- a/src/gallium/drivers/swr/swr_state.h
> +++ b/src/gallium/drivers/swr/swr_state.h
> @@ -63,6 +63,7 @@ struct swr_fragment_shader {
>      struct pipe_shader_state pipe;
>      struct lp_tgsi_info info;
>      uint32_t constantMask;
> +   uint32_t flatConstantMask;
>      uint32_t pointSpriteMask;
>      std::unordered_map<swr_jit_fs_key, std::unique_ptr<VariantFS>> map;
>   };
>



More information about the mesa-dev mailing list