Merge pull request #1797 from billhollings/fix-no-attchmt-tile-mem-prealloc

Fix excessive Metal tile memory preallocation when rendering without attachments.
This commit is contained in:
Bill Hollings 2022-12-12 15:06:06 -05:00 committed by GitHub
commit e743bbcd71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 5 deletions

View File

@ -13,6 +13,15 @@ Copyright (c) 2015-2022 [The Brenwill Workshop Ltd.](http://www.brenwill.com)
MoltenVK 1.2.2
--------------
Released TBD
- Fix excessive Metal tile memory preallocation when rendering without attachments.
MoltenVK 1.2.1
--------------
@ -53,6 +62,7 @@ Released 2022/12/08
- Fix MSL Access Chain.
MoltenVK 1.2.0
--------------

View File

@ -51,7 +51,7 @@ typedef unsigned long MTLArgumentBuffersTier;
*/
#define MVK_VERSION_MAJOR 1
#define MVK_VERSION_MINOR 2
#define MVK_VERSION_PATCH 1
#define MVK_VERSION_PATCH 2
#define MVK_MAKE_VERSION(major, minor, patch) (((major) * 10000) + ((minor) * 100) + (patch))
#define MVK_VERSION MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)

View File

@ -523,9 +523,18 @@ void MVKCommandEncoder::beginMetalRenderPass(MVKCommandUse cmdUse) {
mtlRPDesc.visibilityResultBuffer = _pEncodingContext->visibilityResultBuffer->_mtlBuffer;
}
VkExtent2D fbExtent = getFramebufferExtent();
mtlRPDesc.renderTargetWidthMVK = max(min(_renderArea.offset.x + _renderArea.extent.width, fbExtent.width), 1u);
mtlRPDesc.renderTargetHeightMVK = max(min(_renderArea.offset.y + _renderArea.extent.height, fbExtent.height), 1u);
// Metal uses MTLRenderPassDescriptor properties renderTargetWidth, renderTargetHeight,
// and renderTargetArrayLength to preallocate tile memory storage on machines using tiled
// rendering. This memory preallocation is not necessary if we are not rendering to
// attachments, and some apps actively define extremely oversized framebuffers when they
// know they are not rendering to actual attachments, making this internal tile memory
// allocation even more wasteful, occasionally to the point of triggering OOM crashes.
bool hasAttachments = _attachments.size() > 0;
if (hasAttachments) {
VkExtent2D fbExtent = getFramebufferExtent();
mtlRPDesc.renderTargetWidthMVK = max(min(_renderArea.offset.x + _renderArea.extent.width, fbExtent.width), 1u);
mtlRPDesc.renderTargetHeightMVK = max(min(_renderArea.offset.y + _renderArea.extent.height, fbExtent.height), 1u);
}
if (_canUseLayeredRendering) {
uint32_t renderTargetArrayLength;
bool found3D = false, found2D = false;
@ -548,7 +557,7 @@ void MVKCommandEncoder::beginMetalRenderPass(MVKCommandUse cmdUse) {
renderTargetArrayLength = getFramebufferLayerCount();
}
// Metal does not allow layered render passes where some RTs are 3D and others are 2D.
if (!(found3D && found2D) || renderTargetArrayLength > 1) {
if (hasAttachments && (!(found3D && found2D) || renderTargetArrayLength > 1)) {
mtlRPDesc.renderTargetArrayLengthMVK = renderTargetArrayLength;
}
}