From 66a2545393f4a90263efb1ab701b846232e9fcee Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Wed, 17 Jul 2024 22:29:13 -0400 Subject: [PATCH] Fixes from Vulkan SDK 1.3.290 testing. - Argument buffer offset into MTLBuffer must respect Metal buffer alignment limits. --- MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm index b197c2531..b98a6e74d 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm @@ -648,6 +648,7 @@ static void populateAuxBuffer(mvk::SPIRVToMSLConversionConfiguration& shaderConf mtlArgBuffEncSize = mvkDSL->getMetal3ArgumentBufferEncodedLength(variableDescriptorCount); } } + uint64_t mtlArgBuffEncAlignedSize = mvkAlignByteCount(mtlArgBuffEncSize, getMetalFeatures().mtlBufferAlignment); size_t dsCnt = _descriptorSetAvailablility.size(); _descriptorSetAvailablility.enumerateEnabledBits(true, [&](size_t dsIdx) { @@ -665,7 +666,7 @@ static void populateAuxBuffer(mvk::SPIRVToMSLConversionConfiguration& shaderConf // on a reset pool), set the offset and update the next available offset value. if ( !mtlArgBuffOffset && (dsIdx || !_nextMetalArgumentBufferOffset)) { mtlArgBuffOffset = _nextMetalArgumentBufferOffset; - _nextMetalArgumentBufferOffset += mtlArgBuffEncSize; + _nextMetalArgumentBufferOffset += mtlArgBuffEncAlignedSize; } // Get the offset of the next desc set, if one exists and @@ -975,9 +976,10 @@ static void populateAuxBuffer(mvk::SPIRVToMSLConversionConfiguration& shaderConf // contain buffers, we add an additional buffer at the end to track buffer sizes. mtlBuffCnt += std::min(mtlBuffCnt, pCreateInfo->maxSets); - // Each descriptor set uses a separate Metal argument buffer, but all of these descriptor set - // Metal argument buffers share a single MTLBuffer. This single MTLBuffer needs to be large - // enough to hold all of the encoded resources for the descriptors. + // Each descriptor set uses a separate Metal argument buffer, but all of these + // descriptor set Metal argument buffers share a single MTLBuffer. This single + // MTLBuffer needs to be large enough to hold all of the encoded resources for the + // descriptors, plus additional buffer offset alignment space for each descriptor set. NSUInteger metalArgBuffSize = 0; if (needsMetalArgumentBufferEncoders()) { // If argument buffer encoders are required, depending on the platform, a Metal argument @@ -998,6 +1000,7 @@ static void populateAuxBuffer(mvk::SPIRVToMSLConversionConfiguration& shaderConf } else { // For Metal 3, encoders are not required, and each arg buffer entry fits into 64 bits. metalArgBuffSize = (mtlBuffCnt + mtlTexCnt + mtlSampCnt) * kMVKMetal3ArgBuffSlotSizeInBytes; + metalArgBuffSize += (mtlFeats.mtlBufferAlignment * pCreateInfo->maxSets); } if (metalArgBuffSize) {