Merge pull request #1309 from billhollings/fix-memoryless-load-store

In a renderpass, don't load or store memoryless attachments.
This commit is contained in:
Bill Hollings 2021-03-11 14:11:42 -05:00 committed by GitHub
commit 20b5067ee5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 26 deletions

View File

@ -19,7 +19,9 @@ MoltenVK 1.1.3
Released TBD
- Add support for `HDR10` colorspace via `VK_COLOR_SPACE_HDR10_HLG_EXT` and `VK_COLOR_SPACE_HDR10_ST2084_EXT`.
- Always explicitly set `CAMetalLayer` colorspace property based on _Vulkan_ parameters, and don't rely on _Metal_ default values.
- Always explicitly set `CAMetalLayer` colorspace property based on _Vulkan_ parameters,
and don't rely on _Metal_ default values.
- Avoid use of _Metal_ renderpass load and store actions on memoryless attachments.
- Remove project qualifiers from references to `SPIRV-Cross` header files.
- Add `MVKConfiguration::apiVersionToAdvertise` and `MVK_CONFIG_API_VERSION_TO_ADVERTISE`
env var to configure **MoltenVK** to advertise a particular _Vulkan_ version.

View File

@ -600,21 +600,21 @@ bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRende
bool hasResolveAttachment,
bool isStencil,
bool loadOverride) {
bool willClear = false; // Assume the attachment won't be cleared
// Only allow clearing of entire attachment if we're actually rendering to the entire
// attachment AND we're in the first subpass.
if ( loadOverride && !isMemorylessAttachment ) {
mtlAttDesc.loadAction = MTLLoadActionLoad;
} else if ( isMemorylessAttachment || (isRenderingEntireAttachment && isFirstUseOfAttachment(subpass)) ) {
VkAttachmentLoadOp loadOp = isStencil ? _info.stencilLoadOp : _info.loadOp;
mtlAttDesc.loadAction = mvkMTLLoadActionFromVkAttachmentLoadOp(loadOp);
willClear = (loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR);
// 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)) {
mtlLA = MTLLoadActionLoad;
} else {
mtlAttDesc.loadAction = MTLLoadActionLoad;
VkAttachmentLoadOp loadOp = isStencil ? _info.stencilLoadOp : _info.loadOp;
mtlLA = mvkMTLLoadActionFromVkAttachmentLoadOp(loadOp);
}
// Memoryless can be cleared, but can't be loaded, so force load to don't care.
if (isMemorylessAttachment && mtlLA == MTLLoadActionLoad) { mtlLA = MTLLoadActionDontCare; }
mtlAttDesc.loadAction = mtlLA;
// If the device supports late-specified store actions, we'll use those, and then set them later.
// That way, if we wind up doing a tessellated draw, we can set the store action to store then,
// and then when the render pass actually ends, we can use the true store action.
@ -623,7 +623,7 @@ bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRende
} else {
mtlAttDesc.storeAction = getMTLStoreAction(subpass, isRenderingEntireAttachment, isMemorylessAttachment, hasResolveAttachment, isStencil, false);
}
return willClear;
return (mtlLA == MTLLoadActionClear);
}
void MVKRenderPassAttachment::encodeStoreAction(MVKCommandEncoder* cmdEncoder,
@ -687,20 +687,22 @@ MTLStoreAction MVKRenderPassAttachment::getMTLStoreAction(MVKRenderSubpass* subp
bool isStencil,
bool storeOverride) {
// If a resolve attachment exists, this attachment must resolve once complete.
// Otherwise only allow the attachment to be discarded if we're actually rendering
// to the entire attachment and we're in the last subpass.
if (hasResolveAttachment && !_renderPass->getDevice()->_pMetalFeatures->combinedStoreResolveAction) {
return MTLStoreActionMultisampleResolve;
}
if ( storeOverride && !isMemorylessAttachment ) {
// Memoryless can't be stored.
if (isMemorylessAttachment) {
return hasResolveAttachment ? MTLStoreActionMultisampleResolve : MTLStoreActionDontCare;
}
// Only allow the attachment to be discarded if we're actually
// rendering to the entire attachment and we're in the last subpass.
if (storeOverride || !isRenderingEntireAttachment || !isLastUseOfAttachment(subpass)) {
return hasResolveAttachment ? MTLStoreActionStoreAndMultisampleResolve : MTLStoreActionStore;
}
if ( isMemorylessAttachment || (isRenderingEntireAttachment && isLastUseOfAttachment(subpass)) ) {
VkAttachmentStoreOp storeOp = isStencil ? _info.stencilStoreOp : _info.storeOp;
return mvkMTLStoreActionFromVkAttachmentStoreOp(storeOp, hasResolveAttachment);
}
return hasResolveAttachment ? MTLStoreActionStoreAndMultisampleResolve : MTLStoreActionStore;
}
bool MVKRenderPassAttachment::shouldUseClearAttachment(MVKRenderSubpass* subpass) {

View File

@ -734,10 +734,9 @@ MVK_PUBLIC_SYMBOL MTLBarrierScope mvkMTLBarrierScopeFromVkAccessFlags(VkAccessFl
MVK_PUBLIC_SYMBOL MTLStorageMode mvkMTLStorageModeFromVkMemoryPropertyFlags(VkMemoryPropertyFlags vkFlags) {
// If not visible to the host: Private
// If not visible to the host, use Private, or Memoryless if available and lazily allocated.
if ( !mvkAreAllFlagsEnabled(vkFlags, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ) {
#if MVK_APPLE_SILICON
// iOS: If lazily allocated, Memoryless
if (mvkAreAllFlagsEnabled(vkFlags, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)) {
return MTLStorageModeMemoryless;
}