From f8b974371b6a841d4759049376094a60facbf62b Mon Sep 17 00:00:00 2001 From: Chip Davis Date: Thu, 24 Jan 2019 20:24:03 -0600 Subject: [PATCH] MVKPipeline: Support sample masks in the Metal SPI. This is yet another "secret" property on the `MTLRenderPipelineDescriptor`. --- Docs/Whats_New.md | 1 + MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm | 15 +++++++++++-- .../OS/MTLRenderPipelineDescriptor+MoltenVK.h | 9 ++++++++ .../OS/MTLRenderPipelineDescriptor+MoltenVK.m | 21 +++++++++++++++++++ README.md | 1 + 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 62a48bb1..b2570f10 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -22,6 +22,7 @@ Released TBD - Add support for `VkPhysicalDeviceFeatures::wideLines` feature when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. - Add support for the `VkPhysicalDeviceFeatures::logicOp` feature when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. - Add support for the `VkPhysicalDevicePortabilitySubsetFeaturesKHR::samplerMipLodBias` feature when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. +- Add support for Metal native pipeline sample masks when `MVK_USE_METAL_PRIVATE_API` is enabled in a **MoltenVK** build. - Fix potential crash when using multi-planar images. - Ensure buffers available for buffer addresses in push constants. - Support `libMoltenVK.dylib` for _iOS Simulator_ architecture. diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index 8a4baca6..5717a089 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -1302,9 +1302,15 @@ bool MVKGraphicsPipeline::addFragmentShaderToPipeline(MTLRenderPipelineDescripto shaderConfig.options.mslOptions.sample_dref_lod_array_as_grad = true; } if (_isRasterizing && pCreateInfo->pMultisampleState) { // Must ignore allowed bad pMultisampleState pointer if rasterization disabled - if (pCreateInfo->pMultisampleState->pSampleMask && pCreateInfo->pMultisampleState->pSampleMask[0] != 0xffffffff) { - shaderConfig.options.mslOptions.additional_fixed_sample_mask = pCreateInfo->pMultisampleState->pSampleMask[0]; +#if MVK_USE_METAL_PRIVATE_API + if (!getMVKConfig().useMetalPrivateAPI) { +#endif + if (pCreateInfo->pMultisampleState->pSampleMask && pCreateInfo->pMultisampleState->pSampleMask[0] != 0xffffffff) { + shaderConfig.options.mslOptions.additional_fixed_sample_mask = pCreateInfo->pMultisampleState->pSampleMask[0]; + } +#if MVK_USE_METAL_PRIVATE_API } +#endif shaderConfig.options.mslOptions.force_sample_rate_shading = pCreateInfo->pMultisampleState->sampleShadingEnable && pCreateInfo->pMultisampleState->minSampleShading != 0.0f; } if (std::any_of(shaderOutputs.begin(), shaderOutputs.end(), [](const SPIRVShaderOutput& output) { return output.builtin == spv::BuiltInLayer; })) { @@ -1651,6 +1657,11 @@ void MVKGraphicsPipeline::addFragmentOutputToPipeline(MTLRenderPipelineDescripto // Multisampling - must ignore allowed bad pMultisampleState pointer if rasterization disabled if (_isRasterizing && pCreateInfo->pMultisampleState) { plDesc.rasterSampleCount = mvkSampleCountFromVkSampleCountFlagBits(pCreateInfo->pMultisampleState->rasterizationSamples); +#if MVK_USE_METAL_PRIVATE_API + if (getMVKConfig().useMetalPrivateAPI && pCreateInfo->pMultisampleState->pSampleMask) { + plDesc.sampleMaskMVK = pCreateInfo->pMultisampleState->pSampleMask[0]; + } +#endif plDesc.alphaToCoverageEnabled = pCreateInfo->pMultisampleState->alphaToCoverageEnable; plDesc.alphaToOneEnabled = pCreateInfo->pMultisampleState->alphaToOneEnable; diff --git a/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.h b/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.h index 90921377..45d44c0d 100644 --- a/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.h +++ b/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.h @@ -33,4 +33,13 @@ */ @property(nonatomic, readwrite) MTLPrimitiveTopologyClass inputPrimitiveTopologyMVK; +/** + * Replacement for the sampleMask property. + * + * This property allows support under all OS versions. Delegates to the sampleMask + * property if it is available. otherwise, returns 0xFFFFFFFF when + * read and does nothing when set. + */ +@property(nonatomic, readwrite) NSUInteger sampleMaskMVK; + @end diff --git a/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.m b/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.m index 42adb999..1e47304d 100644 --- a/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.m +++ b/MoltenVK/MoltenVK/OS/MTLRenderPipelineDescriptor+MoltenVK.m @@ -20,6 +20,16 @@ #include "MTLRenderPipelineDescriptor+MoltenVK.h" #include "MVKCommonEnvironment.h" +#if MVK_USE_METAL_PRIVATE_API +// These properties aren't public yet. +@interface MTLRenderPipelineDescriptor () + +@property(nonatomic, readwrite) NSUInteger sampleMask; +@property(nonatomic, readwrite) float sampleCoverage; + +@end +#endif + @implementation MTLRenderPipelineDescriptor (MoltenVK) -(MTLPrimitiveTopologyClass) inputPrimitiveTopologyMVK { @@ -31,4 +41,15 @@ if ([self respondsToSelector: @selector(setInputPrimitiveTopology:)]) { [self setInputPrimitiveTopology:topology]; } } +#if MVK_USE_METAL_PRIVATE_API +-(NSUInteger) sampleMaskMVK { + if ( [self respondsToSelector: @selector(sampleMask)] ) { return self.sampleMask; } + return 0xFFFFFFFFFFFFFFFFULL; +} + +-(void) setSampleMaskMVK: (NSUInteger) mask { + if ([self respondsToSelector: @selector(setSampleMask:)]) { self.sampleMask = mask; } +} +#endif + @end diff --git a/README.md b/README.md index ac63c460..81dd446e 100644 --- a/README.md +++ b/README.md @@ -330,6 +330,7 @@ Functionality added with `MVK_USE_METAL_PRIVATE_API` enabled includes: - `VkPhysicalDeviceFeatures::wideLines` - `VkPhysicalDeviceFeatures::logicOp` - `VkPhysicalDevicePortabilitySubsetFeaturesKHR::samplerMipLodBias` +- `VkGraphicsPipelineRasterizationCreateInfo::sampleMask`, using `MTLRenderPipelineDescriptor.sampleMask` instead of emulating it in the fragment shader