diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 9968bd4e..07c371e8 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -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 -------------- diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h index 51a605fc..6aef84a3 100644 --- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h +++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h @@ -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) diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index 2c014c77..0bbc5185 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -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; } }