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:
commit
20b5067ee5
@ -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.
|
||||
|
@ -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,19 +687,21 @@ 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 ) {
|
||||
return hasResolveAttachment ? MTLStoreActionStoreAndMultisampleResolve : MTLStoreActionStore;
|
||||
}
|
||||
if ( isMemorylessAttachment || (isRenderingEntireAttachment && isLastUseOfAttachment(subpass)) ) {
|
||||
VkAttachmentStoreOp storeOp = isStencil ? _info.stencilStoreOp : _info.storeOp;
|
||||
return mvkMTLStoreActionFromVkAttachmentStoreOp(storeOp, hasResolveAttachment);
|
||||
}
|
||||
return hasResolveAttachment ? MTLStoreActionStoreAndMultisampleResolve : MTLStoreActionStore;
|
||||
// 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;
|
||||
}
|
||||
VkAttachmentStoreOp storeOp = isStencil ? _info.stencilStoreOp : _info.storeOp;
|
||||
return mvkMTLStoreActionFromVkAttachmentStoreOp(storeOp, hasResolveAttachment);
|
||||
}
|
||||
|
||||
bool MVKRenderPassAttachment::shouldUseClearAttachment(MVKRenderSubpass* subpass) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user