Repository: google/filament
File: filament/backend/src/webgpu/WebGPUHandles.cpp (C++)

Code before:
                .sourceBufferIndex = attribute.buffer,
                .bufferOffset = attribute.offset,
                .stride = attribute.stride
            });
            // we need to have a vertex buffer layout for each slot
            mVertexBufferLayouts.push_back({
                .stepMode = wgpu::VertexStepMode::Vertex,
                .arrayStride = attribute.stride
            });
        }
        attributeInfos[currentAttributeIndex++] = {
            .slot = existingSlot,
            .attribute = {
                .format = vertexFormat,
                .offset = attribute.offset - mWebGPUSlotBindingInfos[existingSlot].bufferOffset,
                .shaderLocation = attributeIndex
            }
        };
    }
    FILAMENT_CHECK_POSTCONDITION(currentAttributeIndex == attributeCount)
            << "Using " << currentAttributeIndex << " attributes, but " << attributeCount
            << " where indicated.";
    mVertexBufferLayouts.shrink_to_fit();
    mWebGPUSlotBindingInfos.shrink_to_fit();
    // sort attribute infos by increasing slot (by increasing offset within each slot)...
    std::sort(attributeInfos.data(), attributeInfos.data() + attributeCount,
            [](AttributeInfo const& first, AttributeInfo const& second) {
                if (first.slot < second.slot) {
                    return true;
                }
                if (first.slot == second.slot) {
                    if (first.attribute.offset < second.attribute.offset) {
                        return true;
                    }
                }
                return false;
            });
    // populate mVertexAttributes and update mVertexBufferLayouts to reference the correct
    // attributes in it...
    for (uint32_t attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex) {
        AttributeInfo const& info = attributeInfos[attributeIndex];
        mVertexAttributes.push_back(info.attribute);
        if (mVertexBufferLayouts[info.slot].attributeCount == 0) {
            mVertexBufferLayouts[info.slot].attributes = &mVertexAttributes[attributeIndex];
        }
        mVertexBufferLayouts[info.slot].attributeCount += 1;
    }
}

WGPUIndexBuffer::WGPUIndexBuffer(wgpu::Device const& device, uint8_t elementSize,
        uint32_t indexCount)

Review comment (suggestion):
is there a case for when `attribute.offset` is 0 and `mWebGPUSlotBindingInfos[existingSlot].bufferOffset` is not? 
or cases in which `mWebGPUSlotBindingInfos[existingSlot].bufferOffset > attribute.offset` ? that would result in a negative offset

Code after:
        if (existingSlot == IMPOSSIBLE_SLOT_INDEX) {
            // New combination, use a new WebGPU slot
            FILAMENT_CHECK_PRECONDITION(currentWebGPUSlotIndex < MAX_VERTEX_BUFFER_COUNT &&
                                        currentWebGPUSlotIndex < deviceLimits.maxVertexBuffers)
                    << "Number of vertex buffer layouts must not exceed MAX_VERTEX_BUFFER_COUNT ("
                    << MAX_VERTEX_BUFFER_COUNT << ") or the device limit ("
                    << deviceLimits.maxVertexBuffers << ")";
            existingSlot = currentWebGPUSlotIndex++;
            mWebGPUSlotBindingInfos.push_back({
                .sourceBufferIndex = attribute.buffer,
                .bufferOffset = attribute.offset,
                .stride = attribute.stride
            });
            // we need to have a vertex buffer layout for each slot
            mVertexBufferLayouts.push_back({
                .stepMode = wgpu::VertexStepMode::Vertex,
                .arrayStride = attribute.stride
                // we do not know attributeCount or attributes at this time. We get those
                // in a subsequent pass over the attributeInfos we collect in this loop.
            });
        }
        attributeInfos[currentAttributeIndex++] = {
            .slot = existingSlot,
            .attribute = {
                .format = vertexFormat,
                .offset = attribute.offset - mWebGPUSlotBindingInfos[existingSlot].bufferOffset,
                .shaderLocation = attributeIndex
            }
        };
    }
    FILAMENT_CHECK_POSTCONDITION(currentAttributeIndex == attributeCount)
            << "Using " << currentAttributeIndex << " attributes, but " << attributeCount
            << " where indicated.";
    mVertexBufferLayouts.shrink_to_fit();
    mWebGPUSlotBindingInfos.shrink_to_fit();
    // sort attribute infos by increasing slot (by increasing offset within each slot).
    // We do this to ensure that attributes for the same slot/layout are contiguous in
    // the vector, so the vertex buffer layout associated with these contiguous attributes
    // can directly reference them in the mVertexAttributes vector below.
    std::sort(attributeInfos.data(), attributeInfos.data() + attributeCount,
            [](AttributeInfo const& first, AttributeInfo const& second) {
                if (first.slot < second.slot) {
                    return true;
                }
                if (first.slot == second.slot) {
                    if (first.attribute.offset < second.attribute.offset) {
                        return true;
                    }
                }
                return false;
            });