diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h index 11ce6165c..fd7ae7690 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h @@ -430,6 +430,8 @@ class MVKGraphicsPipeline : public MVKPipeline { uint32_t _tessCtlPatchOutputBufferIndex = 0; uint32_t _tessCtlLevelBufferIndex = 0; + static constexpr uint32_t _maxVertexInputBindingBufferCount = 31u; // Taken from Metal Feature Set Table. Highest value out of all present GPUs + bool _isVertexInputBindingUsed[_maxVertexInputBindingBufferCount] = { false }; bool _primitiveRestartEnable = true; bool _hasRasterInfo = false; bool _needsVertexSwizzleBuffer = false; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index 021703591..486575d2b 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -1414,6 +1414,7 @@ static MTLVertexFormat mvkAdjustFormatVectorToSize(MTLVertexFormat format, uint3 maxBinding = max(pVKVB->binding, maxBinding); uint32_t vbIdx = getMetalBufferIndexForVertexAttributeBinding(pVKVB->binding); + _isVertexInputBindingUsed[vbIdx] = true; auto vbDesc = inputDesc.layouts[vbIdx]; if (isVtxStrideStatic && pVKVB->stride == 0) { // Stride can't be 0, it will be set later to attributes' maximum offset + size @@ -1840,7 +1841,7 @@ static MTLVertexFormat mvkAdjustFormatVectorToSize(MTLVertexFormat format, uint3 } bool MVKGraphicsPipeline::isValidVertexBufferIndex(MVKShaderStage stage, uint32_t mtlBufferIndex) { - return mtlBufferIndex < _descriptorBufferCounts.stages[stage] || mtlBufferIndex > getImplicitBufferIndex(stage, 0); + return _isVertexInputBindingUsed[mtlBufferIndex] || mtlBufferIndex < _descriptorBufferCounts.stages[stage] || mtlBufferIndex > getImplicitBufferIndex(stage, 0); } // Initializes the vertex attributes in a shader conversion configuration.