Commit 18c9ac49 by Nicolas Capens Committed by Nicolas Capens

Optimize non-solid polygon rasterization

Instead of using a batch size of 1, divide the batch size by 3 so that we have enough room for 3x more primitives to render. Also use local Triangle data structures to copy the vertices for the extra primitives, instead of adding them to the input batch. Bug: b/139872671 Change-Id: I1bc860d291b53fdd266b6c018ac0c47c876aaa09 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/35588Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 2210f804
...@@ -217,11 +217,11 @@ namespace sw ...@@ -217,11 +217,11 @@ namespace sw
break; break;
case VK_POLYGON_MODE_LINE: case VK_POLYGON_MODE_LINE:
setupPrimitives = &DrawCall::setupWireframeTriangles; setupPrimitives = &DrawCall::setupWireframeTriangles;
numPrimitivesPerBatch = 1; numPrimitivesPerBatch /= 3;
break; break;
case VK_POLYGON_MODE_POINT: case VK_POLYGON_MODE_POINT:
setupPrimitives = &DrawCall::setupPointTriangles; setupPrimitives = &DrawCall::setupPointTriangles;
numPrimitivesPerBatch = 1; numPrimitivesPerBatch /= 3;
break; break;
default: default:
UNSUPPORTED("polygon mode: %d", int(context->polygonMode)); UNSUPPORTED("polygon mode: %d", int(context->polygonMode));
...@@ -631,39 +631,42 @@ namespace sw ...@@ -631,39 +631,42 @@ namespace sw
int ms = state.multiSample; int ms = state.multiSample;
int visible = 0; int visible = 0;
const Vertex &v0 = triangles[0].v0; for(int i = 0; i < count; i++)
const Vertex &v1 = triangles[0].v1;
const Vertex &v2 = triangles[0].v2;
float d = (v0.position.y * v1.position.x - v0.position.x * v1.position.y) * v2.position.w +
(v0.position.x * v2.position.y - v0.position.y * v2.position.x) * v1.position.w +
(v2.position.x * v1.position.y - v1.position.x * v2.position.y) * v0.position.w;
bool frontFacing = (state.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE) ? d > 0.0f : d < 0.0f;
if(state.cullMode & VK_CULL_MODE_FRONT_BIT)
{
if(frontFacing) return 0;
}
if(state.cullMode & VK_CULL_MODE_BACK_BIT)
{ {
if(!frontFacing) return 0; const Vertex &v0 = triangles[i].v0;
} const Vertex &v1 = triangles[i].v1;
const Vertex &v2 = triangles[i].v2;
// Copy attributes float d = (v0.y * v1.x - v0.x * v1.y) * v2.w +
triangles[1].v0 = v1; (v0.x * v2.y - v0.y * v2.x) * v1.w +
triangles[1].v1 = v2; (v2.x * v1.y - v1.x * v2.y) * v0.w;
triangles[2].v0 = v2;
triangles[2].v1 = v0;
for(int i = 0; i < 3; i++) bool frontFacing = (state.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE) ? (d > 0) : (d < 0);
{ if(state.cullMode & VK_CULL_MODE_FRONT_BIT)
if(setupLine(*primitives, *triangles, *drawCall))
{ {
primitives += ms; if(frontFacing) continue;
visible++; }
if(state.cullMode & VK_CULL_MODE_BACK_BIT)
{
if(!frontFacing) continue;
} }
triangles++; Triangle lines[3];
lines[0].v0 = v0;
lines[0].v1 = v1;
lines[1].v0 = v1;
lines[1].v1 = v2;
lines[2].v0 = v2;
lines[2].v1 = v0;
for(int i = 0; i < 3; i++)
{
if(setupLine(*primitives, lines[i], *drawCall))
{
primitives += ms;
visible++;
}
}
} }
return visible; return visible;
...@@ -676,37 +679,39 @@ namespace sw ...@@ -676,37 +679,39 @@ namespace sw
int ms = state.multiSample; int ms = state.multiSample;
int visible = 0; int visible = 0;
const Vertex &v0 = triangles[0].v0; for(int i = 0; i < count; i++)
const Vertex &v1 = triangles[0].v1;
const Vertex &v2 = triangles[0].v2;
float d = (v0.position.y * v1.position.x - v0.position.x * v1.position.y) * v2.position.w +
(v0.position.x * v2.position.y - v0.position.y * v2.position.x) * v1.position.w +
(v2.position.x * v1.position.y - v1.position.x * v2.position.y) * v0.position.w;
bool frontFacing = (state.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE) ? d > 0.0f : d < 0.0f;
if(state.cullMode & VK_CULL_MODE_FRONT_BIT)
{
if(frontFacing) return 0;
}
if(state.cullMode & VK_CULL_MODE_BACK_BIT)
{ {
if(!frontFacing) return 0; const Vertex &v0 = triangles[i].v0;
} const Vertex &v1 = triangles[i].v1;
const Vertex &v2 = triangles[i].v2;
// Copy attributes float d = (v0.y * v1.x - v0.x * v1.y) * v2.w +
triangles[1].v0 = v1; (v0.x * v2.y - v0.y * v2.x) * v1.w +
triangles[2].v0 = v2; (v2.x * v1.y - v1.x * v2.y) * v0.w;
for(int i = 0; i < 3; i++) bool frontFacing = (state.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE) ? (d > 0) : (d < 0);
{ if(state.cullMode & VK_CULL_MODE_FRONT_BIT)
if(setupPoint(*primitives, *triangles, *drawCall))
{ {
primitives += ms; if(frontFacing) continue;
visible++; }
if(state.cullMode & VK_CULL_MODE_BACK_BIT)
{
if(!frontFacing) continue;
} }
triangles++; Triangle points[3];
points[0].v0 = v0;
points[1].v0 = v1;
points[2].v0 = v2;
for(int i = 0; i < 3; i++)
{
if(setupPoint(*primitives, points[i], *drawCall))
{
primitives += ms;
visible++;
}
}
} }
return visible; return visible;
......
...@@ -23,7 +23,19 @@ namespace sw ...@@ -23,7 +23,19 @@ namespace sw
{ {
ALIGN(16, struct Vertex ALIGN(16, struct Vertex
{ {
float4 position; union
{
struct
{
float x;
float y;
float z;
float w;
};
float4 position;
};
float pointSize; float pointSize;
int clipFlags; int clipFlags;
......
...@@ -86,9 +86,9 @@ namespace sw ...@@ -86,9 +86,9 @@ namespace sw
Return(0); Return(0);
} }
Int w0w1w2 = *Pointer<Int>(v0 + OFFSET(Vertex, position.w)) ^ Int w0w1w2 = *Pointer<Int>(v0 + OFFSET(Vertex, w)) ^
*Pointer<Int>(v1 + OFFSET(Vertex, position.w)) ^ *Pointer<Int>(v1 + OFFSET(Vertex, w)) ^
*Pointer<Int>(v2 + OFFSET(Vertex, position.w)); *Pointer<Int>(v2 + OFFSET(Vertex, w));
A = IfThenElse(w0w1w2 < 0, -A, A); A = IfThenElse(w0w1w2 < 0, -A, A);
...@@ -268,9 +268,9 @@ namespace sw ...@@ -268,9 +268,9 @@ namespace sw
// Sort by minimum y // Sort by minimum y
if(triangle) if(triangle)
{ {
Float y0 = *Pointer<Float>(v0 + OFFSET(Vertex, position.y)); Float y0 = *Pointer<Float>(v0 + OFFSET(Vertex, y));
Float y1 = *Pointer<Float>(v1 + OFFSET(Vertex, position.y)); Float y1 = *Pointer<Float>(v1 + OFFSET(Vertex, y));
Float y2 = *Pointer<Float>(v2 + OFFSET(Vertex, position.y)); Float y2 = *Pointer<Float>(v2 + OFFSET(Vertex, y));
Float yMin = Min(Min(y0, y1), y2); Float yMin = Min(Min(y0, y1), y2);
...@@ -281,9 +281,9 @@ namespace sw ...@@ -281,9 +281,9 @@ namespace sw
// Sort by maximum w // Sort by maximum w
if(triangle) if(triangle)
{ {
Float w0 = *Pointer<Float>(v0 + OFFSET(Vertex, position.w)); Float w0 = *Pointer<Float>(v0 + OFFSET(Vertex, w));
Float w1 = *Pointer<Float>(v1 + OFFSET(Vertex, position.w)); Float w1 = *Pointer<Float>(v1 + OFFSET(Vertex, w));
Float w2 = *Pointer<Float>(v2 + OFFSET(Vertex, position.w)); Float w2 = *Pointer<Float>(v2 + OFFSET(Vertex, w));
Float wMax = Max(Max(w0, w1), w2); Float wMax = Max(Max(w0, w1), w2);
...@@ -292,13 +292,13 @@ namespace sw ...@@ -292,13 +292,13 @@ namespace sw
} }
*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordX)) = *Pointer<Float>(primitive + OFFSET(Primitive, pointCoordX)) =
*Pointer<Float>(v0 + OFFSET(Vertex, position.x)); *Pointer<Float>(v0 + OFFSET(Vertex, x));
*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordY)) = *Pointer<Float>(primitive + OFFSET(Primitive, pointCoordY)) =
*Pointer<Float>(v0 + OFFSET(Vertex, position.y)); *Pointer<Float>(v0 + OFFSET(Vertex, y));
Float w0 = *Pointer<Float>(v0 + OFFSET(Vertex, position.w)); Float w0 = *Pointer<Float>(v0 + OFFSET(Vertex, w));
Float w1 = *Pointer<Float>(v1 + OFFSET(Vertex, position.w)); Float w1 = *Pointer<Float>(v1 + OFFSET(Vertex, w));
Float w2 = *Pointer<Float>(v2 + OFFSET(Vertex, position.w)); Float w2 = *Pointer<Float>(v2 + OFFSET(Vertex, w));
Float4 w012; Float4 w012;
...@@ -443,11 +443,13 @@ namespace sw ...@@ -443,11 +443,13 @@ namespace sw
for (int interpolant = 0; interpolant < MAX_INTERFACE_COMPONENTS; interpolant++) for (int interpolant = 0; interpolant < MAX_INTERFACE_COMPONENTS; interpolant++)
{ {
if (state.gradient[interpolant].Type != SpirvShader::ATTRIBTYPE_UNUSED) if (state.gradient[interpolant].Type != SpirvShader::ATTRIBTYPE_UNUSED)
{
setupGradient(primitive, tri, w012, M, v0, v1, v2, setupGradient(primitive, tri, w012, M, v0, v1, v2,
OFFSET(Vertex, v[interpolant]), OFFSET(Vertex, v[interpolant]),
OFFSET(Primitive, V[interpolant]), OFFSET(Primitive, V[interpolant]),
state.gradient[interpolant].Flat, state.gradient[interpolant].Flat,
!state.gradient[interpolant].NoPerspective, 0); !state.gradient[interpolant].NoPerspective, 0);
}
} }
Return(1); Return(1);
......
...@@ -397,7 +397,8 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn ...@@ -397,7 +397,8 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn
const VkPipelineMultisampleStateCreateInfo* multisampleState = pCreateInfo->pMultisampleState; const VkPipelineMultisampleStateCreateInfo* multisampleState = pCreateInfo->pMultisampleState;
if(multisampleState) if(multisampleState)
{ {
switch (multisampleState->rasterizationSamples) { switch (multisampleState->rasterizationSamples)
{
case VK_SAMPLE_COUNT_1_BIT: case VK_SAMPLE_COUNT_1_BIT:
context.sampleCount = 1; context.sampleCount = 1;
break; break;
...@@ -409,7 +410,9 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn ...@@ -409,7 +410,9 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn
} }
if (multisampleState->pSampleMask) if (multisampleState->pSampleMask)
{
context.sampleMask = multisampleState->pSampleMask[0]; context.sampleMask = multisampleState->pSampleMask[0];
}
context.alphaToCoverage = (multisampleState->alphaToCoverageEnable == VK_TRUE); context.alphaToCoverage = (multisampleState->alphaToCoverageEnable == VK_TRUE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment