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 <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Tomek Ponitka <tommek@google.com>
This commit is contained in:
Tomek Ponitka 2020-07-29 08:19:59 +00:00 committed by Commit Bot service account
parent bce1cbd0e2
commit 225a2b46b0
4 changed files with 16 additions and 23 deletions

View File

@ -344,7 +344,8 @@ namespace dawn_native { namespace metal {
const char* fragmentEntryPoint = descriptor->fragmentStage->entryPoint; const char* fragmentEntryPoint = descriptor->fragmentStage->entryPoint;
ShaderModule::MetalFunctionData fragmentData; ShaderModule::MetalFunctionData fragmentData;
DAWN_TRY(fragmentModule->GetFunction(fragmentEntryPoint, SingleShaderStage::Fragment, DAWN_TRY(fragmentModule->GetFunction(fragmentEntryPoint, SingleShaderStage::Fragment,
ToBackend(GetLayout()), &fragmentData)); ToBackend(GetLayout()), &fragmentData,
descriptor->sampleMask));
descriptorMTL.fragmentFunction = fragmentData.function; descriptorMTL.fragmentFunction = fragmentData.function;
if (fragmentData.needsStorageBufferLength) { if (fragmentData.needsStorageBufferLength) {

View File

@ -46,14 +46,15 @@ namespace dawn_native { namespace metal {
MaybeError GetFunction(const char* functionName, MaybeError GetFunction(const char* functionName,
SingleShaderStage functionStage, SingleShaderStage functionStage,
const PipelineLayout* layout, const PipelineLayout* layout,
MetalFunctionData* out); MetalFunctionData* out,
uint32_t sampleMask = 0xFFFFFFFF);
private: private:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor); ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
~ShaderModule() override = default; ~ShaderModule() override = default;
MaybeError Initialize(); MaybeError Initialize();
shaderc_spvc::CompileOptions GetMSLCompileOptions(); shaderc_spvc::CompileOptions GetMSLCompileOptions(uint32_t sampleMask = 0xFFFFFFFF);
}; };
}} // namespace dawn_native::metal }} // namespace dawn_native::metal

View File

@ -91,7 +91,8 @@ namespace dawn_native { namespace metal {
MaybeError ShaderModule::GetFunction(const char* functionName, MaybeError ShaderModule::GetFunction(const char* functionName,
SingleShaderStage functionStage, SingleShaderStage functionStage,
const PipelineLayout* layout, const PipelineLayout* layout,
ShaderModule::MetalFunctionData* out) { ShaderModule::MetalFunctionData* out,
uint32_t sampleMask) {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(out); ASSERT(out);
const std::vector<uint32_t>& spirv = GetSpirv(); const std::vector<uint32_t>& spirv = GetSpirv();
@ -101,9 +102,10 @@ namespace dawn_native { namespace metal {
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
// Initializing the compiler is needed every call, because this method uses reflection // Initializing the compiler is needed every call, because this method uses reflection
// to mutate the compiler's IR. // to mutate the compiler's IR.
DAWN_TRY(CheckSpvcSuccess( DAWN_TRY(
mSpvcContext.InitializeForMsl(spirv.data(), spirv.size(), GetMSLCompileOptions()), CheckSpvcSuccess(mSpvcContext.InitializeForMsl(spirv.data(), spirv.size(),
"Unable to initialize instance of spvc")); GetMSLCompileOptions(sampleMask)),
"Unable to initialize instance of spvc"));
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetCompiler(reinterpret_cast<void**>(&compiler)), DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetCompiler(reinterpret_cast<void**>(&compiler)),
"Unable to get cross compiler")); "Unable to get cross compiler"));
} else { } else {
@ -122,6 +124,8 @@ namespace dawn_native { namespace metal {
// the shader storage buffer lengths. // the shader storage buffer lengths.
options_msl.buffer_size_buffer_index = kBufferLengthBufferSlot; options_msl.buffer_size_buffer_index = kBufferLengthBufferSlot;
options_msl.additional_fixed_sample_mask = sampleMask;
compilerImpl = std::make_unique<spirv_cross::CompilerMSL>(spirv); compilerImpl = std::make_unique<spirv_cross::CompilerMSL>(spirv);
compiler = compilerImpl.get(); compiler = compilerImpl.get();
compiler->set_msl_options(options_msl); compiler->set_msl_options(options_msl);
@ -245,7 +249,7 @@ namespace dawn_native { namespace metal {
return {}; 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 // If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to
// be updated. // be updated.
shaderc_spvc::CompileOptions options = GetCompileOptions(); shaderc_spvc::CompileOptions options = GetCompileOptions();
@ -261,6 +265,8 @@ namespace dawn_native { namespace metal {
// the shader storage buffer lengths. // the shader storage buffer lengths.
options.SetMSLBufferSizeBufferIndex(kBufferLengthBufferSlot); options.SetMSLBufferSizeBufferIndex(kBufferLengthBufferSlot);
options.SetMSLAdditionalFixedSampleMask(sampleMask);
return options; return options;
} }

View File

@ -534,9 +534,6 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DArrayTexture) {
// Test using one multisampled color attachment with resolve target can render correctly // Test using one multisampled color attachment with resolve target can render correctly
// with a non-default sample mask. // with a non-default sample mask.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMask) { 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; constexpr bool kTestDepth = false;
// The second and third samples are included, // The second and third samples are included,
// only the second one is covered by the triangle. // 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 // Test using one multisampled color attachment with resolve target can render correctly
// with the final sample mask empty. // with the final sample mask empty.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithEmptyFinalSampleMask) { 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; constexpr bool kTestDepth = false;
// The third and fourth samples are included, // The third and fourth samples are included,
// none of which is covered by the triangle. // 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 // Test doing MSAA resolve into multiple resolve targets works correctly with a non-default sample
// mask. // mask.
TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithSampleMask) { TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithSampleMask) {
// TODO(dawn:491): Remove this condition after enabling sampleMask usage in Metal.
DAWN_SKIP_TEST_IF(IsMetal());
wgpu::TextureView multisampledColorView2 = wgpu::TextureView multisampledColorView2 =
CreateTextureForOutputAttachment(kColorFormat, kSampleCount).CreateView(); CreateTextureForOutputAttachment(kColorFormat, kSampleCount).CreateView();
wgpu::Texture resolveTexture2 = CreateTextureForOutputAttachment(kColorFormat, 1); 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 multisampled rendering with depth test works correctly with a non-default sample mask.
TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTestAndSampleMask) { 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. // TODO(dawn:491): Find out why this test doesn't work on Windows Intel Vulkan.
DAWN_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan()); 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 // Test using one multisampled color attachment with resolve target can render correctly
// with non-default sample mask and shader-output mask. // with non-default sample mask and shader-output mask.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMaskAndShaderOutputMask) { 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. // TODO(dawn:491): Remove this when SPIRV-cross adds support for SV_Coverage in HLSL.
DAWN_SKIP_TEST_IF(IsD3D12()); DAWN_SKIP_TEST_IF(IsD3D12());