Implement input coverage mask
- Take the pipeline's multisample mask into account when generating
cMask
- Wire up cMask to the BuiltInSampleMask input
Bug: b/118386749
Test: dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.pattern.*
Change-Id: Ia65ba31c6a73f87f537164c69e2d3086b82ea27e
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/32528
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Device/QuadRasterizer.cpp b/src/Device/QuadRasterizer.cpp
index 9e0d5da..b52c276 100644
--- a/src/Device/QuadRasterizer.cpp
+++ b/src/Device/QuadRasterizer.cpp
@@ -199,8 +199,15 @@
for(unsigned int q = 0; q < state.multiSample; q++)
{
- Short4 mask = CmpGT(xxxx, xLeft[q]) & CmpGT(xRight[q], xxxx);
- cMask[q] = SignMask(PackSigned(mask, mask)) & 0x0000000F;
+ if (state.multiSampleMask & (1<<q))
+ {
+ Short4 mask = CmpGT(xxxx, xLeft[q]) & CmpGT(xRight[q], xxxx);
+ cMask[q] = SignMask(PackSigned(mask, mask)) & 0x0000000F;
+ }
+ else
+ {
+ cMask[q] = 0;
+ }
}
quad(cBuffer, zBuffer, sBuffer, cMask, x, y);
diff --git a/src/Pipeline/PixelProgram.cpp b/src/Pipeline/PixelProgram.cpp
index a086774..38f7222 100644
--- a/src/Pipeline/PixelProgram.cpp
+++ b/src/Pipeline/PixelProgram.cpp
@@ -85,6 +85,25 @@
routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<Float4>(frontFacing);
}
+ it = spirvShader->inputBuiltins.find(spv::BuiltInSampleMask);
+ if (it != spirvShader->inputBuiltins.end())
+ {
+ static_assert(SIMD::Width == 4, "Expects SIMD width to be 4");
+ Int4 laneBits = Int4(1, 2, 4, 8);
+
+ Int4 inputSampleMask = Int4(1) & CmpNEQ(Int4(cMask[0]) & laneBits, Int4(0));
+ for (auto i = 1u; i < state.multiSample; i++)
+ {
+ inputSampleMask |= Int4(1 << i) & CmpNEQ(Int4(cMask[i]) & laneBits, Int4(0));
+ }
+
+ routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<Float4>(inputSampleMask);
+ // Sample mask input is an array, as the spec contemplates MSAA levels higher than 32.
+ // Fill any non-zero indices with 0.
+ for (auto i = 1u; i < it->second.SizeInComponents; i++)
+ routine.getVariable(it->second.Id)[it->second.FirstComponent + i] = Float4(0);
+ }
+
// Note: all lanes initially active to facilitate derivatives etc. Actual coverage is
// handled separately, through the cMask.
auto activeLaneMask = SIMD::Int(0xFFFFFFFF);