Don't attempt to store the depth component of a stencil-only renderpass attachment.
For a combined depth-stencil format in a MVKImageView attachment with VK_IMAGE_ASPECT_STENCIL_BIT, the attachment format may have been swizzled to a stencil-only format. In this case, we want to guard against an attempt to store the non-existent depth component. Pass MVKImageView attachment to MVKRenderPassAttachment::encodeStoreAction() and MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor() to check attachment depth format component. Consolidate calls to MVKImageView::populateMTLRenderPassAttachmentDescriptor() by calling it from within MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor().
This commit is contained in:
parent
a6f5841b91
commit
e42b33e593
@ -19,7 +19,8 @@ MoltenVK 1.1.9
|
||||
Released TBD
|
||||
|
||||
- Update *glslang* version, to use `python3` in *glslang* scripts, to replace missing `python` on *macOS 12.3*.
|
||||
- Fix alignment between outputs and inputs between shader stages when using nested structures.
|
||||
- Fix alignment between outputs and inputs between shader stages when using nested structures.
|
||||
- Fix issue where the depth component of a stencil-only renderpass attachment was incorrectly attempting to be stored.
|
||||
|
||||
|
||||
|
||||
|
@ -190,8 +190,8 @@ public:
|
||||
*/
|
||||
bool populateMTLRenderPassAttachmentDescriptor(MTLRenderPassAttachmentDescriptor* mtlAttDesc,
|
||||
MVKRenderSubpass* subpass,
|
||||
MVKImageView* attachment,
|
||||
bool isRenderingEntireAttachment,
|
||||
bool isMemorylessAttachment,
|
||||
bool hasResolveAttachment,
|
||||
bool canResolveFormat,
|
||||
bool isStencil,
|
||||
@ -200,8 +200,8 @@ public:
|
||||
/** If a render encoder is active, sets the store action for this attachment to it. */
|
||||
void encodeStoreAction(MVKCommandEncoder* cmdEncoder,
|
||||
MVKRenderSubpass* subpass,
|
||||
MVKImageView* attachment,
|
||||
bool isRenderingEntireAttachment,
|
||||
bool isMemorylessAttachment,
|
||||
bool hasResolveAttachment,
|
||||
bool canResolveFormat,
|
||||
uint32_t caIdx,
|
||||
|
@ -237,13 +237,8 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
|
||||
|
||||
// Configure the color attachment
|
||||
MVKRenderPassAttachment* clrMVKRPAtt = &_renderPass->_attachments[clrRPAttIdx];
|
||||
attachments[clrRPAttIdx]->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc);
|
||||
bool isMemorylessAttachment = false;
|
||||
#if MVK_APPLE_SILICON
|
||||
isMemorylessAttachment = attachments[clrRPAttIdx]->getMTLTexture(0).storageMode == MTLStorageModeMemoryless;
|
||||
#endif
|
||||
if (clrMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc, this,
|
||||
isRenderingEntireAttachment, isMemorylessAttachment,
|
||||
if (clrMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlColorAttDesc, this, attachments[clrRPAttIdx],
|
||||
isRenderingEntireAttachment,
|
||||
hasResolveAttachment, canResolveFormat,
|
||||
false, loadOverride)) {
|
||||
mtlColorAttDesc.clearColor = pixFmts->getMTLClearColor(clearValues[clrRPAttIdx], clrMVKRPAtt->getFormat());
|
||||
@ -281,13 +276,8 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
|
||||
mtlDepthAttDesc.resolveSlice += getFirstViewIndexInMetalPass(passIdx);
|
||||
}
|
||||
}
|
||||
dsImage->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc);
|
||||
bool isMemorylessAttachment = false;
|
||||
#if MVK_APPLE_SILICON
|
||||
isMemorylessAttachment = dsImage->getMTLTexture(0).storageMode == MTLStorageModeMemoryless;
|
||||
#endif
|
||||
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc, this,
|
||||
isRenderingEntireAttachment, isMemorylessAttachment,
|
||||
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlDepthAttDesc, this, dsImage,
|
||||
isRenderingEntireAttachment,
|
||||
hasResolveAttachment, true,
|
||||
false, loadOverride)) {
|
||||
mtlDepthAttDesc.clearDepth = pixFmts->getMTLClearDepthValue(clearValues[dsRPAttIdx]);
|
||||
@ -308,13 +298,8 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
|
||||
mtlStencilAttDesc.resolveSlice += getFirstViewIndexInMetalPass(passIdx);
|
||||
}
|
||||
}
|
||||
dsImage->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc);
|
||||
bool isMemorylessAttachment = false;
|
||||
#if MVK_APPLE_SILICON
|
||||
isMemorylessAttachment = dsImage->getMTLTexture(0).storageMode == MTLStorageModeMemoryless;
|
||||
#endif
|
||||
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc, this,
|
||||
isRenderingEntireAttachment, isMemorylessAttachment,
|
||||
if (dsMVKRPAtt->populateMTLRenderPassAttachmentDescriptor(mtlStencilAttDesc, this, dsImage,
|
||||
isRenderingEntireAttachment,
|
||||
hasResolveAttachment, true,
|
||||
true, loadOverride)) {
|
||||
mtlStencilAttDesc.clearStencil = pixFmts->getMTLClearStencilValue(clearValues[dsRPAttIdx]);
|
||||
@ -359,11 +344,7 @@ void MVKRenderSubpass::encodeStoreActions(MVKCommandEncoder* cmdEncoder,
|
||||
uint32_t rslvRPAttIdx = _resolveAttachments.empty() ? VK_ATTACHMENT_UNUSED : _resolveAttachments[caIdx].attachment;
|
||||
bool hasResolveAttachment = (rslvRPAttIdx != VK_ATTACHMENT_UNUSED);
|
||||
bool canResolveFormat = hasResolveAttachment && mvkAreAllFlagsEnabled(pixFmts->getCapabilities(attachments[rslvRPAttIdx]->getMTLPixelFormat()), kMVKMTLFmtCapsResolve);
|
||||
bool isMemorylessAttachment = false;
|
||||
#if MVK_APPLE_SILICON
|
||||
isMemorylessAttachment = attachments[clrRPAttIdx]->getMTLTexture(0).storageMode == MTLStorageModeMemoryless;
|
||||
#endif
|
||||
_renderPass->_attachments[clrRPAttIdx].encodeStoreAction(cmdEncoder, this, isRenderingEntireAttachment, isMemorylessAttachment, hasResolveAttachment, canResolveFormat, caIdx, false, storeOverride);
|
||||
_renderPass->_attachments[clrRPAttIdx].encodeStoreAction(cmdEncoder, this, attachments[clrRPAttIdx], isRenderingEntireAttachment, hasResolveAttachment, canResolveFormat, caIdx, false, storeOverride);
|
||||
}
|
||||
}
|
||||
uint32_t dsRPAttIdx = _depthStencilAttachment.attachment;
|
||||
@ -372,12 +353,8 @@ void MVKRenderSubpass::encodeStoreActions(MVKCommandEncoder* cmdEncoder,
|
||||
bool hasDepthResolveAttachment = hasResolveAttachment && _depthResolveMode != VK_RESOLVE_MODE_NONE;
|
||||
bool hasStencilResolveAttachment = hasResolveAttachment && _stencilResolveMode != VK_RESOLVE_MODE_NONE;
|
||||
bool canResolveFormat = true;
|
||||
bool isMemorylessAttachment = false;
|
||||
#if MVK_APPLE_SILICON
|
||||
isMemorylessAttachment = attachments[dsRPAttIdx]->getMTLTexture(0).storageMode == MTLStorageModeMemoryless;
|
||||
#endif
|
||||
_renderPass->_attachments[dsRPAttIdx].encodeStoreAction(cmdEncoder, this, isRenderingEntireAttachment, isMemorylessAttachment, hasDepthResolveAttachment, canResolveFormat, 0, false, storeOverride);
|
||||
_renderPass->_attachments[dsRPAttIdx].encodeStoreAction(cmdEncoder, this, isRenderingEntireAttachment, isMemorylessAttachment, hasStencilResolveAttachment, canResolveFormat, 0, true, storeOverride);
|
||||
_renderPass->_attachments[dsRPAttIdx].encodeStoreAction(cmdEncoder, this, attachments[dsRPAttIdx], isRenderingEntireAttachment, hasDepthResolveAttachment, canResolveFormat, 0, false, storeOverride);
|
||||
_renderPass->_attachments[dsRPAttIdx].encodeStoreAction(cmdEncoder, this, attachments[dsRPAttIdx], isRenderingEntireAttachment, hasStencilResolveAttachment, canResolveFormat, 0, true, storeOverride);
|
||||
}
|
||||
}
|
||||
|
||||
@ -610,13 +587,21 @@ VkSampleCountFlagBits MVKRenderPassAttachment::getSampleCount() { return _info.s
|
||||
|
||||
bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRenderPassAttachmentDescriptor* mtlAttDesc,
|
||||
MVKRenderSubpass* subpass,
|
||||
MVKImageView* attachment,
|
||||
bool isRenderingEntireAttachment,
|
||||
bool isMemorylessAttachment,
|
||||
bool hasResolveAttachment,
|
||||
bool canResolveFormat,
|
||||
bool isStencil,
|
||||
bool loadOverride) {
|
||||
// Only allow clearing of entire attachment if we're actually
|
||||
// Populate from the attachment image view
|
||||
attachment->populateMTLRenderPassAttachmentDescriptor(mtlAttDesc);
|
||||
|
||||
bool isMemorylessAttachment = false;
|
||||
#if MVK_APPLE_SILICON
|
||||
isMemorylessAttachment = attachment->getMTLTexture().storageMode == MTLStorageModeMemoryless;
|
||||
#endif
|
||||
|
||||
// Only allow clearing of entire attachment if we're actually
|
||||
// rendering to the entire attachment AND we're in the first subpass.
|
||||
MTLLoadAction mtlLA;
|
||||
if (loadOverride || !isRenderingEntireAttachment || !isFirstUseOfAttachment(subpass)) {
|
||||
@ -637,28 +622,46 @@ bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRende
|
||||
if ( _renderPass->getDevice()->_pMetalFeatures->deferredStoreActions ) {
|
||||
mtlAttDesc.storeAction = MTLStoreActionUnknown;
|
||||
} else {
|
||||
mtlAttDesc.storeAction = getMTLStoreAction(subpass, isRenderingEntireAttachment, isMemorylessAttachment, hasResolveAttachment, canResolveFormat, isStencil, false);
|
||||
// For a combined depth-stencil format in an attachment with VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
// the attachment format may have been swizzled to a stencil-only format. In this case,
|
||||
// we want to guard against an attempt to store the non-existent depth component.
|
||||
MTLPixelFormat mtlFmt = attachment->getMTLPixelFormat();
|
||||
MVKPixelFormats* pixFmts = _renderPass->getPixelFormats();
|
||||
bool isDepthFormat = pixFmts->isDepthFormat(mtlFmt);
|
||||
bool isStencilFormat = pixFmts->isStencilFormat(mtlFmt);
|
||||
if (isStencilFormat && !isStencil && !isDepthFormat) {
|
||||
mtlAttDesc.storeAction = MTLStoreActionDontCare;
|
||||
} else {
|
||||
mtlAttDesc.storeAction = getMTLStoreAction(subpass, isRenderingEntireAttachment, isMemorylessAttachment, hasResolveAttachment, canResolveFormat, isStencil, false);
|
||||
}
|
||||
}
|
||||
return (mtlLA == MTLLoadActionClear);
|
||||
}
|
||||
|
||||
void MVKRenderPassAttachment::encodeStoreAction(MVKCommandEncoder* cmdEncoder,
|
||||
MVKRenderSubpass* subpass,
|
||||
MVKImageView* attachment,
|
||||
bool isRenderingEntireAttachment,
|
||||
bool isMemorylessAttachment,
|
||||
bool hasResolveAttachment,
|
||||
bool canResolveFormat,
|
||||
uint32_t caIdx,
|
||||
bool isStencil,
|
||||
bool storeOverride) {
|
||||
MTLStoreAction storeAction = getMTLStoreAction(subpass, isRenderingEntireAttachment, isMemorylessAttachment, hasResolveAttachment, canResolveFormat, isStencil, storeOverride);
|
||||
MVKPixelFormats* pixFmts = _renderPass->getPixelFormats();
|
||||
|
||||
MTLPixelFormat mtlFmt = pixFmts->getMTLPixelFormat(_info.format);
|
||||
// For a combined depth-stencil format in an attachment with VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
// the attachment format may have been swizzled to a stencil-only format. In this case,
|
||||
// we want to guard against an attempt to store the non-existent depth component.
|
||||
MTLPixelFormat mtlFmt = attachment->getMTLPixelFormat();
|
||||
MVKPixelFormats* pixFmts = _renderPass->getPixelFormats();
|
||||
bool isDepthFormat = pixFmts->isDepthFormat(mtlFmt);
|
||||
bool isStencilFormat = pixFmts->isStencilFormat(mtlFmt);
|
||||
bool isColorFormat = !(isDepthFormat || isStencilFormat);
|
||||
|
||||
bool isMemorylessAttachment = false;
|
||||
#if MVK_APPLE_SILICON
|
||||
isMemorylessAttachment = attachment->getMTLTexture().storageMode == MTLStorageModeMemoryless;
|
||||
#endif
|
||||
MTLStoreAction storeAction = getMTLStoreAction(subpass, isRenderingEntireAttachment, isMemorylessAttachment, hasResolveAttachment, canResolveFormat, isStencil, storeOverride);
|
||||
|
||||
if (isColorFormat) {
|
||||
[cmdEncoder->_mtlRenderEncoder setColorStoreAction: storeAction atIndex: caIdx];
|
||||
} else if (isDepthFormat && !isStencil) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user