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

Code before:
            case ElementType::BYTE4: return VertexFormat::Snorm8x4;
            case ElementType::UBYTE4: return VertexFormat::Unorm8x4;
            case ElementType::SHORT4: return VertexFormat::Snorm16x4;
            case ElementType::USHORT4: return VertexFormat::Unorm8x4;
            default:
                FILAMENT_CHECK_POSTCONDITION(false) << "Normalized format does not exist.";
                return VertexFormat::Float32x3;
        }
    }
    switch (type) {
        // Single Component Types
        // There is no direct alternative for SSCALED in webgpu. Convert them to Float32 directly.
        // This will result in increased memory on the cpu side.
        // TODO: Is Float16 acceptable instead with some potential accuracy errors?
        case ElementType::BYTE: return integer ? VertexFormat::Sint8 : VertexFormat::Float32;
        case ElementType::UBYTE: return integer ? VertexFormat::Uint8 : VertexFormat::Float32;
        case ElementType::SHORT: return integer ? VertexFormat::Sint16 : VertexFormat::Float32;
        case ElementType::USHORT: return integer ? VertexFormat::Uint16 : VertexFormat::Float32;
        case ElementType::HALF: return VertexFormat::Float16;
        case ElementType::INT: return VertexFormat::Sint32;
        case ElementType::UINT: return VertexFormat::Uint32;
        case ElementType::FLOAT: return VertexFormat::Float32;
        // Two Component Types
        case ElementType::BYTE2: return integer ? VertexFormat::Sint8x2 : VertexFormat::Float32x2;
        case ElementType::UBYTE2: return integer ? VertexFormat::Uint8x2 : VertexFormat::Float32x2;
        case ElementType::SHORT2: return integer ? VertexFormat::Sint16x2 : VertexFormat::Float32x2;
        case ElementType::USHORT2: return integer ? VertexFormat::Uint16x2 : VertexFormat::Float32x2;
        case ElementType::HALF2: return VertexFormat::Float16x2;
        case ElementType::FLOAT2: return VertexFormat::Float32x2;
        // Three Component Types
        case ElementType::BYTE3: return VertexFormat::Sint8x4;    // NOT MINSPEC
        case ElementType::UBYTE3: return VertexFormat::Uint8x4;   // NOT MINSPEC
        case ElementType::SHORT3: return VertexFormat::Sint16x4;  // NOT MINSPEC
        case ElementType::USHORT3: return VertexFormat::Uint16x4; // NOT MINSPEC
        case ElementType::HALF3: return VertexFormat::Float16x4;  // NOT MINSPEC
        case ElementType::FLOAT3: return VertexFormat::Float32x3;
        // Four Component Types
        case ElementType::BYTE4: return integer ? VertexFormat::Sint8x4 : VertexFormat::Float32x4;
        case ElementType::UBYTE4: return integer ? VertexFormat::Uint8x4 : VertexFormat::Float32x4;
        case ElementType::SHORT4: return integer ? VertexFormat::Sint16x4 : VertexFormat::Float32x4;
        case ElementType::USHORT4: return integer ? VertexFormat::Uint16x4 : VertexFormat::Float32x4;
        case ElementType::HALF4: return VertexFormat::Float16x4;
        case ElementType::FLOAT4: return VertexFormat::Float32x4;
    }
    FILAMENT_CHECK_POSTCONDITION(false) << "Vertex format should always be defined.";
    return VertexFormat::Float32x3;
}

} // namespace

namespace filament::backend {

Review comment (performance):
being able to use half floats vs single floats makes a BIG difference from a performance point of view, vectorization, etc... (see [High performance (graphics) programming (Android Dev Summit '19)](https://youtu.be/Lcq_fzet9Iw?si=m1-WwWj4S74WabTL)). We should think carefully about this.

Code after:
            case ElementType::UBYTE2: return VertexFormat::Unorm8x2;
            case ElementType::SHORT2: return VertexFormat::Snorm16x2;
            case ElementType::USHORT2: return VertexFormat::Unorm16x2;
            // Three Component Types
            // There is no vertex format type for 3 byte data in webgpu. Use
            // 4 byte signed normalized type and ignore the last byte.
            // TODO: This is to be verified.
            case ElementType::BYTE3: return VertexFormat::Snorm8x4;    // NOT MINSPEC
            case ElementType::UBYTE3: return VertexFormat::Unorm8x4;   // NOT MINSPEC
            case ElementType::SHORT3: return VertexFormat::Snorm16x4;  // NOT MINSPEC
            case ElementType::USHORT3: return VertexFormat::Unorm16x4; // NOT MINSPEC
            // Four Component Types
            case ElementType::BYTE4: return VertexFormat::Snorm8x4;
            case ElementType::UBYTE4: return VertexFormat::Unorm8x4;
            case ElementType::SHORT4: return VertexFormat::Snorm16x4;
            case ElementType::USHORT4: return VertexFormat::Unorm8x4;
            default:
                FILAMENT_CHECK_POSTCONDITION(false) << "Normalized format does not exist.";
                return VertexFormat::Float32x3;
        }
    }
    switch (type) {
        // Single Component Types
        // There is no direct alternative for SSCALED in webgpu. Convert them to Float32 directly.
        // This will result in increased memory on the cpu side.
        // TODO: Is Float16 acceptable instead with some potential accuracy errors?
        case ElementType::BYTE: return integer ? VertexFormat::Sint8 : VertexFormat::Float32;
        case ElementType::UBYTE: return integer ? VertexFormat::Uint8 : VertexFormat::Float32;
        case ElementType::SHORT: return integer ? VertexFormat::Sint16 : VertexFormat::Float32;
        case ElementType::USHORT: return integer ? VertexFormat::Uint16 : VertexFormat::Float32;
        case ElementType::HALF: return VertexFormat::Float16;
        case ElementType::INT: return VertexFormat::Sint32;
        case ElementType::UINT: return VertexFormat::Uint32;
        case ElementType::FLOAT: return VertexFormat::Float32;
        // Two Component Types
        case ElementType::BYTE2: return integer ? VertexFormat::Sint8x2 : VertexFormat::Float32x2;
        case ElementType::UBYTE2: return integer ? VertexFormat::Uint8x2 : VertexFormat::Float32x2;
        case ElementType::SHORT2: return integer ? VertexFormat::Sint16x2 : VertexFormat::Float32x2;
        case ElementType::USHORT2: return integer ? VertexFormat::Uint16x2 : VertexFormat::Float32x2;
        case ElementType::HALF2: return VertexFormat::Float16x2;
        case ElementType::FLOAT2: return VertexFormat::Float32x2;
        // Three Component Types
        case ElementType::BYTE3: return VertexFormat::Sint8x4;    // NOT MINSPEC
        case ElementType::UBYTE3: return VertexFormat::Uint8x4;   // NOT MINSPEC
        case ElementType::SHORT3: return VertexFormat::Sint16x4;  // NOT MINSPEC
        case ElementType::USHORT3: return VertexFormat::Uint16x4; // NOT MINSPEC
        case ElementType::HALF3: return VertexFormat::Float16x4;  // NOT MINSPEC
        case ElementType::FLOAT3: return VertexFormat::Float32x3;
        // Four Component Types
        case ElementType::BYTE4: return integer ? VertexFormat::Sint8x4 : VertexFormat::Float32x4;
        case ElementType::UBYTE4: return integer ? VertexFormat::Uint8x4 : VertexFormat::Float32x4;