Detect support for having no attachments in a render pass

When we do have support, don't create a dummy texture to attach.
This commit is contained in:
Jan Sikorski 2020-08-07 13:26:24 +02:00
parent c3254cb546
commit 77cbe56101
5 changed files with 23 additions and 7 deletions

View File

@ -615,6 +615,7 @@ typedef struct {
VkDeviceSize vertexStrideAlignment; /**< The alignment used for the stride of vertex attribute bindings. */ VkDeviceSize vertexStrideAlignment; /**< The alignment used for the stride of vertex attribute bindings. */
VkBool32 indirectTessellationDrawing; /**< If true, tessellation draw calls support parameters held in a GPU buffer. */ VkBool32 indirectTessellationDrawing; /**< If true, tessellation draw calls support parameters held in a GPU buffer. */
VkBool32 nonUniformThreadgroups; /**< If true, the device supports arbitrary-sized grids in compute workloads. */ VkBool32 nonUniformThreadgroups; /**< If true, the device supports arbitrary-sized grids in compute workloads. */
VkBool32 renderWithoutAttachments; /**< If true, we don't have to create a dummy attachment for a render pass if there isn't one. */
} MVKPhysicalDeviceMetalFeatures; } MVKPhysicalDeviceMetalFeatures;
/** MoltenVK performance of a particular type of activity. */ /** MoltenVK performance of a particular type of activity. */

View File

