Commit ed65dc43 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: implement glSampleCoverage

Emulated by applying a mask on top of the mask from glSampleMask. Bug: angleproject:3204 Change-Id: I4c80ab0a3261cbf1b8a43c270fe13c2a247ea663 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1639749Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent b407e1a0
...@@ -93,6 +93,41 @@ void InitializeSubmitInfo(VkSubmitInfo *submitInfo, ...@@ -93,6 +93,41 @@ void InitializeSubmitInfo(VkSubmitInfo *submitInfo,
submitInfo->pSignalSemaphores = signalSemaphores.data(); submitInfo->pSignalSemaphores = signalSemaphores.data();
} }
uint32_t GetCoverageSampleCount(const gl::State &glState, FramebufferVk *drawFramebuffer)
{
if (!glState.isSampleCoverageEnabled())
{
return 0;
}
// Get a fraction of the samples based on the coverage parameters.
return static_cast<uint32_t>(
std::round(glState.getSampleCoverageValue() * drawFramebuffer->getSamples()));
}
void ApplySampleCoverage(const gl::State &glState,
uint32_t coverageSampleCount,
uint32_t maskNumber,
uint32_t *maskOut)
{
if (!glState.isSampleCoverageEnabled())
{
return;
}
uint32_t maskBitOffset = maskNumber * 32;
uint32_t coverageMask = coverageSampleCount >= (maskBitOffset + 32)
? std::numeric_limits<uint32_t>::max()
: (1u << (coverageSampleCount - maskBitOffset)) - 1;
if (glState.getSampleCoverageInvert())
{
coverageMask = ~coverageMask;
}
*maskOut &= coverageMask;
}
} // anonymous namespace } // anonymous namespace
// std::array only uses aggregate init. Thus we make a helper macro to reduce on code duplication. // std::array only uses aggregate init. Thus we make a helper macro to reduce on code duplication.
...@@ -1259,10 +1294,18 @@ void ContextVk::updateColorMask(const gl::BlendState &blendState) ...@@ -1259,10 +1294,18 @@ void ContextVk::updateColorMask(const gl::BlendState &blendState)
void ContextVk::updateSampleMask(const gl::State &glState) void ContextVk::updateSampleMask(const gl::State &glState)
{ {
// If sample coverage is enabled, emulate it by generating and applying a mask on top of the
// sample mask.
uint32_t coverageSampleCount = GetCoverageSampleCount(glState, mDrawFramebuffer);
static_assert(sizeof(uint32_t) == sizeof(GLbitfield), "Vulkan assumes 32-bit sample masks");
for (uint32_t maskNumber = 0; maskNumber < glState.getMaxSampleMaskWords(); ++maskNumber) for (uint32_t maskNumber = 0; maskNumber < glState.getMaxSampleMaskWords(); ++maskNumber)
{ {
static_assert(sizeof(uint32_t) == sizeof(GLbitfield), "Vulkan assumes 32-bit sample masks"); uint32_t mask = glState.isSampleMaskEnabled() ? glState.getSampleMaskWord(maskNumber)
uint32_t mask = glState.isSampleMaskEnabled() ? glState.getSampleMaskWord(maskNumber) : 0; : std::numeric_limits<uint32_t>::max();
ApplySampleCoverage(glState, coverageSampleCount, maskNumber, &mask);
mGraphicsPipelineDesc->updateSampleMask(&mGraphicsPipelineTransition, maskNumber, mask); mGraphicsPipelineDesc->updateSampleMask(&mGraphicsPipelineTransition, maskNumber, mask);
} }
} }
...@@ -1375,33 +1418,10 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -1375,33 +1418,10 @@ angle::Result ContextVk::syncState(const gl::Context *context,
&mGraphicsPipelineTransition, glState.isSampleAlphaToCoverageEnabled()); &mGraphicsPipelineTransition, glState.isSampleAlphaToCoverageEnabled());
break; break;
case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED: case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
// TODO(syoussefi): glSampleCoverage and `GL_SAMPLE_COVERAGE` have a similar updateSampleMask(glState);
// behavior to alphaToCoverage, without native support in Vulkan. Sample coverage
// results in a mask that's applied *on top of* alphaToCoverage. More importantly,
// glSampleCoverage can choose to invert the applied mask; a feature that's not
// easily emulatable. For example, say there are 4 samples {0, 1, 2, 3} and
// alphaToCoverage (both in GL and Vulkan, as well as sampleCoverage in GL) is
// implemented such that the alpha value selects the set of samples
// {0, ..., round(alpha * 4)}. With glSampleCoverage, an application can blend two
// object LODs as such the following, covering all samples in a pixel:
//
// glSampleCoverage(0.5, GL_FALSE); // covers samples {0, 1}
// drawLOD0();
// glSampleCoverage(0.5, GL_TRUE); // covers samples {2, 3}
// drawLOD1();
//
// In Vulkan, it's not possible to restrict drawing to samples {2, 3} through
// alphaToCoverage alone.
//
// One way to acheive this behavior is to modify the shader to output to
// gl_SampleMask with values we emulate for sample coverage, taking inversion
// into account.
//
// http://anglebug.com/3204
break; break;
case gl::State::DIRTY_BIT_SAMPLE_COVERAGE: case gl::State::DIRTY_BIT_SAMPLE_COVERAGE:
// TODO(syoussefi): See DIRTY_BIT_SAMPLE_COVERAGE_ENABLED. updateSampleMask(glState);
// http://anglebug.com/3204
break; break;
case gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED: case gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED:
updateSampleMask(glState); updateSampleMask(glState);
......
...@@ -709,8 +709,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -709,8 +709,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
multisampleState.sampleShadingEnable = multisampleState.sampleShadingEnable =
static_cast<VkBool32>(rasterAndMS.bits.sampleShadingEnable); static_cast<VkBool32>(rasterAndMS.bits.sampleShadingEnable);
multisampleState.minSampleShading = rasterAndMS.minSampleShading; multisampleState.minSampleShading = rasterAndMS.minSampleShading;
// TODO(jmadill): sample masks multisampleState.pSampleMask = rasterAndMS.sampleMask;
multisampleState.pSampleMask = nullptr;
multisampleState.alphaToCoverageEnable = multisampleState.alphaToCoverageEnable =
static_cast<VkBool32>(rasterAndMS.bits.alphaToCoverageEnable); static_cast<VkBool32>(rasterAndMS.bits.alphaToCoverageEnable);
multisampleState.alphaToOneEnable = static_cast<VkBool32>(rasterAndMS.bits.alphaToOneEnable); multisampleState.alphaToOneEnable = static_cast<VkBool32>(rasterAndMS.bits.alphaToOneEnable);
......
...@@ -544,20 +544,6 @@ ...@@ -544,20 +544,6 @@
3189 VULKAN : dEQP-GLES3.functional.texture.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.texture.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.* = SKIP
// Multisampling:
3204 VULKAN : dEQP-GLES3.functional.multisample.default_framebuffer.sample_coverage_invert = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.default_framebuffer.proportionality_sample_coverage = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.default_framebuffer.proportionality_sample_coverage_inverted = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_4_samples.sample_coverage_invert = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_4_samples.proportionality_sample_coverage = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_4_samples.proportionality_sample_coverage_inverted = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_8_samples.sample_coverage_invert = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_8_samples.proportionality_sample_coverage = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_8_samples.proportionality_sample_coverage_inverted = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_max_samples.sample_coverage_invert = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_max_samples.proportionality_sample_coverage = FAIL
3204 VULKAN : dEQP-GLES3.functional.multisample.fbo_max_samples.proportionality_sample_coverage_inverted = FAIL
// Formats: // Formats:
2950 VULKAN : dEQP-GLES3.functional.fbo.completeness.renderable.renderbuffer.color0.rgba32f = FAIL 2950 VULKAN : dEQP-GLES3.functional.fbo.completeness.renderable.renderbuffer.color0.rgba32f = FAIL
2950 VULKAN : dEQP-GLES3.functional.fbo.completeness.renderable.texture.color0.rgba32f = FAIL 2950 VULKAN : dEQP-GLES3.functional.fbo.completeness.renderable.texture.color0.rgba32f = FAIL
......
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