diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h index 44fe65d10..3956d6965 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 kMVKMaxVertexInputBindingBufferCount = 31u; // Taken from Metal Feature Set Table. Highest value out of all present GPUs + bool _isVertexInputBindingUsed[kMVKMaxVertexInputBindingBufferCount] = { 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 4b77291cb..de486ad92 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -1415,6 +1415,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 @@ -1842,7 +1843,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.