Skip to content

Commit

Permalink
MVKDescriptor: Calculate argument buffer allocation size taking varia…
Browse files Browse the repository at this point in the history
…ble counts into account.
  • Loading branch information
js6i committed Apr 4, 2024
1 parent e97ec49 commit efba837
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 22 deletions.
7 changes: 4 additions & 3 deletions MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class MVKDescriptorSetLayoutBinding : public MVKBaseDeviceObject {
* count provided to that descriptor set is returned. Otherwise returns the value
* defined in VkDescriptorSetLayoutBinding::descriptorCount.
*/
uint32_t getDescriptorCount(MVKDescriptorSet* descSet = nullptr) const;
uint32_t getDescriptorCount(MVKDescriptorSet* descSet = nullptr, uint32_t variableDescriptorCount = std::numeric_limits<uint32_t>::max()) const;

/** Returns the descriptor type of this layout. */
inline VkDescriptorType getDescriptorType() { return _info.descriptorType; }
Expand Down Expand Up @@ -170,11 +170,12 @@ class MVKDescriptorSetLayoutBinding : public MVKBaseDeviceObject {
friend class MVKInlineUniformBlockDescriptor;

void initMetalResourceIndexOffsets(const VkDescriptorSetLayoutBinding* pBinding, uint32_t stage);
void addMTLArgumentDescriptors(NSMutableArray<MTLArgumentDescriptor*>* args);
void addMTLArgumentDescriptors(NSMutableArray<MTLArgumentDescriptor*>* args, uint32_t variableDescriptorCount = 0);
void addMTLArgumentDescriptor(NSMutableArray<MTLArgumentDescriptor*>* args,
uint32_t argIndex,
MTLDataType dataType,
MTLArgumentAccess access);
MTLArgumentAccess access,
uint32_t variableDescriptorCount);
bool isUsingMetalArgumentBuffer();
void populateShaderConversionConfig(mvk::SPIRVToMSLConversionConfiguration& shaderConfig,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
Expand Down
39 changes: 22 additions & 17 deletions MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,17 @@ void mvkPopulateShaderConversionConfig(mvk::SPIRVToMSLConversionConfiguration& s

MVKVulkanAPIObject* MVKDescriptorSetLayoutBinding::getVulkanAPIObject() { return _layout; };

uint32_t MVKDescriptorSetLayoutBinding::getDescriptorCount(MVKDescriptorSet* descSet) const {
uint32_t MVKDescriptorSetLayoutBinding::getDescriptorCount(MVKDescriptorSet* descSet, uint32_t variableDescriptorCount) const {

if (_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
return 1;
}

if (descSet && hasVariableDescriptorCount()) {
return descSet->_variableDescriptorCount;
if (hasVariableDescriptorCount()) {
if (descSet)
return descSet->_variableDescriptorCount;
if (variableDescriptorCount != std::numeric_limits<uint32_t>::max())
return variableDescriptorCount;
}

return _info.descriptorCount;
Expand Down Expand Up @@ -419,50 +422,50 @@ void mvkPopulateShaderConversionConfig(mvk::SPIRVToMSLConversionConfiguration& s
bool MVKDescriptorSetLayoutBinding::isUsingMetalArgumentBuffer() { return _layout->isUsingMetalArgumentBuffer(); };

// Adds MTLArgumentDescriptors to the array, and updates resource indexes consumed.
void MVKDescriptorSetLayoutBinding::addMTLArgumentDescriptors(NSMutableArray<MTLArgumentDescriptor*>* args) {
void MVKDescriptorSetLayoutBinding::addMTLArgumentDescriptors(NSMutableArray<MTLArgumentDescriptor*>* args, uint32_t variableDescriptorCount) {
switch (getDescriptorType()) {

case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().bufferIndex, MTLDataTypePointer, MTLArgumentAccessReadOnly);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().bufferIndex, MTLDataTypePointer, MTLArgumentAccessReadOnly, variableDescriptorCount);
break;

case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().bufferIndex, MTLDataTypePointer, MTLArgumentAccessReadWrite);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().bufferIndex, MTLDataTypePointer, MTLArgumentAccessReadWrite, variableDescriptorCount);
break;

case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadOnly);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadOnly, variableDescriptorCount);
break;

case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadWrite);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadWrite, variableDescriptorCount);
if (!getPhysicalDevice()->useNativeTextureAtomics()) { // Needed for emulated atomic operations
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().bufferIndex, MTLDataTypePointer, MTLArgumentAccessReadWrite);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().bufferIndex, MTLDataTypePointer, MTLArgumentAccessReadWrite, variableDescriptorCount);
}
break;

case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadOnly);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadOnly, variableDescriptorCount);
break;

case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadWrite);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadWrite, variableDescriptorCount);
if (!getPhysicalDevice()->useNativeTextureAtomics()) { // Needed for emulated atomic operations
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().bufferIndex, MTLDataTypePointer, MTLArgumentAccessReadWrite);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().bufferIndex, MTLDataTypePointer, MTLArgumentAccessReadWrite, variableDescriptorCount);
}
break;

