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);