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 <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn_native/metal/InputStateMTL.mm b/src/dawn_native/metal/InputStateMTL.mm
index 02a0c8a..0763a3d 100644
--- a/src/dawn_native/metal/InputStateMTL.mm
+++ b/src/dawn_native/metal/InputStateMTL.mm
@@ -82,12 +82,25 @@
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<uint32_t>(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;