@ -1072,6 +1072,10 @@ void MVKPhysicalDevice::initMetalFeatures() {
_metalFeatures.indirectTessellationDrawing = true; _metalFeatures.indirectTessellationDrawing = true;
} }
if ( mvkOSVersionIsAtLeast(11.0) ) {
_metalFeatures.renderWithoutAttachments = true;
}
if ( mvkOSVersionIsAtLeast(13.0) ) { if ( mvkOSVersionIsAtLeast(13.0) ) {
_metalFeatures.mslVersionEnum = MTLLanguageVersion2_2; _metalFeatures.mslVersionEnum = MTLLanguageVersion2_2;
_metalFeatures.placementHeaps = useMTLHeaps; _metalFeatures.placementHeaps = useMTLHeaps;
@ -1130,6 +1134,7 @@ void MVKPhysicalDevice::initMetalFeatures() {
if ( mvkOSVersionIsAtLeast(10.15) ) { if ( mvkOSVersionIsAtLeast(10.15) ) {
_metalFeatures.mslVersionEnum = MTLLanguageVersion2_2; _metalFeatures.mslVersionEnum = MTLLanguageVersion2_2;
_metalFeatures.native3DCompressedTextures = true; _metalFeatures.native3DCompressedTextures = true;
_metalFeatures.renderWithoutAttachments = true;
if (supportsMTLGPUFamily(Mac2)) { if (supportsMTLGPUFamily(Mac2)) {
_metalFeatures.nativeTextureSwizzle = true; _metalFeatures.nativeTextureSwizzle = true;
_metalFeatures.placementHeaps = useMTLHeaps; _metalFeatures.placementHeaps = useMTLHeaps;

View File

@ -1275,9 +1275,11 @@ void MVKGraphicsPipeline::addFragmentOutputToPipeline(MTLRenderPipelineDescripto
if (pixFmts->isDepthFormat(mtlDSFormat)) { plDesc.depthAttachmentPixelFormat = mtlDSFormat; } if (pixFmts->isDepthFormat(mtlDSFormat)) { plDesc.depthAttachmentPixelFormat = mtlDSFormat; }
if (pixFmts->isStencilFormat(mtlDSFormat)) { plDesc.stencilAttachmentPixelFormat = mtlDSFormat; } if (pixFmts->isStencilFormat(mtlDSFormat)) { plDesc.stencilAttachmentPixelFormat = mtlDSFormat; }
// In Vulkan, it's perfectly valid to render with no attachments. Not so in Metal. // In Vulkan, it's perfectly valid to render with no attachments. In Metal we need to check for
// If we have no attachments, then we'll have to add a dummy attachment. // support for it. If we have no attachments, then we may have to add a dummy attachment.
if (!caCnt && !pixFmts->isDepthFormat(mtlDSFormat) && !pixFmts->isStencilFormat(mtlDSFormat)) { if (!caCnt && !pixFmts->isDepthFormat(mtlDSFormat) && !pixFmts->isStencilFormat(mtlDSFormat) &&
!getDevice()->_pMetalFeatures->renderWithoutAttachments) {
MTLRenderPipelineColorAttachmentDescriptor* colorDesc = plDesc.colorAttachments[0]; MTLRenderPipelineColorAttachmentDescriptor* colorDesc = plDesc.colorAttachments[0];
colorDesc.pixelFormat = MTLPixelFormatR8Unorm; colorDesc.pixelFormat = MTLPixelFormatR8Unorm;
colorDesc.writeMask = MTLColorWriteMaskNone; colorDesc.writeMask = MTLColorWriteMaskNone;

View File

@ -138,6 +138,14 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
_mtlDummyTex = nil; _mtlDummyTex = nil;
if (caUsedCnt == 0 && dsRPAttIdx == VK_ATTACHMENT_UNUSED) { if (caUsedCnt == 0 && dsRPAttIdx == VK_ATTACHMENT_UNUSED) {
if (_renderPass->getDevice()->_pMetalFeatures->renderWithoutAttachments) {
// We support having no attachments.
#if MVK_MACOS_OR_IOS
mtlRPDesc.defaultRasterSampleCount = 1;
#endif
return;
}
// Add a dummy attachment so this passes validation. // Add a dummy attachment so this passes validation.
VkExtent2D fbExtent = framebuffer->getExtent2D(); VkExtent2D fbExtent = framebuffer->getExtent2D();
MTLTextureDescriptor* mtlTexDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatR8Unorm width: fbExtent.width height: fbExtent.height mipmapped: NO]; MTLTextureDescriptor* mtlTexDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatR8Unorm width: fbExtent.width height: fbExtent.height mipmapped: NO];

View File

@ -57,7 +57,7 @@
#if MVK_TVOS #if MVK_TVOS
return 0; return 0;
#endif #endif
#if MVK_MACOS || MVK_IOS #if MVK_MACOS_OR_IOS
if ([self respondsToSelector: @selector(renderTargetWidth)]) if ([self respondsToSelector: @selector(renderTargetWidth)])
return self.renderTargetWidth; return self.renderTargetWidth;
return 0; return 0;
@ -67,7 +67,7 @@
-(void) setRenderTargetWidthMVK: (NSUInteger) width { -(void) setRenderTargetWidthMVK: (NSUInteger) width {
#if MVK_MACOS || MVK_IOS #if MVK_MACOS_OR_IOS
if ([self respondsToSelector: @selector(setRenderTargetWidth:)]) if ([self respondsToSelector: @selector(setRenderTargetWidth:)])
self.renderTargetWidth = width; self.renderTargetWidth = width;
#endif #endif
@ -79,7 +79,7 @@
#if MVK_TVOS #if MVK_TVOS
return 0; return 0;
#endif #endif
#if MVK_MACOS || MVK_IOS #if MVK_MACOS_OR_IOS
if ([self respondsToSelector: @selector(renderTargetHeight)]) if ([self respondsToSelector: @selector(renderTargetHeight)])
return self.renderTargetHeight; return self.renderTargetHeight;
return 0; return 0;
@ -89,7 +89,7 @@
-(void) setRenderTargetHeightMVK: (NSUInteger) height { -(void) setRenderTargetHeightMVK: (NSUInteger) height {
#if MVK_MACOS || MVK_IOS #if MVK_MACOS_OR_IOS
if ([self respondsToSelector: @selector(setRenderTargetHeight:)]) if ([self respondsToSelector: @selector(setRenderTargetHeight:)])
self.renderTargetHeight = height; self.renderTargetHeight = height;
#endif #endif