diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h index bf75742a..ec12615d 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h @@ -120,10 +120,49 @@ protected: #pragma mark - -#pragma mark MVKCmdBindDescriptorSets +#pragma mark MVKCmdBindDescriptorSetsStatic -/** Vulkan command to bind descriptor sets. */ -class MVKCmdBindDescriptorSets : public MVKCommand { +/** + * Vulkan command to bind descriptor sets without dynamic offsets. + * Template class to balance vector pre-allocations between very common low counts and fewer larger counts. + */ +template +class MVKCmdBindDescriptorSetsStatic : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t setCount, + const VkDescriptorSet* pDescriptorSets); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + MVKVectorInline _descriptorSets; + MVKPipelineLayout* _pipelineLayout; + VkPipelineBindPoint _pipelineBindPoint; + uint32_t _firstSet; +}; + +// Concrete template class implementations. +typedef MVKCmdBindDescriptorSetsStatic<1> MVKCmdBindDescriptorSetsStatic1; +typedef MVKCmdBindDescriptorSetsStatic<4> MVKCmdBindDescriptorSetsStatic4; +typedef MVKCmdBindDescriptorSetsStatic<8> MVKCmdBindDescriptorSetsStaticMulti; + + +#pragma mark - +#pragma mark MVKCmdBindDescriptorSetsDynamic + +/** + * Vulkan command to bind descriptor sets with dynamic offsets. + * Template class to balance vector pre-allocations between very common low counts and fewer larger counts. + */ +template +class MVKCmdBindDescriptorSetsDynamic : public MVKCmdBindDescriptorSetsStatic { public: VkResult setContent(MVKCommandBuffer* cmdBuff, @@ -140,13 +179,13 @@ public: protected: MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; - VkPipelineBindPoint _pipelineBindPoint; - MVKPipelineLayout* _pipelineLayout; - MVKVectorInline _descriptorSets; - MVKVectorInline _dynamicOffsets; - uint32_t _firstSet; + MVKVectorInline _dynamicOffsets; }; +// Concrete template class implementations. +typedef MVKCmdBindDescriptorSetsDynamic<4> MVKCmdBindDescriptorSetsDynamic4; +typedef MVKCmdBindDescriptorSetsDynamic<8> MVKCmdBindDescriptorSetsDynamicMulti; + #pragma mark - #pragma mark MVKCmdPushConstants diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm index 50252ad7..1658a52b 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm @@ -182,16 +182,15 @@ void MVKCmdBindComputePipeline::encode(MVKCommandEncoder* cmdEncoder) { #pragma mark - -#pragma mark MVKCmdBindDescriptorSets +#pragma mark MVKCmdBindDescriptorSetsStatic -VkResult MVKCmdBindDescriptorSets::setContent(MVKCommandBuffer* cmdBuff, - VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t firstSet, - uint32_t setCount, - const VkDescriptorSet* pDescriptorSets, - uint32_t dynamicOffsetCount, - const uint32_t* pDynamicOffsets) { +template +VkResult MVKCmdBindDescriptorSetsStatic::setContent(MVKCommandBuffer* cmdBuff, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t setCount, + const VkDescriptorSet* pDescriptorSets) { _pipelineBindPoint = pipelineBindPoint; _pipelineLayout = (MVKPipelineLayout*)layout; _firstSet = firstSet; @@ -203,6 +202,35 @@ VkResult MVKCmdBindDescriptorSets::setContent(MVKCommandBuffer* cmdBuff, _descriptorSets.push_back((MVKDescriptorSet*)pDescriptorSets[dsIdx]); } + return VK_SUCCESS; +} + +template +void MVKCmdBindDescriptorSetsStatic::encode(MVKCommandEncoder* cmdEncoder) { + _pipelineLayout->bindDescriptorSets(cmdEncoder, _descriptorSets, _firstSet, nullptr); +} + +template class MVKCmdBindDescriptorSetsStatic<1>; +template class MVKCmdBindDescriptorSetsStatic<4>; +template class MVKCmdBindDescriptorSetsStatic<8>; + + +#pragma mark - +#pragma mark MVKCmdBindDescriptorSetsDynamic + +template +VkResult MVKCmdBindDescriptorSetsDynamic::setContent(MVKCommandBuffer* cmdBuff, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t setCount, + const VkDescriptorSet* pDescriptorSets, + uint32_t dynamicOffsetCount, + const uint32_t* pDynamicOffsets) { + + MVKCmdBindDescriptorSetsStatic::setContent(cmdBuff, pipelineBindPoint, layout, + firstSet, setCount, pDescriptorSets); + // Add the dynamic offsets _dynamicOffsets.clear(); // Clear for reuse _dynamicOffsets.reserve(dynamicOffsetCount); @@ -213,10 +241,14 @@ VkResult MVKCmdBindDescriptorSets::setContent(MVKCommandBuffer* cmdBuff, return VK_SUCCESS; } -void MVKCmdBindDescriptorSets::encode(MVKCommandEncoder* cmdEncoder) { - _pipelineLayout->bindDescriptorSets(cmdEncoder, _descriptorSets, _firstSet, _dynamicOffsets); +template +void MVKCmdBindDescriptorSetsDynamic::encode(MVKCommandEncoder* cmdEncoder) { + MVKCmdBindDescriptorSetsStatic::_pipelineLayout->bindDescriptorSets(cmdEncoder, MVKCmdBindDescriptorSetsStatic::_descriptorSets, MVKCmdBindDescriptorSetsStatic::_firstSet, &_dynamicOffsets); } +template class MVKCmdBindDescriptorSetsDynamic<4>; +template class MVKCmdBindDescriptorSetsDynamic<8>; + #pragma mark - #pragma mark MVKCmdPushConstants diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index f48bd927..815ed97f 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -58,7 +58,8 @@ MVK_CMD_TYPE_POOLS_FROM_TWO_THRESHOLDS(BeginRenderPass, 1, 2) MVK_CMD_TYPE_POOL(NextSubpass) MVK_CMD_TYPE_POOL(EndRenderPass) MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(ExecuteCommands, 1) -MVK_CMD_TYPE_POOL(BindDescriptorSets) +MVK_CMD_TYPE_POOLS_FROM_TWO_THRESHOLDS(BindDescriptorSetsStatic, 1, 4) +MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(BindDescriptorSetsDynamic, 4) MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(SetViewport, 1) MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(SetScissor, 1) MVK_CMD_TYPE_POOL(SetLineWidth) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h index 2d53f1a2..c19f2eba 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h @@ -89,7 +89,7 @@ public: MVKDescriptorSet* descSet, uint32_t descStartIndex, MVKShaderResourceBinding& dslMTLRezIdxOffsets, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex); /** Encodes this binding layout and the specified descriptor on the specified command encoder immediately. */ @@ -148,7 +148,7 @@ public: uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) = 0; /** @@ -202,7 +202,7 @@ public: uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) override; void write(MVKDescriptorSet* mvkDescSet, @@ -280,7 +280,7 @@ public: uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) override; void write(MVKDescriptorSet* mvkDescSet, @@ -319,7 +319,7 @@ public: uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) override; void write(MVKDescriptorSet* mvkDescSet, @@ -391,7 +391,7 @@ protected: uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex); void write(MVKDescriptorSet* mvkDescSet, @@ -433,7 +433,7 @@ public: uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) override; void write(MVKDescriptorSet* mvkDescSet, @@ -473,7 +473,7 @@ public: uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) override; void write(MVKDescriptorSet* mvkDescSet, @@ -511,7 +511,7 @@ public: uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) override; void write(MVKDescriptorSet* mvkDescSet, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm index a5cb26b9..3179cc21 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm @@ -83,7 +83,7 @@ uint32_t MVKDescriptorSetLayoutBinding::bind(MVKCommandEncoder* cmdEncoder, MVKDescriptorSet* descSet, uint32_t descStartIndex, MVKShaderResourceBinding& dslMTLRezIdxOffsets, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { // Establish the resource indices to use, by combining the offsets of the DSL and this DSL binding. @@ -93,7 +93,7 @@ uint32_t MVKDescriptorSetLayoutBinding::bind(MVKCommandEncoder* cmdEncoder, for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) { MVKDescriptor* mvkDesc = descSet->getDescriptor(descStartIndex + descIdx); mvkDesc->bind(cmdEncoder, _info.descriptorType, descIdx, _applyToStage, - mtlIdxs, dynamicOffsets, pDynamicOffsetIndex); + mtlIdxs, pDynamicOffsets, pDynamicOffsetIndex); } return descCnt; } @@ -476,7 +476,7 @@ void MVKBufferDescriptor::bind(MVKCommandEncoder* cmdEncoder, uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { MVKMTLBufferBinding bb; NSUInteger bufferDynamicOffset = 0; @@ -485,8 +485,10 @@ void MVKBufferDescriptor::bind(MVKCommandEncoder* cmdEncoder, // After determining dynamic part of offset (zero otherwise), fall through to non-dynamic handling case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - bufferDynamicOffset = dynamicOffsets[*pDynamicOffsetIndex]; - (*pDynamicOffsetIndex)++; // Move on to next dynamic offset (and feedback to caller) + if (pDynamicOffsets) { + bufferDynamicOffset = (*pDynamicOffsets)[*pDynamicOffsetIndex]; + (*pDynamicOffsetIndex)++; // Move on to next dynamic offset (and feedback to caller) + } case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: { if (_mvkBuffer) { @@ -581,7 +583,7 @@ void MVKInlineUniformBlockDescriptor::bind(MVKCommandEncoder* cmdEncoder, uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { MVKMTLBufferBinding bb; @@ -678,7 +680,7 @@ void MVKImageDescriptor::bind(MVKCommandEncoder* cmdEncoder, uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { MVKMTLTextureBinding tb; MVKMTLBufferBinding bb; @@ -796,7 +798,7 @@ void MVKSamplerDescriptorMixin::bind(MVKCommandEncoder* cmdEncoder, uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { MVKMTLSamplerStateBinding sb; switch (descriptorType) { @@ -914,12 +916,12 @@ void MVKSamplerDescriptor::bind(MVKCommandEncoder* cmdEncoder, uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { switch (descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: { MVKSamplerDescriptorMixin::bind(cmdEncoder, descriptorType, descriptorIndex, stages, - mtlIndexes, dynamicOffsets, pDynamicOffsetIndex); + mtlIndexes, pDynamicOffsets, pDynamicOffsetIndex); break; } @@ -983,14 +985,14 @@ void MVKCombinedImageSamplerDescriptor::bind(MVKCommandEncoder* cmdEncoder, uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { switch (descriptorType) { case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { MVKImageDescriptor::bind(cmdEncoder, descriptorType, descriptorIndex, stages, - mtlIndexes, dynamicOffsets, pDynamicOffsetIndex); + mtlIndexes, pDynamicOffsets, pDynamicOffsetIndex); MVKSamplerDescriptorMixin::bind(cmdEncoder, descriptorType, descriptorIndex, stages, - mtlIndexes, dynamicOffsets, pDynamicOffsetIndex); + mtlIndexes, pDynamicOffsets, pDynamicOffsetIndex); break; } @@ -1057,7 +1059,7 @@ void MVKTexelBufferDescriptor::bind(MVKCommandEncoder* cmdEncoder, uint32_t descriptorIndex, bool stages[], MVKShaderResourceBinding& mtlIndexes, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { MVKMTLTextureBinding tb; MVKMTLBufferBinding bb; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h index 51756a32..a5cbe576 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h @@ -46,7 +46,7 @@ public: void bindDescriptorSet(MVKCommandEncoder* cmdEncoder, MVKDescriptorSet* descSet, MVKShaderResourceBinding& dslMTLRezIdxOffsets, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm index 45d5ba5e..59c29021 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm @@ -38,7 +38,7 @@ uint32_t MVKDescriptorSetLayout::getDescriptorIndex(uint32_t binding, uint32_t e void MVKDescriptorSetLayout::bindDescriptorSet(MVKCommandEncoder* cmdEncoder, MVKDescriptorSet* descSet, MVKShaderResourceBinding& dslMTLRezIdxOffsets, - MVKVector& dynamicOffsets, + MVKVector* pDynamicOffsets, uint32_t* pDynamicOffsetIndex) { if (_isPushDescriptorLayout) return; @@ -46,7 +46,7 @@ void MVKDescriptorSetLayout::bindDescriptorSet(MVKCommandEncoder* cmdEncoder, uint32_t bindCnt = (uint32_t)_bindings.size(); for (uint32_t descIdx = 0, bindIdx = 0; bindIdx < bindCnt; bindIdx++) { descIdx += _bindings[bindIdx].bind(cmdEncoder, descSet, descIdx, - dslMTLRezIdxOffsets, dynamicOffsets, + dslMTLRezIdxOffsets, pDynamicOffsets, pDynamicOffsetIndex); } } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h index 431f02f6..3221299e 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h @@ -56,7 +56,7 @@ public: void bindDescriptorSets(MVKCommandEncoder* cmdEncoder, MVKVector& descriptorSets, uint32_t firstSet, - MVKVector& dynamicOffsets); + MVKVector* pDynamicOffsets); /** Updates a descriptor set in a command encoder. */ void pushDescriptorSet(MVKCommandEncoder* cmdEncoder, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index c67ab8cc..d270906c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -40,7 +40,7 @@ using namespace SPIRV_CROSS_NAMESPACE; void MVKPipelineLayout::bindDescriptorSets(MVKCommandEncoder* cmdEncoder, MVKVector& descriptorSets, uint32_t firstSet, - MVKVector& dynamicOffsets) { + MVKVector* pDynamicOffsets) { clearConfigurationResult(); uint32_t pDynamicOffsetIndex = 0; uint32_t dsCnt = (uint32_t)descriptorSets.size(); @@ -50,7 +50,7 @@ void MVKPipelineLayout::bindDescriptorSets(MVKCommandEncoder* cmdEncoder, MVKDescriptorSetLayout* dsl = _descriptorSetLayouts[dslIdx]; dsl->bindDescriptorSet(cmdEncoder, descSet, _dslMTLResourceIndexOffsets[dslIdx], - dynamicOffsets, &pDynamicOffsetIndex); + pDynamicOffsets, &pDynamicOffsetIndex); setConfigurationResult(dsl->getConfigurationResult()); } } diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 9254cf41..6428509e 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -1449,8 +1449,13 @@ MVK_PUBLIC_SYMBOL void vkCmdBindDescriptorSets( const uint32_t* pDynamicOffsets) { MVKTraceVulkanCallStart(); - MVKAddCmd(BindDescriptorSets, commandBuffer, pipelineBindPoint, layout, - firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); + if (dynamicOffsetCount) { + MVKAddCmdFromThreshold(BindDescriptorSetsDynamic, setCount, 4, commandBuffer, pipelineBindPoint, layout, + firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); + } else { + MVKAddCmdFromTwoThresholds(BindDescriptorSetsStatic, setCount, 1, 4, commandBuffer, pipelineBindPoint, layout, + firstSet, setCount, pDescriptorSets); + } MVKTraceVulkanCallEnd(); }