Allow zero offset and stride combo in VkVertexInputBindingDescription.

Also fix memory overrun if no VB found with same binding as a VA.
This commit is contained in:
Bill Hollings 2019-03-14 17:50:20 -04:00
parent e5ebf069ee
commit e13444e305
2 changed files with 27 additions and 14 deletions

View File

@ -18,7 +18,11 @@ MoltenVK 1.0.34
Released TBD
- Allow zero offset and stride combo in VkVertexInputBindingDescription.
- Fix potential memory leak on synchronous command buffer submission.
- Increase shader float constant accuracy beyond 6 digits of precision.
- MoltenVKShaderConverterTool support cs & csh for compute shader file extensions.
- `fetchDependencies`: Stop on first error.
@ -46,6 +50,7 @@ Released 2019/02/28
- Fix crash from use of MTLDevice registryID on early OS versions.
- `fetchDependencies`: Fix issue loading from `Vulkan-Portability_repo_revision`.
- `fetchDependencies`: Clean MoltenVK build to ensure using latest dependency libs.
- Update `VK_MVK_MOLTENVK_SPEC_VERSION` to 18.
- Update to latest dependency libraries to support SDK 1.1.101.
- Update to latest SPIRV-Cross version:
- MSL: Implement 8-bit part of `VK_KHR_shader_float16_int8`.

View File

@ -363,16 +363,23 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLRenderPipelineDescriptor
for (uint32_t i = 0; i < vaCnt; i++) {
const VkVertexInputAttributeDescription* pVKVA = &pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i];
if (shaderContext.isVertexAttributeLocationUsed(pVKVA->location)) {
// Vulkan allows offsets to exceed the buffer stride, but Metal doesn't.
const VkVertexInputBindingDescription* pVKVB = pCreateInfo->pVertexInputState->pVertexBindingDescriptions;
for (uint32_t j = 0; j < vbCnt; j++, pVKVB++) {
if (pVKVB->binding == pVKVA->binding) { break; }
}
if (pVKVA->offset >= pVKVB->stride) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Under Metal, vertex attribute offsets must not exceed the vertex buffer stride."));
return nil;
}
MTLVertexAttributeDescriptor* vaDesc = plDesc.vertexDescriptor.attributes[pVKVA->location];
// Only check non-zero offsets, as it's common for both to be zero when step rate is instance.
if (pVKVA->offset > 0) {
const VkVertexInputBindingDescription* pVKVB = pCreateInfo->pVertexInputState->pVertexBindingDescriptions;
for (uint32_t j = 0; j < vbCnt; j++, pVKVB++) {
if (pVKVB->binding == pVKVA->binding) {
if (pVKVA->offset >= pVKVB->stride) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Under Metal, vertex attribute offsets must not exceed the vertex buffer stride."));
return nil;
}
break;
}
}
}
MTLVertexAttributeDescriptor* vaDesc = plDesc.vertexDescriptor.attributes[pVKVA->location];
vaDesc.format = mvkMTLVertexFormatFromVkFormat(pVKVA->format);
vaDesc.bufferIndex = _device->getMetalBufferIndexForVertexAttributeBinding(pVKVA->binding);
vaDesc.offset = pVKVA->offset;
@ -384,15 +391,16 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLRenderPipelineDescriptor
const VkVertexInputBindingDescription* pVKVB = &pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i];
uint32_t vbIdx = _device->getMetalBufferIndexForVertexAttributeBinding(pVKVB->binding);
if (shaderContext.isVertexBufferUsed(vbIdx)) {
MTLVertexBufferLayoutDescriptor* vbDesc = plDesc.vertexDescriptor.layouts[vbIdx];
// Vulkan allows any stride, but Metal only allows multiples of 4.
// TODO: We should try to expand the buffer to the required alignment
// in that case.
// Vulkan allows any stride, but Metal only allows multiples of 4.
// TODO: We should try to expand the buffer to the required alignment in that case.
if ((pVKVB->stride % 4) != 0) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Under Metal, vertex buffer strides must be aligned to four bytes."));
return nil;
}
vbDesc.stride = (pVKVB->stride == 0) ? sizeof(simd::float4) : pVKVB->stride; // Vulkan allows zero stride but Metal doesn't. Default to float4
MTLVertexBufferLayoutDescriptor* vbDesc = plDesc.vertexDescriptor.layouts[vbIdx];
vbDesc.stride = (pVKVB->stride == 0) ? sizeof(simd::float4) : pVKVB->stride; // Vulkan allows zero stride but Metal doesn't. Default to float4
vbDesc.stepFunction = mvkMTLVertexStepFunctionFromVkVertexInputRate(pVKVB->inputRate);
vbDesc.stepRate = 1;
}