Support SampleId and SamplePosition builtins The sampleRateShading feature adds new builtins variables which have to be supported: BuiltInSampleId and BuiltInSamplePosition. This cl sets the values for these builtins properly and turns on per sample rendering where either of these is persent in the shader. Bug: b/171415086 Change-Id: I959e80722493d12213be349019a0cc3a108a7596 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51735 Tested-by: Alexis Hétu <sugoi@google.com> Commit-Queue: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/PixelProgram.cpp b/src/Pipeline/PixelProgram.cpp index 5066996..bdc3da7 100644 --- a/src/Pipeline/PixelProgram.cpp +++ b/src/Pipeline/PixelProgram.cpp
@@ -170,6 +170,22 @@ routine.getVariable(it->second.Id)[it->second.FirstComponent + i] = Float4(0); } + it = spirvShader->inputBuiltins.find(spv::BuiltInSampleId); + if(it != spirvShader->inputBuiltins.end()) + { + routine.getVariable(it->second.Id)[it->second.FirstComponent] = + As<SIMD::Float>(SIMD::Int((sampleId >= 0) ? sampleId : 0)); + } + + it = spirvShader->inputBuiltins.find(spv::BuiltInSamplePosition); + if(it != spirvShader->inputBuiltins.end()) + { + routine.getVariable(it->second.Id)[it->second.FirstComponent + 0] = + SIMD::Float(((sampleId >= 0) && (state.multiSampleCount > 1)) ? Constants::VkSampleLocations4[sampleId][0] : 0.5f); + routine.getVariable(it->second.Id)[it->second.FirstComponent + 1] = + SIMD::Float(((sampleId >= 0) && (state.multiSampleCount > 1)) ? Constants::VkSampleLocations4[sampleId][1] : 0.5f); + } + // Note: all lanes initially active to facilitate derivatives etc. Actual coverage is // handled separately, through the cMask. auto activeLaneMask = SIMD::Int(0xFFFFFFFF);
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp index 9864c01..7272825 100644 --- a/src/Pipeline/PixelRoutine.cpp +++ b/src/Pipeline/PixelRoutine.cpp
@@ -62,9 +62,28 @@ Int zMask[4]; // Depth mask Int sMask[4]; // Stencil mask + bool sampleShadingEnabled = state.sampleShadingEnabled; + float minSampleShading = state.minSampleShading; + if(spirvShader) + { + // SampleId and SamplePosition built-ins require the sampleRateShading feature, so the Vulkan spec + // requires turning on per sample shading if either of them is present in the shader. + + // "If a fragment shader entry point's interface includes an input variable decorated with SampleId, + // Sample Shading is considered enabled with a minSampleShading value of 1.0." + + // "If a fragment shader entry point's interface includes an input variable decorated with SamplePosition, + // Sample Shading is considered enabled with a minSampleShading value of 1.0." + if(spirvShader->hasBuiltinInput(spv::BuiltInSampleId) || spirvShader->hasBuiltinInput(spv::BuiltInSamplePosition)) + { + sampleShadingEnabled = true; + minSampleShading = 1.0f; + } + } + bool shaderContainsInterpolation = spirvShader && spirvShader->getUsedCapabilities().InterpolationFunction; bool shaderContainsSampleQualifier = spirvShader && spirvShader->getModes().ContainsSampleQualifier; - bool perSampleShading = (state.sampleShadingEnabled && (state.minSampleShading > 0.0f)) || + bool perSampleShading = (sampleShadingEnabled && (minSampleShading > 0.0f)) || shaderContainsInterpolation || shaderContainsSampleQualifier; unsigned int numSampleRenders = perSampleShading ? state.multiSampleCount : 1;