From fef613365afe5234c1bae9fe33c3d30698d27078 Mon Sep 17 00:00:00 2001 From: Li Hao Date: Mon, 18 Mar 2019 12:26:07 +0000 Subject: [PATCH] Fix zero stride in input state for Metal validation Update stride value to max(attribute.offset + sizeof(attribute) for each attribute) when input stride is 0 in Metal backend BUG=dawn:75 TEST=dawn_end2end_tests Change-Id: Ic0b2bfc685b8aeb92d1d4401174a819279386ea3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/5221 Commit-Queue: Corentin Wallez Reviewed-by: Corentin Wallez Reviewed-by: Kai Ninomiya --- src/dawn_native/metal/InputStateMTL.mm | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/dawn_native/metal/InputStateMTL.mm b/src/dawn_native/metal/InputStateMTL.mm index 02a0c8ab2a..0763a3d44f 100644 --- a/src/dawn_native/metal/InputStateMTL.mm +++ b/src/dawn_native/metal/InputStateMTL.mm @@ -82,12 +82,25 @@ namespace dawn_native { namespace metal { auto layoutDesc = [MTLVertexBufferLayoutDescriptor new]; if (info.stride == 0) { // For MTLVertexStepFunctionConstant, the stepRate must be 0, - // but the stride must NOT be 0, so I made up a value (256). - // TODO(cwallez@chromium.org): the made up value will need to be at least - // max(attrib.offset + sizeof(attrib) for each attrib) + // but the stride must NOT be 0, so we made up it with + // max(attrib.offset + sizeof(attrib) for each attrib) + uint32_t max_stride = 0; + for (uint32_t attribIndex : IterateBitSet(attributesSetMask)) { + const VertexAttributeDescriptor& attrib = GetAttribute(attribIndex); + // Only use the attributes that use the current input + if (attrib.inputSlot != info.inputSlot) { + continue; + } + max_stride = std::max( + max_stride, + static_cast(VertexFormatSize(attrib.format)) + attrib.offset); + } + layoutDesc.stepFunction = MTLVertexStepFunctionConstant; layoutDesc.stepRate = 0; - layoutDesc.stride = 256; + // Metal requires the stride must be a multiple of 4 bytes, align it with next + // multiple of 4 if it's not. + layoutDesc.stride = Align(max_stride, 4); } else { layoutDesc.stepFunction = InputStepModeFunction(info.stepMode); layoutDesc.stepRate = 1;