mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 21:50:12 +01:00
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 <bruce.cherniak@intel.com>
This commit is contained in:
parent
c81b090c92
commit
87f0a0448f
7 changed files with 77 additions and 12 deletions
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue