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
|
Released TBD
|
||||||
|
|
||||||
- Add support for `HDR10` colorspace via `VK_COLOR_SPACE_HDR10_HLG_EXT` and `VK_COLOR_SPACE_HDR10_ST2084_EXT`.
|
- 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.
|
- Remove project qualifiers from references to `SPIRV-Cross` header files.
|
||||||
- Add `MVKConfiguration::apiVersionToAdvertise` and `MVK_CONFIG_API_VERSION_TO_ADVERTISE`
|
- Add `MVKConfiguration::apiVersionToAdvertise` and `MVK_CONFIG_API_VERSION_TO_ADVERTISE`
|
||||||
env var to configure **MoltenVK** to advertise a particular _Vulkan_ version.
|
env var to configure **MoltenVK** to advertise a particular _Vulkan_ version.
|
||||||
|
@ -600,21 +600,21 @@ bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRende
|
|||||||
bool hasResolveAttachment,
|
bool hasResolveAttachment,
|
||||||
bool isStencil,
|
bool isStencil,
|
||||||
bool loadOverride) {
|
bool loadOverride) {
|
||||||
|
// Only allow clearing of entire attachment if we're actually
|
||||||
bool willClear = false; // Assume the attachment won't be cleared
|
// rendering to the entire attachment AND we're in the first subpass.
|
||||||
|
MTLLoadAction mtlLA;
|
||||||
// Only allow clearing of entire attachment if we're actually rendering to the entire
|
if (loadOverride || !isRenderingEntireAttachment || !isFirstUseOfAttachment(subpass)) {
|
||||||
// attachment AND we're in the first subpass.
|
mtlLA = MTLLoadActionLoad;
|
||||||
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);
|
|
||||||
} else {
|
} 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.
|
// 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,
|
// 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.
|
// and then when the render pass actually ends, we can use the true store action.
|
||||||
@ -623,7 +623,7 @@ bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRende
|
|||||||
} else {
|
} else {
|
||||||
mtlAttDesc.storeAction = getMTLStoreAction(subpass, isRenderingEntireAttachment, isMemorylessAttachment, hasResolveAttachment, isStencil, false);
|
mtlAttDesc.storeAction = getMTLStoreAction(subpass, isRenderingEntireAttachment, isMemorylessAttachment, hasResolveAttachment, isStencil, false);
|
||||||
}
|
}
|
||||||
return willClear;
|
return (mtlLA == MTLLoadActionClear);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKRenderPassAttachment::encodeStoreAction(MVKCommandEncoder* cmdEncoder,
|
void MVKRenderPassAttachment::encodeStoreAction(MVKCommandEncoder* cmdEncoder,
|
||||||
@ -687,19 +687,21 @@ MTLStoreAction MVKRenderPassAttachment::getMTLStoreAction(MVKRenderSubpass* subp
|
|||||||
bool isStencil,
|
bool isStencil,
|
||||||
bool storeOverride) {
|
bool storeOverride) {
|
||||||
// If a resolve attachment exists, this attachment must resolve once complete.
|
// 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) {
|
if (hasResolveAttachment && !_renderPass->getDevice()->_pMetalFeatures->combinedStoreResolveAction) {
|
||||||
return MTLStoreActionMultisampleResolve;
|
return MTLStoreActionMultisampleResolve;
|
||||||
}
|
}
|
||||||
if ( storeOverride && !isMemorylessAttachment ) {
|
// Memoryless can't be stored.
|
||||||
return hasResolveAttachment ? MTLStoreActionStoreAndMultisampleResolve : MTLStoreActionStore;
|
if (isMemorylessAttachment) {
|
||||||
}
|
return hasResolveAttachment ? MTLStoreActionMultisampleResolve : MTLStoreActionDontCare;
|
||||||
if ( isMemorylessAttachment || (isRenderingEntireAttachment && isLastUseOfAttachment(subpass)) ) {
|
}
|
||||||
VkAttachmentStoreOp storeOp = isStencil ? _info.stencilStoreOp : _info.storeOp;
|
|
||||||
return mvkMTLStoreActionFromVkAttachmentStoreOp(storeOp, hasResolveAttachment);
|
// Only allow the attachment to be discarded if we're actually
|
||||||
}
|
// rendering to the entire attachment and we're in the last subpass.
|
||||||
return hasResolveAttachment ? MTLStoreActionStoreAndMultisampleResolve : MTLStoreActionStore;
|
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) {
|
bool MVKRenderPassAttachment::shouldUseClearAttachment(MVKRenderSubpass* subpass) {
|
||||||
|
@ -734,10 +734,9 @@ MVK_PUBLIC_SYMBOL MTLBarrierScope mvkMTLBarrierScopeFromVkAccessFlags(VkAccessFl
|
|||||||
|
|
||||||
MVK_PUBLIC_SYMBOL MTLStorageMode mvkMTLStorageModeFromVkMemoryPropertyFlags(VkMemoryPropertyFlags vkFlags) {
|
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 ( !mvkAreAllFlagsEnabled(vkFlags, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ) {
|
||||||
#if MVK_APPLE_SILICON
|
#if MVK_APPLE_SILICON
|
||||||
// iOS: If lazily allocated, Memoryless
|
|
||||||
if (mvkAreAllFlagsEnabled(vkFlags, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)) {
|
if (mvkAreAllFlagsEnabled(vkFlags, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)) {
|
||||||
return MTLStorageModeMemoryless;
|
return MTLStorageModeMemoryless;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user