From 87f0a0448fba898a7ab2a36eed9682ff8c1c6d5c Mon Sep 17 00:00:00 2001 From: Tim Rowley Date: Wed, 1 Jun 2016 09:56:26 -0500 Subject: [PATCH] swr: fix provoking vertex Use rasterizer provoking vertex API. Fix rasterizer provoking vertex for tristrips and quad list/strips. v2: make provoking vertex tables static const Reviewed-by: Bruce Cherniak --- .../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 ef90a24fe75..6e1bc0e3d27 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; + static const uint32_t tristripProvokingVertex[] = {0, 2, 1}; + static const int32_t quadProvokingTri[2][4] = {{0, 0, 0, 1}, {0, -1, 0, 0}}; + static const uint32_t quadProvokingVertex[2][4] = {{0, 1, 2, 2}, {0, 1, 1, 2}}; + static const int32_t qstripProvokingTri[2][4] = {{0, 0, 0, 1}, {-1, 0, 0, 0}}; + static const uint32_t qstripProvokingVertex[2][4] = {{0, 1, 2, 1}, {0, 0, 2, 1}}; + + 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 7a4c89626fb..ab8d2750623 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 361b17ac55b..ca3920240fb 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 f693f51bb49..f26467e078e 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 11d50c3848f..1b604b5a3c2 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 f9326f35230..f50537f3a61 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 82ee20f73c1..cb699641274 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> map; }; -- 2.30.2