Reviewed-by: Bruce Cherniak <[email protected]> > On Jun 3, 2016, at 12:39 PM, Rowley, Timothy O <[email protected]> > wrote: > > Use rasterizer provoking vertex API. > > Fix rasterizer provoking vertex for tristrips and quad list/strips. > > v2: make provoking vertex tables static const > --- > .../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..6e1bc0e 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 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; > }; > -- > 1.9.1 >
_______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