case VK_DESCRIPTOR_TYPE_SAMPLER:
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().samplerIndex, MTLDataTypeSampler, MTLArgumentAccessReadOnly);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().samplerIndex, MTLDataTypeSampler, MTLArgumentAccessReadOnly, variableDescriptorCount);
break;

case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadOnly);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().samplerIndex, MTLDataTypeSampler, MTLArgumentAccessReadOnly);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().textureIndex, MTLDataTypeTexture, MTLArgumentAccessReadOnly, variableDescriptorCount);
addMTLArgumentDescriptor(args, getMetalResourceIndexOffsets().samplerIndex, MTLDataTypeSampler, MTLArgumentAccessReadOnly, variableDescriptorCount);
break;

default:
Expand All @@ -473,8 +476,10 @@ void mvkPopulateShaderConversionConfig(mvk::SPIRVToMSLConversionConfiguration& s
void MVKDescriptorSetLayoutBinding::addMTLArgumentDescriptor(NSMutableArray<MTLArgumentDescriptor*>* args,
uint32_t argIndex,
MTLDataType dataType,
MTLArgumentAccess access) {
uint32_t descCnt = getDescriptorCount();
MTLArgumentAccess access,
uint32_t variableDescriptorCount) {
uint32_t descCnt = getDescriptorCount(nullptr, variableDescriptorCount);

if (descCnt == 0) { return; }

auto* argDesc = [MTLArgumentDescriptor argumentDescriptor];
Expand Down
5 changes: 5 additions & 0 deletions MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ class MVKDescriptorSetLayout : public MVKVulkanAPIDeviceObject {
/** Returns the MTLArgumentEncoder for the descriptor set. */
MVKMTLArgumentEncoder& getMTLArgumentEncoder() { return _mtlArgumentEncoder; }

id<MTLArgumentEncoder> getMTLArgumentEncoder(MVKDescriptorSet *dsSet);

/** Calculates the length of encoded argument buffer. */
size_t getEncodedArgumentBufferLength(uint32_t variableDescriptorCount = 0);

MVKDescriptorSetLayout(MVKDevice* device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo);

protected:
Expand Down
26 changes: 24 additions & 2 deletions MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,34 @@
if (isUsingDescriptorSetMetalArgumentBuffers() && isUsingMetalArgumentBuffer()) {
@autoreleasepool {
NSMutableArray<MTLArgumentDescriptor*>* args = [NSMutableArray arrayWithCapacity: _bindings.size()];
for (auto& dslBind : _bindings) { dslBind.addMTLArgumentDescriptors(args); }
for (auto& dslBind : _bindings) { dslBind.addMTLArgumentDescriptors(args, dslBind.getDescriptorCount()); }
_mtlArgumentEncoder.init(args.count ? [getMTLDevice() newArgumentEncoderWithArguments: args] : nil);
}
}
}

id<MTLArgumentEncoder> MVKDescriptorSetLayout::getMTLArgumentEncoder(MVKDescriptorSet *dsSet) {
@autoreleasepool {
NSMutableArray<MTLArgumentDescriptor*>* args = [NSMutableArray arrayWithCapacity: _bindings.size()];
for (auto& dslBind : _bindings) { dslBind.addMTLArgumentDescriptors(args, dsSet->getDescriptorCount()); }
return [getMTLDevice() newArgumentEncoderWithArguments: args];
}
}

size_t MVKDescriptorSetLayout::getEncodedArgumentBufferLength(uint32_t variableDescriptorCount) {
if (_bindings.size() > 0 && _bindings.back().hasVariableDescriptorCount()) {
@autoreleasepool {
NSMutableArray<MTLArgumentDescriptor*>* args = [NSMutableArray arrayWithCapacity: _bindings.size()];
for (auto& dslBind : _bindings) { dslBind.addMTLArgumentDescriptors(args, variableDescriptorCount); }
auto encoder = [getMTLDevice() newArgumentEncoderWithArguments: args];
auto size = [encoder encodedLength];
[encoder release];
return size;
}
}

return _mtlArgumentEncoder.mtlArgumentEncoderSize;
}

#pragma mark -
#pragma mark MVKDescriptorSet
Expand Down Expand Up @@ -487,7 +509,7 @@
uint32_t variableDescriptorCount,
VkDescriptorSet* pVKDS) {
VkResult rslt = VK_ERROR_OUT_OF_POOL_MEMORY;
NSUInteger mtlArgBuffAllocSize = mvkDSL->getMTLArgumentEncoder().mtlArgumentEncoderSize;
NSUInteger mtlArgBuffAllocSize = mvkDSL->getEncodedArgumentBufferLength(variableDescriptorCount);
NSUInteger mtlArgBuffAlignedSize = mvkAlignByteCount(mtlArgBuffAllocSize,
getDevice()->_pMetalFeatures->mtlBufferAlignment);

Expand Down

0 comments on commit efba837

Please sign in to comment.