From 225a2b46b0f27376b537fc3c4eb68ae44b713a5e Mon Sep 17 00:00:00 2001 From: Tomek Ponitka Date: Wed, 29 Jul 2020 08:19:59 +0000 Subject: [PATCH] Enabling sampleMask usage in RenderPipelineMTL Added the sampleMask functionality in Metal. Bug: dawn:491 Change-Id: Id4a14d0cc715dc701c6f29e4588ce327c5b26cba Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/25481 Reviewed-by: Corentin Wallez Reviewed-by: Austin Eng Commit-Queue: Tomek Ponitka --- src/dawn_native/metal/RenderPipelineMTL.mm | 3 ++- src/dawn_native/metal/ShaderModuleMTL.h | 5 +++-- src/dawn_native/metal/ShaderModuleMTL.mm | 16 +++++++++++----- src/tests/end2end/MultisampledRenderingTests.cpp | 15 --------------- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/dawn_native/metal/RenderPipelineMTL.mm b/src/dawn_native/metal/RenderPipelineMTL.mm index 9deba399bd..c4eb5bc987 100644 --- a/src/dawn_native/metal/RenderPipelineMTL.mm +++ b/src/dawn_native/metal/RenderPipelineMTL.mm @@ -344,7 +344,8 @@ namespace dawn_native { namespace metal { const char* fragmentEntryPoint = descriptor->fragmentStage->entryPoint; ShaderModule::MetalFunctionData fragmentData; DAWN_TRY(fragmentModule->GetFunction(fragmentEntryPoint, SingleShaderStage::Fragment, - ToBackend(GetLayout()), &fragmentData)); + ToBackend(GetLayout()), &fragmentData, + descriptor->sampleMask)); descriptorMTL.fragmentFunction = fragmentData.function; if (fragmentData.needsStorageBufferLength) { diff --git a/src/dawn_native/metal/ShaderModuleMTL.h b/src/dawn_native/metal/ShaderModuleMTL.h index d4d41abc68..7460727cf8 100644 --- a/src/dawn_native/metal/ShaderModuleMTL.h +++ b/src/dawn_native/metal/ShaderModuleMTL.h @@ -46,14 +46,15 @@ namespace dawn_native { namespace metal { MaybeError GetFunction(const char* functionName, SingleShaderStage functionStage, const PipelineLayout* layout, - MetalFunctionData* out); + MetalFunctionData* out, + uint32_t sampleMask = 0xFFFFFFFF); private: ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor); ~ShaderModule() override = default; MaybeError Initialize(); - shaderc_spvc::CompileOptions GetMSLCompileOptions(); + shaderc_spvc::CompileOptions GetMSLCompileOptions(uint32_t sampleMask = 0xFFFFFFFF); }; }} // namespace dawn_native::metal diff --git a/src/dawn_native/metal/ShaderModuleMTL.mm b/src/dawn_native/metal/ShaderModuleMTL.mm index 5f69a0cd8e..bb3dffa9f8 100644 --- a/src/dawn_native/metal/ShaderModuleMTL.mm +++ b/src/dawn_native/metal/ShaderModuleMTL.mm @@ -91,7 +91,8 @@ namespace dawn_native { namespace metal { MaybeError ShaderModule::GetFunction(const char* functionName, SingleShaderStage functionStage, const PipelineLayout* layout, - ShaderModule::MetalFunctionData* out) { + ShaderModule::MetalFunctionData* out, + uint32_t sampleMask) { ASSERT(!IsError()); ASSERT(out); const std::vector& spirv = GetSpirv(); @@ -101,9 +102,10 @@ namespace dawn_native { namespace metal { if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { // Initializing the compiler is needed every call, because this method uses reflection // to mutate the compiler's IR. - DAWN_TRY(CheckSpvcSuccess( - mSpvcContext.InitializeForMsl(spirv.data(), spirv.size(), GetMSLCompileOptions()), - "Unable to initialize instance of spvc")); + DAWN_TRY( + CheckSpvcSuccess(mSpvcContext.InitializeForMsl(spirv.data(), spirv.size(), + GetMSLCompileOptions(sampleMask)), + "Unable to initialize instance of spvc")); DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetCompiler(reinterpret_cast(&compiler)), "Unable to get cross compiler")); } else { @@ -122,6 +124,8 @@ namespace dawn_native { namespace metal { // the shader storage buffer lengths. options_msl.buffer_size_buffer_index = kBufferLengthBufferSlot; + options_msl.additional_fixed_sample_mask = sampleMask; + compilerImpl = std::make_unique(spirv); compiler = compilerImpl.get(); compiler->set_msl_options(options_msl); @@ -245,7 +249,7 @@ namespace dawn_native { namespace metal { return {}; } - shaderc_spvc::CompileOptions ShaderModule::GetMSLCompileOptions() { + shaderc_spvc::CompileOptions ShaderModule::GetMSLCompileOptions(uint32_t sampleMask) { // If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to // be updated. shaderc_spvc::CompileOptions options = GetCompileOptions(); @@ -261,6 +265,8 @@ namespace dawn_native { namespace metal { // the shader storage buffer lengths. options.SetMSLBufferSizeBufferIndex(kBufferLengthBufferSlot); + options.SetMSLAdditionalFixedSampleMask(sampleMask); + return options; } diff --git a/src/tests/end2end/MultisampledRenderingTests.cpp b/src/tests/end2end/MultisampledRenderingTests.cpp index 0bd94a09a9..2235040110 100644 --- a/src/tests/end2end/MultisampledRenderingTests.cpp +++ b/src/tests/end2end/MultisampledRenderingTests.cpp @@ -534,9 +534,6 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DArrayTexture) { // Test using one multisampled color attachment with resolve target can render correctly // with a non-default sample mask. TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMask) { - // TODO(dawn:491): Remove this condition after enabling sampleMask usage in Metal. - DAWN_SKIP_TEST_IF(IsMetal()); - constexpr bool kTestDepth = false; // The second and third samples are included, // only the second one is covered by the triangle. @@ -567,9 +564,6 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMask) { // Test using one multisampled color attachment with resolve target can render correctly // with the final sample mask empty. TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithEmptyFinalSampleMask) { - // TODO(dawn:491): Remove this condition after enabling sampleMask usage in Metal. - DAWN_SKIP_TEST_IF(IsMetal()); - constexpr bool kTestDepth = false; // The third and fourth samples are included, // none of which is covered by the triangle. @@ -600,9 +594,6 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithEmptyFinalSampleMask) // Test doing MSAA resolve into multiple resolve targets works correctly with a non-default sample // mask. TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithSampleMask) { - // TODO(dawn:491): Remove this condition after enabling sampleMask usage in Metal. - DAWN_SKIP_TEST_IF(IsMetal()); - wgpu::TextureView multisampledColorView2 = CreateTextureForOutputAttachment(kColorFormat, kSampleCount).CreateView(); wgpu::Texture resolveTexture2 = CreateTextureForOutputAttachment(kColorFormat, 1); @@ -641,9 +632,6 @@ TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithSampleMas // Test multisampled rendering with depth test works correctly with a non-default sample mask. TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTestAndSampleMask) { - // TODO(dawn:491): Remove this condition after enabling sampleMask usage in Metal. - DAWN_SKIP_TEST_IF(IsMetal()); - // TODO(dawn:491): Find out why this test doesn't work on Windows Intel Vulkan. DAWN_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan()); @@ -707,9 +695,6 @@ TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTestAndSampleMas // Test using one multisampled color attachment with resolve target can render correctly // with non-default sample mask and shader-output mask. TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMaskAndShaderOutputMask) { - // TODO(dawn:491): Remove this condition after enabling sampleMask usage in Metal. - DAWN_SKIP_TEST_IF(IsMetal()); - // TODO(dawn:491): Remove this when SPIRV-cross adds support for SV_Coverage in HLSL. DAWN_SKIP_TEST_IF(IsD3D12());