diff --git a/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp b/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp index 0ceca8d79c..79cacd9be1 100644 --- a/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp +++ b/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp @@ -96,7 +96,17 @@ size_t ScalarTypeSize(ScalarType scalarType) { // 3. "Padding": Add `size` bytes of padding bytes into buffer; // 4. "FillingFixed": Fill all `size` given (fixed) bytes into the memory buffer. // Note that data bytes and padding bytes are generated seperatedly and designed to -// be distinguishable, i.e. data bytes have MSB set to 0 while padding bytes 1. +// be distinguishable, i.e. data bytes have the second most significant bit set to 0 while padding +// bytes 1. +// We don't want testing data includes NaN or Inf, because according to WGSL spec an implementation +// may give indeterminate value if a expression evaluated to NaN or Inf, and in Tint generated +// HLSL reading a f16 NaN from buffer is not bit-pattern preserved (i.e. a NaN input may be changed +// to another NaN with different bit pattern). In bit representation of both f32 and f16, the first +// (most significant) bit is sign bit, and some biased exponent bits go after it (start from the +// second most significant bit). A float value is NaN or Inf if and only if all its exponent bits +// are 1. By setting the second most significant bit of every data byte to 0, we ensure that the +// second most significant bit of any float data in the buffer is 0, and therefore avoid generating +// NaN or Inf float datas. class MemoryDataBuilder { public: // Record a "Align" operation @@ -150,15 +160,20 @@ class MemoryDataBuilder { uint8_t paddingXorKey) { uint8_t dataByte = 0x0u; uint8_t paddingByte = 0x2u; - // Get a data byte with MSB set to 0. + // Padding mask, setting the second most significant bit to 1 + constexpr uint8_t paddingMask = 0x40u; + // Data mask, masking the second most significant bit to 0, distinguished from padding + // bytes and avoid NaN or Inf. + constexpr uint8_t dataMask = ~paddingMask; + // Get a data byte auto NextDataByte = [&]() { dataByte += 0x11u; - return static_cast((dataByte ^ dataXorKey) & 0x7fu); + return static_cast((dataByte ^ dataXorKey) & dataMask); }; - // Get a padding byte with MSB set to 1, distinguished from data bytes. + // Get a padding byte auto NextPaddingByte = [&]() { paddingByte += 0x13u; - return static_cast((paddingByte ^ paddingXorKey) | 0x80u); + return static_cast((paddingByte ^ paddingXorKey) | paddingMask); }; for (auto& operation : mOperations) { switch (operation.mType) { @@ -234,10 +249,11 @@ class Field { public: // Constructor with WGSL type name, natural alignment and natural size. Set mStrideDataBytes to // natural size and mStridePaddingBytes to 0 by default to indicate continious data part. - Field(std::string wgslType, size_t align, size_t size) + Field(std::string wgslType, size_t align, size_t size, bool requireF16Feature) : mWGSLType(wgslType), mAlign(align), mSize(size), + mRequireF16Feature(requireF16Feature), mStrideDataBytes(size), mStridePaddingBytes(0) {} @@ -247,6 +263,7 @@ class Field { size_t GetUnpaddedSize() const { return mSize; } // The padded size determined by @size attribute if existed, otherwise the natural size size_t GetPaddedSize() const { return mHasSizeAttribute ? mPaddedSize : mSize; } + bool IsRequireF16Feature() const { return mRequireF16Feature; } // Applies a @size attribute, sets the mPaddedSize to value. // Returns this Field so calls can be chained. @@ -337,7 +354,8 @@ class Field { // Helper function to build a Field describing a scalar type. static Field Scalar(ScalarType type) { - return Field(ScalarTypeName(type), ScalarTypeSize(type), ScalarTypeSize(type)); + return Field(ScalarTypeName(type), ScalarTypeSize(type), ScalarTypeSize(type), + type == ScalarType::f16); } // Helper function to build a Field describing a vector type. @@ -347,7 +365,7 @@ class Field { size_t vectorSize = n * elementSize; size_t vectorAlignment = (n == 3 ? 4 : n) * elementSize; return Field{"vec" + std::to_string(n) + "<" + ScalarTypeName(type) + ">", vectorAlignment, - vectorSize}; + vectorSize, type == ScalarType::f16}; } // Helper function to build a Field describing a matrix type. @@ -360,7 +378,7 @@ class Field { size_t colVectorAlignment = (row == 3 ? 4 : row) * elementSize; Field field = Field{"mat" + std::to_string(col) + "x" + std::to_string(row) + "<" + ScalarTypeName(type) + ">", - colVectorAlignment, col * colVectorAlignment}; + colVectorAlignment, col * colVectorAlignment, type == ScalarType::f16}; if (colVectorSize != colVectorAlignment) { field.Strided(colVectorSize, colVectorAlignment - colVectorSize); } @@ -371,6 +389,7 @@ class Field { const std::string mWGSLType; // Friendly WGSL name of the type of the field size_t mAlign; // Alignment of the type in bytes, can be change by @align attribute const size_t mSize; // Natural size of the type in bytes + const bool mRequireF16Feature; bool mHasAlignAttribute = false; bool mHasSizeAttribute = false; @@ -392,6 +411,25 @@ std::ostream& operator<<(std::ostream& o, Field field) { return o; } +std::ostream& operator<<(std::ostream& o, const std::vector& byteBuffer) { + o << "\n"; + uint32_t i = 0; + for (auto byte : byteBuffer) { + o << std::hex << std::setw(2) << std::setfill('0') << uint32_t(byte); + if (i < 31) { + o << " "; + i++; + } else { + o << "\n"; + i = 0; + } + } + if (i != 0) { + o << "\n"; + } + return o; +} + // Create a compute pipeline with all buffer in bufferList binded in order starting from slot 0, and // run the given shader. void RunComputeShaderWithBuffers(const wgpu::Device& device, @@ -445,7 +483,40 @@ DAWN_TEST_PARAM_STRUCT(ComputeLayoutMemoryBufferTestParams, AddressSpace, Field) class ComputeLayoutMemoryBufferTests : public DawnTestWithParams { - void SetUp() override { DawnTestBase::SetUp(); } + // void SetUp() override { DawnTestBase::SetUp(); } + + protected: + // Require f16 feature if possible + std::vector GetRequiredFeatures() override { + mIsShaderF16SupportedOnAdapter = SupportsFeatures({wgpu::FeatureName::ShaderF16}); + if (!mIsShaderF16SupportedOnAdapter) { + return {}; + } + + if (!IsD3D12()) { + mUseDxcEnabledOrNonD3D12 = true; + } else { + for (auto* enabledToggle : GetParam().forceEnabledWorkarounds) { + if (strncmp(enabledToggle, "use_dxc", 7) == 0) { + mUseDxcEnabledOrNonD3D12 = true; + break; + } + } + } + + if (mUseDxcEnabledOrNonD3D12) { + return {wgpu::FeatureName::ShaderF16}; + } + + return {}; + } + + bool IsShaderF16SupportedOnAdapter() const { return mIsShaderF16SupportedOnAdapter; } + bool UseDxcEnabledOrNonD3D12() const { return mUseDxcEnabledOrNonD3D12; } + + private: + bool mIsShaderF16SupportedOnAdapter = false; + bool mUseDxcEnabledOrNonD3D12 = false; }; // Align returns the WGSL decoration for an explicit structure field alignment @@ -472,9 +543,14 @@ TEST_P(ComputeLayoutMemoryBufferTests, StructMember) { const Field& field = GetParam().mField; + if (field.IsRequireF16Feature() && !device.HasFeature(wgpu::FeatureName::ShaderF16)) { + return; + } + const bool isUniform = GetParam().mAddressSpace == AddressSpace::Uniform; - std::string shader = R"( + std::string shader = std::string(field.IsRequireF16Feature() ? "enable f16;" : "") + + R"( struct Data { header : u32, @align({field_align}) @size({field_size}) field : {field_type}, @@ -553,6 +629,7 @@ fn main() { { inputDataBuilder.AddFixedU32(kDataHeaderCode); // Input.data.header inputDataBuilder.AddSubBuilder(field.GetDataBuilder()); // Input.data.field + inputDataBuilder.AlignTo(4); // Input.data.footer alignment inputDataBuilder.AddFixedU32(kDataFooterCode); // Input.data.footer inputDataBuilder.AlignTo(field.GetAlign()); // Input.data padding } @@ -563,6 +640,7 @@ fn main() { MemoryDataBuilder expectedDataBuilder; // The expected data to be copied by the shader expectedDataBuilder.AddSubBuilder(field.GetDataBuilder()); + expectedDataBuilder.AlignTo(4); // Storage buffer size must be a multiple of 4 // Expectation and input buffer have identical data bytes but different padding bytes. // Initializes the dst buffer with data bytes different from input and expectation, and padding @@ -603,25 +681,36 @@ fn main() { EXPECT_BUFFER_U32_EQ(kStatusOk, statusBuf, 0) << "status code error" << std::endl << "Shader: " << shader; - // Check the data + // Check the data. Note that MemoryDataBuilder avoid generating NaN and Inf floating point data, + // whose bit pattern will not get preserved when reading from buffer (arbitrary NaNs may be + // silently transformed into a quiet NaN). Having NaN and Inf floating point data in input may + // result in bitwise mismatch. field.CheckData([&](uint32_t offset, uint32_t size) { EXPECT_BUFFER_U8_RANGE_EQ(expectedData.data() + offset, outputBuf, offset, size) - << "offset: " << offset; + << "offset: " << offset << "\n Input buffer:" << inputData << "Shader:\n" + << shader << "\n"; }); } // Test different types that used directly as buffer type TEST_P(ComputeLayoutMemoryBufferTests, NonStructMember) { auto params = GetParam(); + Field& field = params.mField; + // @size and @align attribute only apply to struct members, skip them if (field.HasSizeAttribute() || field.HasAlignAttribute()) { return; } + if (field.IsRequireF16Feature() && !device.HasFeature(wgpu::FeatureName::ShaderF16)) { + return; + } + const bool isUniform = GetParam().mAddressSpace == AddressSpace::Uniform; - std::string shader = R"( + std::string shader = std::string(field.IsRequireF16Feature() ? "enable f16;" : "") + + R"( @group(0) @binding(0) var<{input_qualifiers}> input : {field_type}; @group(0) @binding(1) var output : {field_type}; @@ -638,10 +727,11 @@ fn main() { // Build the input and expected data. MemoryDataBuilder dataBuilder; dataBuilder.AddSubBuilder(field.GetDataBuilder()); + dataBuilder.AlignTo(4); // Storage buffer size must be a multiple of 4 // Expectation and input buffer have identical data bytes but different padding bytes. - // Initializes the dst buffer with data bytes different from input and expectation, and padding - // bytes identical to expectation but different from input. + // Initializes the dst buffer with data bytes different from input and expectation, and + // padding bytes identical to expectation but different from input. constexpr uint8_t dataKeyForInputAndExpectation = 0x00u; constexpr uint8_t dataKeyForDstInit = 0xffu; constexpr uint8_t paddingKeyForInput = 0x3fu; @@ -669,10 +759,14 @@ fn main() { RunComputeShaderWithBuffers(device, queue, shader, {inputBuf, outputBuf}); - // Check the data + // Check the data. Note that MemoryDataBuilder avoid generating NaN and Inf floating point data, + // whose bit pattern will not get preserved when reading from buffer (arbitrary NaNs may be + // silently transformed into a quiet NaN). Having NaN and Inf floating point data in input may + // result in bitwise mismatch. field.CheckData([&](uint32_t offset, uint32_t size) { EXPECT_BUFFER_U8_RANGE_EQ(expectedData.data() + offset, outputBuf, offset, size) - << "offset: " << offset; + << "offset: " << offset << "\n Input buffer:" << inputData << "Shader:\n" + << shader << "\n"; }); } @@ -680,6 +774,7 @@ auto GenerateParams() { auto params = MakeParamGenerator( { D3D12Backend(), + D3D12Backend({"use_dxc"}), MetalBackend(), VulkanBackend(), OpenGLBackend(), @@ -692,16 +787,19 @@ auto GenerateParams() { Field::Scalar(ScalarType::f32), Field::Scalar(ScalarType::i32), Field::Scalar(ScalarType::u32), + Field::Scalar(ScalarType::f16), // Scalar types with custom alignment Field::Scalar(ScalarType::f32).AlignAttribute(16), Field::Scalar(ScalarType::i32).AlignAttribute(16), Field::Scalar(ScalarType::u32).AlignAttribute(16), + Field::Scalar(ScalarType::f16).AlignAttribute(16), // Scalar types with custom size Field::Scalar(ScalarType::f32).SizeAttribute(24), Field::Scalar(ScalarType::i32).SizeAttribute(24), Field::Scalar(ScalarType::u32).SizeAttribute(24), + Field::Scalar(ScalarType::f16).SizeAttribute(24), // Vector types with no custom alignment or size Field::Vector(2, ScalarType::f32), @@ -713,6 +811,9 @@ auto GenerateParams() { Field::Vector(2, ScalarType::u32), Field::Vector(3, ScalarType::u32), Field::Vector(4, ScalarType::u32), + Field::Vector(2, ScalarType::f16), + Field::Vector(3, ScalarType::f16), + Field::Vector(4, ScalarType::f16), // Vector types with custom alignment Field::Vector(2, ScalarType::f32).AlignAttribute(32), @@ -724,6 +825,9 @@ auto GenerateParams() { Field::Vector(2, ScalarType::u32).AlignAttribute(32), Field::Vector(3, ScalarType::u32).AlignAttribute(32), Field::Vector(4, ScalarType::u32).AlignAttribute(32), + Field::Vector(2, ScalarType::f16).AlignAttribute(32), + Field::Vector(3, ScalarType::f16).AlignAttribute(32), + Field::Vector(4, ScalarType::f16).AlignAttribute(32), // Vector types with custom size Field::Vector(2, ScalarType::f32).SizeAttribute(24), @@ -735,6 +839,9 @@ auto GenerateParams() { Field::Vector(2, ScalarType::u32).SizeAttribute(24), Field::Vector(3, ScalarType::u32).SizeAttribute(24), Field::Vector(4, ScalarType::u32).SizeAttribute(24), + Field::Vector(2, ScalarType::f16).SizeAttribute(24), + Field::Vector(3, ScalarType::f16).SizeAttribute(24), + Field::Vector(4, ScalarType::f16).SizeAttribute(24), // Matrix types with no custom alignment or size Field::Matrix(2, 2, ScalarType::f32), @@ -746,6 +853,15 @@ auto GenerateParams() { Field::Matrix(2, 4, ScalarType::f32), Field::Matrix(3, 4, ScalarType::f32), Field::Matrix(4, 4, ScalarType::f32), + Field::Matrix(2, 2, ScalarType::f16), + Field::Matrix(3, 2, ScalarType::f16), + Field::Matrix(4, 2, ScalarType::f16), + Field::Matrix(2, 3, ScalarType::f16), + Field::Matrix(3, 3, ScalarType::f16), + Field::Matrix(4, 3, ScalarType::f16), + Field::Matrix(2, 4, ScalarType::f16), + Field::Matrix(3, 4, ScalarType::f16), + Field::Matrix(4, 4, ScalarType::f16), // Matrix types with custom alignment Field::Matrix(2, 2, ScalarType::f32).AlignAttribute(32), @@ -757,6 +873,15 @@ auto GenerateParams() { Field::Matrix(2, 4, ScalarType::f32).AlignAttribute(32), Field::Matrix(3, 4, ScalarType::f32).AlignAttribute(32), Field::Matrix(4, 4, ScalarType::f32).AlignAttribute(32), + Field::Matrix(2, 2, ScalarType::f16).AlignAttribute(32), + Field::Matrix(3, 2, ScalarType::f16).AlignAttribute(32), + Field::Matrix(4, 2, ScalarType::f16).AlignAttribute(32), + Field::Matrix(2, 3, ScalarType::f16).AlignAttribute(32), + Field::Matrix(3, 3, ScalarType::f16).AlignAttribute(32), + Field::Matrix(4, 3, ScalarType::f16).AlignAttribute(32), + Field::Matrix(2, 4, ScalarType::f16).AlignAttribute(32), + Field::Matrix(3, 4, ScalarType::f16).AlignAttribute(32), + Field::Matrix(4, 4, ScalarType::f16).AlignAttribute(32), // Matrix types with custom size Field::Matrix(2, 2, ScalarType::f32).SizeAttribute(128), @@ -768,85 +893,241 @@ auto GenerateParams() { Field::Matrix(2, 4, ScalarType::f32).SizeAttribute(128), Field::Matrix(3, 4, ScalarType::f32).SizeAttribute(128), Field::Matrix(4, 4, ScalarType::f32).SizeAttribute(128), + Field::Matrix(2, 2, ScalarType::f16).SizeAttribute(128), + Field::Matrix(3, 2, ScalarType::f16).SizeAttribute(128), + Field::Matrix(4, 2, ScalarType::f16).SizeAttribute(128), + Field::Matrix(2, 3, ScalarType::f16).SizeAttribute(128), + Field::Matrix(3, 3, ScalarType::f16).SizeAttribute(128), + Field::Matrix(4, 3, ScalarType::f16).SizeAttribute(128), + Field::Matrix(2, 4, ScalarType::f16).SizeAttribute(128), + Field::Matrix(3, 4, ScalarType::f16).SizeAttribute(128), + Field::Matrix(4, 4, ScalarType::f16).SizeAttribute(128), // Array types with no custom alignment or size. - // Note: The use of StorageBufferOnly() is due to UBOs requiring 16 byte alignment - // of array elements. See https://www.w3.org/TR/WGSL/#storage-class-constraints - Field("array", /* align */ 4, /* size */ 4).StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 8).StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 12).StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 16).StorageBufferOnly(), - Field("array, 1>", /* align */ 8, /* size */ 8).StorageBufferOnly(), - Field("array, 2>", /* align */ 8, /* size */ 16).StorageBufferOnly(), - Field("array, 3>", /* align */ 8, /* size */ 24).StorageBufferOnly(), - Field("array, 4>", /* align */ 8, /* size */ 32).StorageBufferOnly(), - Field("array, 1>", /* align */ 16, /* size */ 16).Strided(12, 4), - Field("array, 2>", /* align */ 16, /* size */ 32).Strided(12, 4), - Field("array, 3>", /* align */ 16, /* size */ 48).Strided(12, 4), - Field("array, 4>", /* align */ 16, /* size */ 64).Strided(12, 4), - Field("array, 1>", /* align */ 16, /* size */ 16), - Field("array, 2>", /* align */ 16, /* size */ 32), - Field("array, 3>", /* align */ 16, /* size */ 48), - Field("array, 4>", /* align */ 16, /* size */ 64), + // Note: The use of StorageBufferOnly() is due to UBOs requiring 16 byte + // alignment of array elements. See + // https://www.w3.org/TR/WGSL/#storage-class-constraints + Field("array", /* align */ 4, /* size */ 4, /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array", /* align */ 4, /* size */ 8, /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array", /* align */ 4, /* size */ 12, /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array", /* align */ 4, /* size */ 16, /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array, 1>", /* align */ 8, /* size */ 8, /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array, 2>", /* align */ 8, /* size */ 16, + /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 24, + /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array, 4>", /* align */ 8, /* size */ 32, + /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array, 1>", /* align */ 16, /* size */ 16, + /* requireF16Feature */ false) + .Strided(12, 4), + Field("array, 2>", /* align */ 16, /* size */ 32, + /* requireF16Feature */ false) + .Strided(12, 4), + Field("array, 3>", /* align */ 16, /* size */ 48, + /* requireF16Feature */ false) + .Strided(12, 4), + Field("array, 4>", /* align */ 16, /* size */ 64, + /* requireF16Feature */ false) + .Strided(12, 4), + Field("array, 1>", /* align */ 16, /* size */ 16, + /* requireF16Feature */ false), + Field("array, 2>", /* align */ 16, /* size */ 32, + /* requireF16Feature */ false), + Field("array, 3>", /* align */ 16, /* size */ 48, + /* requireF16Feature */ false), + Field("array, 4>", /* align */ 16, /* size */ 64, + /* requireF16Feature */ false), // Array types with custom alignment - Field("array", /* align */ 4, /* size */ 4) + Field("array", /* align */ 4, /* size */ 4, /* requireF16Feature */ false) .AlignAttribute(32) .StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 8) + Field("array", /* align */ 4, /* size */ 8, /* requireF16Feature */ false) .AlignAttribute(32) .StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 12) + Field("array", /* align */ 4, /* size */ 12, /* requireF16Feature */ false) .AlignAttribute(32) .StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 16) + Field("array", /* align */ 4, /* size */ 16, /* requireF16Feature */ false) .AlignAttribute(32) .StorageBufferOnly(), - Field("array, 1>", /* align */ 8, /* size */ 8) + Field("array, 1>", /* align */ 8, /* size */ 8, /* requireF16Feature */ false) .AlignAttribute(32) .StorageBufferOnly(), - Field("array, 2>", /* align */ 8, /* size */ 16) + Field("array, 2>", /* align */ 8, /* size */ 16, + /* requireF16Feature */ false) .AlignAttribute(32) .StorageBufferOnly(), - Field("array, 3>", /* align */ 8, /* size */ 24) + Field("array, 3>", /* align */ 8, /* size */ 24, + /* requireF16Feature */ false) .AlignAttribute(32) .StorageBufferOnly(), - Field("array, 4>", /* align */ 8, /* size */ 32) + Field("array, 4>", /* align */ 8, /* size */ 32, + /* requireF16Feature */ false) .AlignAttribute(32) .StorageBufferOnly(), - Field("array, 1>", /* align */ 16, /* size */ 16) + Field("array, 1>", /* align */ 16, /* size */ 16, + /* requireF16Feature */ false) .AlignAttribute(32) .Strided(12, 4), - Field("array, 2>", /* align */ 16, /* size */ 32) + Field("array, 2>", /* align */ 16, /* size */ 32, + /* requireF16Feature */ false) .AlignAttribute(32) .Strided(12, 4), - Field("array, 3>", /* align */ 16, /* size */ 48) + Field("array, 3>", /* align */ 16, /* size */ 48, + /* requireF16Feature */ false) .AlignAttribute(32) .Strided(12, 4), - Field("array, 4>", /* align */ 16, /* size */ 64) + Field("array, 4>", /* align */ 16, /* size */ 64, + /* requireF16Feature */ false) .AlignAttribute(32) .Strided(12, 4), - Field("array, 1>", /* align */ 16, /* size */ 16).AlignAttribute(32), - Field("array, 2>", /* align */ 16, /* size */ 32).AlignAttribute(32), - Field("array, 3>", /* align */ 16, /* size */ 48).AlignAttribute(32), - Field("array, 4>", /* align */ 16, /* size */ 64).AlignAttribute(32), + Field("array, 1>", /* align */ 16, /* size */ 16, + /* requireF16Feature */ false) + .AlignAttribute(32), + Field("array, 2>", /* align */ 16, /* size */ 32, + /* requireF16Feature */ false) + .AlignAttribute(32), + Field("array, 3>", /* align */ 16, /* size */ 48, + /* requireF16Feature */ false) + .AlignAttribute(32), + Field("array, 4>", /* align */ 16, /* size */ 64, + /* requireF16Feature */ false) + .AlignAttribute(32), // Array types with custom size - Field("array", /* align */ 4, /* size */ 4) + Field("array", /* align */ 4, /* size */ 4, /* requireF16Feature */ false) .SizeAttribute(128) .StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 8) + Field("array", /* align */ 4, /* size */ 8, /* requireF16Feature */ false) .SizeAttribute(128) .StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 12) + Field("array", /* align */ 4, /* size */ 12, /* requireF16Feature */ false) .SizeAttribute(128) .StorageBufferOnly(), - Field("array", /* align */ 4, /* size */ 16) + Field("array", /* align */ 4, /* size */ 16, /* requireF16Feature */ false) .SizeAttribute(128) .StorageBufferOnly(), - Field("array, 4>", /* align */ 16, /* size */ 64) + Field("array, 4>", /* align */ 16, /* size */ 64, + /* requireF16Feature */ false) .SizeAttribute(128) .Strided(12, 4), + + // Array of f32 matrix + Field("array, 3>", /* align */ 8, /* size */ 48, + /* requireF16Feature */ false) + .StorageBufferOnly(), + // Uniform scope require the array alignment round up to 16. + Field("array, 3>", /* align */ 8, /* size */ 48, + /* requireF16Feature */ false) + .AlignAttribute(16), + Field("array, 3>", /* align */ 16, /* size */ 96, + /* requireF16Feature */ false) + .Strided(12, 4), + Field("array, 3>", /* align */ 16, /* size */ 96, + /* requireF16Feature */ false), + Field("array, 3>", /* align */ 8, /* size */ 72, + /* requireF16Feature */ false) + .StorageBufferOnly(), + // `mat3x2` can not be the element type of a uniform array, because its size 24 is + // not a multiple of 16. + Field("array, 3>", /* align */ 8, /* size */ 72, + /* requireF16Feature */ false) + .AlignAttribute(16) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 16, /* size */ 144, + /* requireF16Feature */ false) + .Strided(12, 4), + Field("array, 3>", /* align */ 16, /* size */ 144, + /* requireF16Feature */ false), + Field("array, 3>", /* align */ 8, /* size */ 96, + /* requireF16Feature */ false) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 96, + /* requireF16Feature */ false) + .AlignAttribute(16), + Field("array, 3>", /* align */ 16, /* size */ 192, + /* requireF16Feature */ false) + .Strided(12, 4), + Field("array, 3>", /* align */ 16, /* size */ 192, + /* requireF16Feature */ false), + + // Array of f16 matrix + Field("array, 3>", /* align */ 4, /* size */ 24, + /* requireF16Feature */ true) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 48, + /* requireF16Feature */ true) + .Strided(6, 2) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 48, + /* requireF16Feature */ true) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 4, /* size */ 36, + /* requireF16Feature */ true) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 72, + /* requireF16Feature */ true) + .Strided(6, 2) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 72, + /* requireF16Feature */ true) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 4, /* size */ 48, + /* requireF16Feature */ true) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 96, + /* requireF16Feature */ true) + .Strided(6, 2) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 96, + /* requireF16Feature */ true) + .StorageBufferOnly(), + // Uniform scope require the array alignment round up to 16, and array element size a + // multiple of 16. + Field("array, 3>", /* align */ 4, /* size */ 24, + /* requireF16Feature */ true) + .AlignAttribute(16) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 48, + /* requireF16Feature */ true) + .AlignAttribute(16) + .Strided(6, 2), + Field("array, 3>", /* align */ 8, /* size */ 48, + /* requireF16Feature */ true) + .AlignAttribute(16), + Field("array, 3>", /* align */ 4, /* size */ 36, + /* requireF16Feature */ true) + .AlignAttribute(16) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 72, + /* requireF16Feature */ true) + .AlignAttribute(16) + .Strided(6, 2) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 8, /* size */ 72, + /* requireF16Feature */ true) + .AlignAttribute(16) + .StorageBufferOnly(), + Field("array, 3>", /* align */ 4, /* size */ 48, + /* requireF16Feature */ true) + .AlignAttribute(16), + Field("array, 3>", /* align */ 8, /* size */ 96, + /* requireF16Feature */ true) + .AlignAttribute(16) + .Strided(6, 2), + Field("array, 3>", /* align */ 8, /* size */ 96, + /* requireF16Feature */ true) + .AlignAttribute(16), }); std::vector filtered; diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index 491fd7dabb..3741764d47 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -1246,6 +1246,8 @@ if (tint_build_unittests) { "transform/single_entry_point_test.cc", "transform/spirv_atomic_test.cc", "transform/std140_exhaustive_test.cc", + "transform/std140_f16_test.cc", + "transform/std140_f32_test.cc", "transform/std140_test.cc", "transform/substitute_override_test.cc", "transform/test_helper.h", diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt index dfe943388a..a8644b7341 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -1212,6 +1212,8 @@ if(TINT_BUILD_TESTS) transform/single_entry_point_test.cc transform/spirv_atomic_test.cc transform/std140_exhaustive_test.cc + transform/std140_f16_test.cc + transform/std140_f32_test.cc transform/std140_test.cc transform/substitute_override_test.cc transform/test_helper.h diff --git a/src/tint/resolver/address_space_layout_validation_test.cc b/src/tint/resolver/address_space_layout_validation_test.cc index 82da573667..b34b88928e 100644 --- a/src/tint/resolver/address_space_layout_validation_test.cc +++ b/src/tint/resolver/address_space_layout_validation_test.cc @@ -363,6 +363,29 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_Vec3MemberOffset_ ASSERT_TRUE(r()->Resolve()) << r()->error(); } +// Make sure that this doesn't fail validation because vec3's align is 8, but +// size is 6. 's' should be at offset 6, which is okay here. +TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_Vec3F16MemberOffset_NoFail) { + // struct ScalarPackedAtEndOfVec3 { + // v : vec3; + // s : f16; + // }; + // @group(0) @binding(0) + // var a : ScalarPackedAtEndOfVec3; + + Enable(ast::Extension::kF16); + + Structure("ScalarPackedAtEndOfVec3", utils::Vector{ + Member("v", ty.vec3(ty.f16())), + Member("s", ty.f16()), + }); + + GlobalVar(Source{{78, 90}}, "a", ty.type_name("ScalarPackedAtEndOfVec3"), + ast::AddressSpace::kUniform, Group(0_a), Binding(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + // Detect array stride must be a multiple of 16 bytes for uniform buffers TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_Scalar) { // type Inner = array; diff --git a/src/tint/resolver/address_space_validation_test.cc b/src/tint/resolver/address_space_validation_test.cc index 3ef19a652c..60e54df5d8 100644 --- a/src/tint/resolver/address_space_validation_test.cc +++ b/src/tint/resolver/address_space_validation_test.cc @@ -113,98 +113,6 @@ TEST_F(ResolverAddressSpaceValidationTest, StorageBufferBoolAlias) { 56:78 note: while instantiating 'var' g)"); } -// F16 types in storage and uniform buffer is not implemented yet. -// TODO(tint:1473, tint:1502): make these testcases valid after f16 is supported. -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferF16_TemporallyBan) { - // var g : f16; - Enable(ast::Extension::kF16); - - GlobalVar("g", ty.f16(Source{{56, 78}}), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_EQ(r()->error(), - "56:78 error: using f16 types in 'storage' address space is not " - "implemented yet"); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferF16Alias_TemporallyBan) { - // type a = f16; - // var g : a; - Enable(ast::Extension::kF16); - - auto* a = Alias("a", ty.f16()); - GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::AddressSpace::kStorage, - Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_EQ(r()->error(), - "56:78 error: using f16 types in 'storage' address space is not " - "implemented yet"); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferVectorF16_TemporallyBan) { - // var g : vec4; - Enable(ast::Extension::kF16); - GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of(), 4u), ast::AddressSpace::kStorage, - Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_EQ(r()->error(), - "56:78 error: using f16 types in 'storage' address space is not " - "implemented yet"); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferArrayF16_TemporallyBan) { - // struct S { a : f16 }; - // var g : array; - Enable(ast::Extension::kF16); - - auto* s = Structure("S", utils::Vector{Member("a", ty.f16(Source{{56, 78}}))}); - auto* a = ty.array(ty.Of(s), 3_u); - GlobalVar("g", a, ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'storage' address " - "space is not implemented yet")); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructF16_TemporallyBan) { - // struct S { x : f16 }; - // var g : S; - Enable(ast::Extension::kF16); - - auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))}); - GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), - Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'storage' address " - "space is not implemented yet")); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferNoErrorStructF16Aliases_TemporallyBan) { - // struct S { x : f16 }; - // type a1 = S; - // var g : a1; - Enable(ast::Extension::kF16); - - auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))}); - auto* a1 = Alias("a1", ty.Of(s)); - auto* a2 = Alias("a2", ty.Of(a1)); - GlobalVar("g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), - Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'storage' address " - "space is not implemented yet")); -} - TEST_F(ResolverAddressSpaceValidationTest, StorageBufferPointer) { // var g : ptr; GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate), @@ -226,6 +134,27 @@ TEST_F(ResolverAddressSpaceValidationTest, StorageBufferIntScalar) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverAddressSpaceValidationTest, StorageBufferF16) { + // var g : f16; + Enable(ast::Extension::kF16); + + GlobalVar("g", ty.f16(Source{{56, 78}}), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, StorageBufferF16Alias) { + // type a = f16; + // var g : a; + Enable(ast::Extension::kF16); + + auto* a = Alias("a", ty.f16()); + GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::AddressSpace::kStorage, + Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + TEST_F(ResolverAddressSpaceValidationTest, StorageBufferVectorF32) { // var g : vec4; GlobalVar(Source{{56, 78}}, "g", ty.vec4(), ast::AddressSpace::kStorage, Binding(0_a), @@ -234,6 +163,15 @@ TEST_F(ResolverAddressSpaceValidationTest, StorageBufferVectorF32) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverAddressSpaceValidationTest, StorageBufferVectorF16) { + // var g : vec4; + Enable(ast::Extension::kF16); + GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of(), 4u), ast::AddressSpace::kStorage, + Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + TEST_F(ResolverAddressSpaceValidationTest, StorageBufferArrayF32) { // var g : array; auto* s = Structure("S", utils::Vector{Member("a", ty.f32())}); @@ -244,6 +182,68 @@ TEST_F(ResolverAddressSpaceValidationTest, StorageBufferArrayF32) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverAddressSpaceValidationTest, StorageBufferArrayF16) { + // var g : array; + Enable(ast::Extension::kF16); + + auto* s = Structure("S", utils::Vector{Member("a", ty.f16())}); + auto* a = ty.array(ty.Of(s), 3_u); + GlobalVar(Source{{56, 78}}, "g", a, ast::AddressSpace::kStorage, ast::Access::kRead, + Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructI32) { + // struct S { x : i32 }; + // var g : S; + auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())}); + GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, + Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructI32Aliases) { + // struct S { x : i32 }; + // type a1 = S; + // var g : a1; + auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())}); + auto* a1 = Alias("a1", ty.Of(s)); + auto* a2 = Alias("a2", ty.Of(a1)); + GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, + Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructF16) { + // struct S { x : f16 }; + // var g : S; + Enable(ast::Extension::kF16); + + auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))}); + GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), + Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructF16Aliases) { + // struct S { x : f16 }; + // type a1 = S; + // var g : a1; + Enable(ast::Extension::kF16); + + auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))}); + auto* a1 = Alias("a1", ty.Of(s)); + auto* a2 = Alias("a2", ty.Of(a1)); + GlobalVar("g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), + Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + TEST_F(ResolverAddressSpaceValidationTest, NotStorage_AccessMode) { // var g : a; GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kPrivate, ast::Access::kRead); @@ -282,29 +282,6 @@ TEST_F(ResolverAddressSpaceValidationTest, Storage_WriteAccessMode) { R"(56:78 error: access mode 'write' is not valid for the 'storage' address space)"); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructI32) { - // struct S { x : i32 }; - // var g : S; - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())}); - GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, - Binding(0_a), Group(0_a)); - - ASSERT_TRUE(r()->Resolve()); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferNoErrorStructI32Aliases) { - // struct S { x : i32 }; - // type a1 = S; - // var g : a1; - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())}); - auto* a1 = Alias("a1", ty.Of(s)); - auto* a2 = Alias("a2", ty.Of(a1)); - GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, - Binding(0_a), Group(0_a)); - - ASSERT_TRUE(r()->Resolve()); -} - TEST_F(ResolverAddressSpaceValidationTest, UniformBuffer_Struct_Runtime) { // struct S { m: array; }; // @group(0) @binding(0) var svar : S; @@ -349,97 +326,6 @@ TEST_F(ResolverAddressSpaceValidationTest, UniformBufferBoolAlias) { 56:78 note: while instantiating 'var' g)"); } -// F16 types in storage and uniform buffer is not implemented yet. -// TODO(tint:1473, tint:1502): make these testcases valid after f16 is supported. -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferF16_TemporallyBan) { - // var g : f16; - Enable(ast::Extension::kF16); - - GlobalVar("g", ty.f16(Source{{56, 78}}), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_EQ(r()->error(), - "56:78 error: using f16 types in 'uniform' address space is not " - "implemented yet"); -} - -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferF16Alias_TemporallyBan) { - // type a = f16; - // var g : a; - Enable(ast::Extension::kF16); - - auto* a = Alias("a", ty.f16()); - GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::AddressSpace::kUniform, - Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_EQ(r()->error(), - "56:78 error: using f16 types in 'uniform' address space is not " - "implemented yet"); -} - -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferVectorF16_TemporallyBan) { - // var g : vec4; - Enable(ast::Extension::kF16); - GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of(), 4u), ast::AddressSpace::kUniform, - Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'uniform' address " - "space is not implemented yet")); -} - -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferArrayF16_TemporallyBan) { - // struct S { - // @size(16) f : f16; - // } - // var g : array; - Enable(ast::Extension::kF16); - - auto* s = Structure( - "S", utils::Vector{Member("a", ty.f16(Source{{56, 78}}), utils::Vector{MemberSize(16_a)})}); - auto* a = ty.array(ty.Of(s), 3_u); - GlobalVar("g", a, ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'uniform' address " - "space is not implemented yet")); -} - -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructF16_TemporallyBan) { - // struct S { x : f16 }; - // var g : S; - Enable(ast::Extension::kF16); - - auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))}); - GlobalVar("g", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'uniform' address " - "space is not implemented yet")); -} - -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructF16Aliases_TemporallyBan) { - // struct S { x : f16 }; - // type a1 = S; - // var g : a1; - Enable(ast::Extension::kF16); - - auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))}); - auto* a1 = Alias("a1", ty.Of(s)); - GlobalVar("g", ty.Of(a1), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'uniform' address " - "space is not implemented yet")); -} - TEST_F(ResolverAddressSpaceValidationTest, UniformBufferPointer) { // var g : ptr; GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate), @@ -461,6 +347,16 @@ TEST_F(ResolverAddressSpaceValidationTest, UniformBufferIntScalar) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverAddressSpaceValidationTest, UniformBufferF16) { + // var g : f16; + Enable(ast::Extension::kF16); + + GlobalVar(Source{{56, 78}}, "g", ty.f16(), ast::AddressSpace::kUniform, Binding(0_a), + Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + TEST_F(ResolverAddressSpaceValidationTest, UniformBufferVectorF32) { // var g : vec4; GlobalVar(Source{{56, 78}}, "g", ty.vec4(), ast::AddressSpace::kUniform, Binding(0_a), @@ -469,6 +365,16 @@ TEST_F(ResolverAddressSpaceValidationTest, UniformBufferVectorF32) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverAddressSpaceValidationTest, UniformBufferVectorF16) { + // var g : vec4; + Enable(ast::Extension::kF16); + + GlobalVar(Source{{56, 78}}, "g", ty.vec4(), ast::AddressSpace::kUniform, Binding(0_a), + Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + TEST_F(ResolverAddressSpaceValidationTest, UniformBufferArrayF32) { // struct S { // @size(16) f : f32; @@ -481,6 +387,20 @@ TEST_F(ResolverAddressSpaceValidationTest, UniformBufferArrayF32) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverAddressSpaceValidationTest, UniformBufferArrayF16) { + // struct S { + // @size(16) f : f16; + // } + // var g : array; + Enable(ast::Extension::kF16); + + auto* s = Structure("S", utils::Vector{Member("a", ty.f16(), utils::Vector{MemberSize(16_a)})}); + auto* a = ty.array(ty.Of(s), 3_u); + GlobalVar(Source{{56, 78}}, "g", a, ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructI32) { // struct S { x : i32 }; // var g : S; @@ -503,6 +423,32 @@ TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructI32Aliases) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructF16) { + // struct S { x : f16 }; + // var g : S; + Enable(ast::Extension::kF16); + + auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.f16())}); + GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), + Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructF16Aliases) { + // struct S { x : f16 }; + // type a1 = S; + // var g : a1; + Enable(ast::Extension::kF16); + + auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.f16())}); + auto* a1 = Alias("a1", ty.Of(s)); + GlobalVar(Source{{56, 78}}, "g", ty.Of(a1), ast::AddressSpace::kUniform, Binding(0_a), + Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + TEST_F(ResolverAddressSpaceValidationTest, PushConstantBool) { // enable chromium_experimental_push_constant; // var g : bool; diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc index 2fc8f21085..70d9f8e997 100644 --- a/src/tint/resolver/validator.cc +++ b/src/tint/resolver/validator.cc @@ -395,13 +395,11 @@ bool Validator::AddressSpaceLayout(const sem::Type* store_ty, return true; } - // Temporally forbid using f16 types in "uniform" and "storage" address space. - // TODO(tint:1473, tint:1502): Remove this error after f16 is supported in "uniform" and - // "storage" address space but keep for "push_constant" address space. - if (Is(sem::Type::DeepestElementOf(store_ty))) { - AddError("using f16 types in '" + utils::ToString(address_space) + - "' address space is not implemented yet", - source); + // Among three host-shareable address spaces, f16 is supported in "uniform" and + // "storage" address space, but not "push_constant" address space yet. + if (Is(sem::Type::DeepestElementOf(store_ty)) && + address_space == ast::AddressSpace::kPushConstant) { + AddError("using f16 types in 'push_constant' address space is not implemented yet", source); return false; } diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc index 046583e2a3..3be550ce1f 100644 --- a/src/tint/transform/decompose_memory_access.cc +++ b/src/tint/transform/decompose_memory_access.cc @@ -153,6 +153,10 @@ bool IntrinsicDataTypeFor(const sem::Type* ty, DecomposeMemoryAccess::Intrinsic: out = DecomposeMemoryAccess::Intrinsic::DataType::kF32; return true; } + if (ty->Is()) { + out = DecomposeMemoryAccess::Intrinsic::DataType::kF16; + return true; + } if (auto* vec = ty->As()) { switch (vec->Width()) { case 2: @@ -168,6 +172,10 @@ bool IntrinsicDataTypeFor(const sem::Type* ty, DecomposeMemoryAccess::Intrinsic: out = DecomposeMemoryAccess::Intrinsic::DataType::kVec2F32; return true; } + if (vec->type()->Is()) { + out = DecomposeMemoryAccess::Intrinsic::DataType::kVec2F16; + return true; + } break; case 3: if (vec->type()->Is()) { @@ -182,6 +190,10 @@ bool IntrinsicDataTypeFor(const sem::Type* ty, DecomposeMemoryAccess::Intrinsic: out = DecomposeMemoryAccess::Intrinsic::DataType::kVec3F32; return true; } + if (vec->type()->Is()) { + out = DecomposeMemoryAccess::Intrinsic::DataType::kVec3F16; + return true; + } break; case 4: if (vec->type()->Is()) { @@ -196,6 +208,10 @@ bool IntrinsicDataTypeFor(const sem::Type* ty, DecomposeMemoryAccess::Intrinsic: out = DecomposeMemoryAccess::Intrinsic::DataType::kVec4F32; return true; } + if (vec->type()->Is()) { + out = DecomposeMemoryAccess::Intrinsic::DataType::kVec4F16; + return true; + } break; } return false; @@ -776,6 +792,9 @@ std::string DecomposeMemoryAccess::Intrinsic::InternalName() const { case DataType::kI32: ss << "i32"; break; + case DataType::kF16: + ss << "f16"; + break; case DataType::kVec2U32: ss << "vec2_u32"; break; @@ -785,6 +804,9 @@ std::string DecomposeMemoryAccess::Intrinsic::InternalName() const { case DataType::kVec2I32: ss << "vec2_i32"; break; + case DataType::kVec2F16: + ss << "vec2_f16"; + break; case DataType::kVec3U32: ss << "vec3_u32"; break; @@ -794,6 +816,9 @@ std::string DecomposeMemoryAccess::Intrinsic::InternalName() const { case DataType::kVec3I32: ss << "vec3_i32"; break; + case DataType::kVec3F16: + ss << "vec3_f16"; + break; case DataType::kVec4U32: ss << "vec4_u32"; break; @@ -803,6 +828,9 @@ std::string DecomposeMemoryAccess::Intrinsic::InternalName() const { case DataType::kVec4I32: ss << "vec4_i32"; break; + case DataType::kVec4F16: + ss << "vec4_f16"; + break; } return ss.str(); } diff --git a/src/tint/transform/decompose_memory_access.h b/src/tint/transform/decompose_memory_access.h index 21c196b864..3c620e07a4 100644 --- a/src/tint/transform/decompose_memory_access.h +++ b/src/tint/transform/decompose_memory_access.h @@ -60,15 +60,19 @@ class DecomposeMemoryAccess final : public Castable, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_vec3_f16 : array, 2>, }; @group(0) @binding(0) var sb : SB; @compute @workgroup_size(1) fn main() { - var a : i32 = sb.a; - var b : u32 = sb.b; - var c : f32 = sb.c; - var d : vec2 = sb.d; - var e : vec2 = sb.e; - var f : vec2 = sb.f; - var g : vec3 = sb.g; - var h : vec3 = sb.h; - var i : vec3 = sb.i; - var j : vec4 = sb.j; - var k : vec4 = sb.k; - var l : vec4 = sb.l; - var m : mat2x2 = sb.m; - var n : mat2x3 = sb.n; - var o : mat2x4 = sb.o; - var p : mat3x2 = sb.p; - var q : mat3x3 = sb.q; - var r : mat3x4 = sb.r; - var s : mat4x2 = sb.s; - var t : mat4x3 = sb.t; - var u : mat4x4 = sb.u; - var v : array, 2> = sb.v; + var scalar_f32 : f32 = sb.scalar_f32; + var scalar_i32 : i32 = sb.scalar_i32; + var scalar_u32 : u32 = sb.scalar_u32; + var scalar_f16 : f16 = sb.scalar_f16; + var vec2_f32 : vec2 = sb.vec2_f32; + var vec2_i32 : vec2 = sb.vec2_i32; + var vec2_u32 : vec2 = sb.vec2_u32; + var vec2_f16 : vec2 = sb.vec2_f16; + var vec3_f32 : vec3 = sb.vec3_f32; + var vec3_i32 : vec3 = sb.vec3_i32; + var vec3_u32 : vec3 = sb.vec3_u32; + var vec3_f16 : vec3 = sb.vec3_f16; + var vec4_f32 : vec4 = sb.vec4_f32; + var vec4_i32 : vec4 = sb.vec4_i32; + var vec4_u32 : vec4 = sb.vec4_u32; + var vec4_f16 : vec4 = sb.vec4_f16; + var mat2x2_f32 : mat2x2 = sb.mat2x2_f32; + var mat2x3_f32 : mat2x3 = sb.mat2x3_f32; + var mat2x4_f32 : mat2x4 = sb.mat2x4_f32; + var mat3x2_f32 : mat3x2 = sb.mat3x2_f32; + var mat3x3_f32 : mat3x3 = sb.mat3x3_f32; + var mat3x4_f32 : mat3x4 = sb.mat3x4_f32; + var mat4x2_f32 : mat4x2 = sb.mat4x2_f32; + var mat4x3_f32 : mat4x3 = sb.mat4x3_f32; + var mat4x4_f32 : mat4x4 = sb.mat4x4_f32; + var mat2x2_f16 : mat2x2 = sb.mat2x2_f16; + var mat2x3_f16 : mat2x3 = sb.mat2x3_f16; + var mat2x4_f16 : mat2x4 = sb.mat2x4_f16; + var mat3x2_f16 : mat3x2 = sb.mat3x2_f16; + var mat3x3_f16 : mat3x3 = sb.mat3x3_f16; + var mat3x4_f16 : mat3x4 = sb.mat3x4_f16; + var mat4x2_f16 : mat4x2 = sb.mat4x2_f16; + var mat4x3_f16 : mat4x3 = sb.mat4x3_f16; + var mat4x4_f16 : mat4x4 = sb.mat4x4_f16; + var arr2_vec3_f32 : array, 2> = sb.arr2_vec3_f32; + var arr2_vec3_f16 : array, 2> = sb.arr2_vec3_f16; } )"; auto* expect = R"( +enable f16; + struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_vec3_f16 : array, 2>, } @group(0) @binding(0) var sb : SB; +@internal(intrinsic_load_storage_f32) @internal(disable_validation__function_has_no_body) +fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 + @internal(intrinsic_load_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 @internal(intrinsic_load_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 -@internal(intrinsic_load_storage_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 - -@internal(intrinsic_load_storage_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 - -@internal(intrinsic_load_storage_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_storage_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 @internal(intrinsic_load_storage_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_storage_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_storage_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_storage_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_storage_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 + +@internal(intrinsic_load_storage_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_storage_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_storage_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_storage_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_storage_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_storage_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 + +@internal(intrinsic_load_storage_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_storage_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { - return mat2x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u))); +@internal(intrinsic_load_storage_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_storage_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_storage_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u))); } -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { - return mat2x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u))); +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u))); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { - return mat3x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u))); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u))); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u))); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { - return mat3x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u))); +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u))); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { - return mat4x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u))); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u)), tint_symbol_4(buffer, (offset + 24u))); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u))); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { - return mat4x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)), tint_symbol_11(buffer, (offset + 48u))); +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u)), tint_symbol_12(buffer, (offset + 48u))); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u))); +} + +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { + return mat2x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u))); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u))); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u))); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { + return mat3x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u))); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u))); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u)), tint_symbol_7(buffer, (offset + 12u))); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { + return mat4x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 24u))); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u)), tint_symbol_15(buffer, (offset + 24u))); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr : array, 2u>; - for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - arr[i_1] = tint_symbol_8(buffer, (offset + (i_1 * 16u))); + for(var i = 0u; (i < 2u); i = (i + 1u)) { + arr[i] = tint_symbol_8(buffer, (offset + (i * 16u))); } return arr; } +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { + var arr_1 : array, 2u>; + for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { + arr_1[i_1] = tint_symbol_11(buffer, (offset + (i_1 * 8u))); + } + return arr_1; +} + @compute @workgroup_size(1) fn main() { - var a : i32 = tint_symbol(&(sb), 0u); - var b : u32 = tint_symbol_1(&(sb), 4u); - var c : f32 = tint_symbol_2(&(sb), 8u); - var d : vec2 = tint_symbol_3(&(sb), 16u); - var e : vec2 = tint_symbol_4(&(sb), 24u); - var f : vec2 = tint_symbol_5(&(sb), 32u); - var g : vec3 = tint_symbol_6(&(sb), 48u); - var h : vec3 = tint_symbol_7(&(sb), 64u); - var i : vec3 = tint_symbol_8(&(sb), 80u); - var j : vec4 = tint_symbol_9(&(sb), 96u); - var k : vec4 = tint_symbol_10(&(sb), 112u); - var l : vec4 = tint_symbol_11(&(sb), 128u); - var m : mat2x2 = tint_symbol_12(&(sb), 144u); - var n : mat2x3 = tint_symbol_13(&(sb), 160u); - var o : mat2x4 = tint_symbol_14(&(sb), 192u); - var p : mat3x2 = tint_symbol_15(&(sb), 224u); - var q : mat3x3 = tint_symbol_16(&(sb), 256u); - var r : mat3x4 = tint_symbol_17(&(sb), 304u); - var s : mat4x2 = tint_symbol_18(&(sb), 352u); - var t : mat4x3 = tint_symbol_19(&(sb), 384u); - var u : mat4x4 = tint_symbol_20(&(sb), 448u); - var v : array, 2> = tint_symbol_21(&(sb), 512u); + var scalar_f32 : f32 = tint_symbol(&(sb), 0u); + var scalar_i32 : i32 = tint_symbol_1(&(sb), 4u); + var scalar_u32 : u32 = tint_symbol_2(&(sb), 8u); + var scalar_f16 : f16 = tint_symbol_3(&(sb), 12u); + var vec2_f32 : vec2 = tint_symbol_4(&(sb), 16u); + var vec2_i32 : vec2 = tint_symbol_5(&(sb), 24u); + var vec2_u32 : vec2 = tint_symbol_6(&(sb), 32u); + var vec2_f16 : vec2 = tint_symbol_7(&(sb), 40u); + var vec3_f32 : vec3 = tint_symbol_8(&(sb), 48u); + var vec3_i32 : vec3 = tint_symbol_9(&(sb), 64u); + var vec3_u32 : vec3 = tint_symbol_10(&(sb), 80u); + var vec3_f16 : vec3 = tint_symbol_11(&(sb), 96u); + var vec4_f32 : vec4 = tint_symbol_12(&(sb), 112u); + var vec4_i32 : vec4 = tint_symbol_13(&(sb), 128u); + var vec4_u32 : vec4 = tint_symbol_14(&(sb), 144u); + var vec4_f16 : vec4 = tint_symbol_15(&(sb), 160u); + var mat2x2_f32 : mat2x2 = tint_symbol_16(&(sb), 168u); + var mat2x3_f32 : mat2x3 = tint_symbol_17(&(sb), 192u); + var mat2x4_f32 : mat2x4 = tint_symbol_18(&(sb), 224u); + var mat3x2_f32 : mat3x2 = tint_symbol_19(&(sb), 256u); + var mat3x3_f32 : mat3x3 = tint_symbol_20(&(sb), 288u); + var mat3x4_f32 : mat3x4 = tint_symbol_21(&(sb), 336u); + var mat4x2_f32 : mat4x2 = tint_symbol_22(&(sb), 384u); + var mat4x3_f32 : mat4x3 = tint_symbol_23(&(sb), 416u); + var mat4x4_f32 : mat4x4 = tint_symbol_24(&(sb), 480u); + var mat2x2_f16 : mat2x2 = tint_symbol_25(&(sb), 544u); + var mat2x3_f16 : mat2x3 = tint_symbol_26(&(sb), 552u); + var mat2x4_f16 : mat2x4 = tint_symbol_27(&(sb), 568u); + var mat3x2_f16 : mat3x2 = tint_symbol_28(&(sb), 584u); + var mat3x3_f16 : mat3x3 = tint_symbol_29(&(sb), 600u); + var mat3x4_f16 : mat3x4 = tint_symbol_30(&(sb), 624u); + var mat4x2_f16 : mat4x2 = tint_symbol_31(&(sb), 648u); + var mat4x3_f16 : mat4x3 = tint_symbol_32(&(sb), 664u); + var mat4x4_f16 : mat4x4 = tint_symbol_33(&(sb), 696u); + var arr2_vec3_f32 : array, 2> = tint_symbol_34(&(sb), 736u); + var arr2_vec3_f16 : array, 2> = tint_symbol_35(&(sb), 768u); } )"; @@ -247,192 +363,308 @@ fn main() { TEST_F(DecomposeMemoryAccessTest, SB_BasicLoad_OutOfOrder) { auto* src = R"( +enable f16; + @compute @workgroup_size(1) fn main() { - var a : i32 = sb.a; - var b : u32 = sb.b; - var c : f32 = sb.c; - var d : vec2 = sb.d; - var e : vec2 = sb.e; - var f : vec2 = sb.f; - var g : vec3 = sb.g; - var h : vec3 = sb.h; - var i : vec3 = sb.i; - var j : vec4 = sb.j; - var k : vec4 = sb.k; - var l : vec4 = sb.l; - var m : mat2x2 = sb.m; - var n : mat2x3 = sb.n; - var o : mat2x4 = sb.o; - var p : mat3x2 = sb.p; - var q : mat3x3 = sb.q; - var r : mat3x4 = sb.r; - var s : mat4x2 = sb.s; - var t : mat4x3 = sb.t; - var u : mat4x4 = sb.u; - var v : array, 2> = sb.v; + var scalar_f32 : f32 = sb.scalar_f32; + var scalar_i32 : i32 = sb.scalar_i32; + var scalar_u32 : u32 = sb.scalar_u32; + var scalar_f16 : f16 = sb.scalar_f16; + var vec2_f32 : vec2 = sb.vec2_f32; + var vec2_i32 : vec2 = sb.vec2_i32; + var vec2_u32 : vec2 = sb.vec2_u32; + var vec2_f16 : vec2 = sb.vec2_f16; + var vec3_f32 : vec3 = sb.vec3_f32; + var vec3_i32 : vec3 = sb.vec3_i32; + var vec3_u32 : vec3 = sb.vec3_u32; + var vec3_f16 : vec3 = sb.vec3_f16; + var vec4_f32 : vec4 = sb.vec4_f32; + var vec4_i32 : vec4 = sb.vec4_i32; + var vec4_u32 : vec4 = sb.vec4_u32; + var vec4_f16 : vec4 = sb.vec4_f16; + var mat2x2_f32 : mat2x2 = sb.mat2x2_f32; + var mat2x3_f32 : mat2x3 = sb.mat2x3_f32; + var mat2x4_f32 : mat2x4 = sb.mat2x4_f32; + var mat3x2_f32 : mat3x2 = sb.mat3x2_f32; + var mat3x3_f32 : mat3x3 = sb.mat3x3_f32; + var mat3x4_f32 : mat3x4 = sb.mat3x4_f32; + var mat4x2_f32 : mat4x2 = sb.mat4x2_f32; + var mat4x3_f32 : mat4x3 = sb.mat4x3_f32; + var mat4x4_f32 : mat4x4 = sb.mat4x4_f32; + var mat2x2_f16 : mat2x2 = sb.mat2x2_f16; + var mat2x3_f16 : mat2x3 = sb.mat2x3_f16; + var mat2x4_f16 : mat2x4 = sb.mat2x4_f16; + var mat3x2_f16 : mat3x2 = sb.mat3x2_f16; + var mat3x3_f16 : mat3x3 = sb.mat3x3_f16; + var mat3x4_f16 : mat3x4 = sb.mat3x4_f16; + var mat4x2_f16 : mat4x2 = sb.mat4x2_f16; + var mat4x3_f16 : mat4x3 = sb.mat4x3_f16; + var mat4x4_f16 : mat4x4 = sb.mat4x4_f16; + var arr2_vec3_f32 : array, 2> = sb.arr2_vec3_f32; + var arr2_vec3_f16 : array, 2> = sb.arr2_vec3_f16; } @group(0) @binding(0) var sb : SB; struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_vec3_f16 : array, 2>, }; )"; auto* expect = R"( -@internal(intrinsic_load_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 - -@internal(intrinsic_load_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 +enable f16; @internal(intrinsic_load_storage_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 +fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 -@internal(intrinsic_load_storage_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_storage_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 -@internal(intrinsic_load_storage_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_storage_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 + +@internal(intrinsic_load_storage_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 @internal(intrinsic_load_storage_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_storage_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_storage_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_storage_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_storage_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 + +@internal(intrinsic_load_storage_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_storage_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_storage_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_storage_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_storage_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_storage_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 + +@internal(intrinsic_load_storage_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_storage_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { - return mat2x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u))); +@internal(intrinsic_load_storage_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_storage_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_storage_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u))); } -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { - return mat2x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u))); +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u))); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { - return mat3x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u))); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u))); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u))); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { - return mat3x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u))); +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u))); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { - return mat4x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u))); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u)), tint_symbol_4(buffer, (offset + 24u))); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u))); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { - return mat4x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)), tint_symbol_11(buffer, (offset + 48u))); +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u)), tint_symbol_12(buffer, (offset + 48u))); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u))); +} + +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { + return mat2x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u))); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u))); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u))); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { + return mat3x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u))); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u))); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u)), tint_symbol_7(buffer, (offset + 12u))); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { + return mat4x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 24u))); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u)), tint_symbol_15(buffer, (offset + 24u))); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr : array, 2u>; - for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - arr[i_1] = tint_symbol_8(buffer, (offset + (i_1 * 16u))); + for(var i = 0u; (i < 2u); i = (i + 1u)) { + arr[i] = tint_symbol_8(buffer, (offset + (i * 16u))); } return arr; } +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { + var arr_1 : array, 2u>; + for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { + arr_1[i_1] = tint_symbol_11(buffer, (offset + (i_1 * 8u))); + } + return arr_1; +} + @compute @workgroup_size(1) fn main() { - var a : i32 = tint_symbol(&(sb), 0u); - var b : u32 = tint_symbol_1(&(sb), 4u); - var c : f32 = tint_symbol_2(&(sb), 8u); - var d : vec2 = tint_symbol_3(&(sb), 16u); - var e : vec2 = tint_symbol_4(&(sb), 24u); - var f : vec2 = tint_symbol_5(&(sb), 32u); - var g : vec3 = tint_symbol_6(&(sb), 48u); - var h : vec3 = tint_symbol_7(&(sb), 64u); - var i : vec3 = tint_symbol_8(&(sb), 80u); - var j : vec4 = tint_symbol_9(&(sb), 96u); - var k : vec4 = tint_symbol_10(&(sb), 112u); - var l : vec4 = tint_symbol_11(&(sb), 128u); - var m : mat2x2 = tint_symbol_12(&(sb), 144u); - var n : mat2x3 = tint_symbol_13(&(sb), 160u); - var o : mat2x4 = tint_symbol_14(&(sb), 192u); - var p : mat3x2 = tint_symbol_15(&(sb), 224u); - var q : mat3x3 = tint_symbol_16(&(sb), 256u); - var r : mat3x4 = tint_symbol_17(&(sb), 304u); - var s : mat4x2 = tint_symbol_18(&(sb), 352u); - var t : mat4x3 = tint_symbol_19(&(sb), 384u); - var u : mat4x4 = tint_symbol_20(&(sb), 448u); - var v : array, 2> = tint_symbol_21(&(sb), 512u); + var scalar_f32 : f32 = tint_symbol(&(sb), 0u); + var scalar_i32 : i32 = tint_symbol_1(&(sb), 4u); + var scalar_u32 : u32 = tint_symbol_2(&(sb), 8u); + var scalar_f16 : f16 = tint_symbol_3(&(sb), 12u); + var vec2_f32 : vec2 = tint_symbol_4(&(sb), 16u); + var vec2_i32 : vec2 = tint_symbol_5(&(sb), 24u); + var vec2_u32 : vec2 = tint_symbol_6(&(sb), 32u); + var vec2_f16 : vec2 = tint_symbol_7(&(sb), 40u); + var vec3_f32 : vec3 = tint_symbol_8(&(sb), 48u); + var vec3_i32 : vec3 = tint_symbol_9(&(sb), 64u); + var vec3_u32 : vec3 = tint_symbol_10(&(sb), 80u); + var vec3_f16 : vec3 = tint_symbol_11(&(sb), 96u); + var vec4_f32 : vec4 = tint_symbol_12(&(sb), 112u); + var vec4_i32 : vec4 = tint_symbol_13(&(sb), 128u); + var vec4_u32 : vec4 = tint_symbol_14(&(sb), 144u); + var vec4_f16 : vec4 = tint_symbol_15(&(sb), 160u); + var mat2x2_f32 : mat2x2 = tint_symbol_16(&(sb), 168u); + var mat2x3_f32 : mat2x3 = tint_symbol_17(&(sb), 192u); + var mat2x4_f32 : mat2x4 = tint_symbol_18(&(sb), 224u); + var mat3x2_f32 : mat3x2 = tint_symbol_19(&(sb), 256u); + var mat3x3_f32 : mat3x3 = tint_symbol_20(&(sb), 288u); + var mat3x4_f32 : mat3x4 = tint_symbol_21(&(sb), 336u); + var mat4x2_f32 : mat4x2 = tint_symbol_22(&(sb), 384u); + var mat4x3_f32 : mat4x3 = tint_symbol_23(&(sb), 416u); + var mat4x4_f32 : mat4x4 = tint_symbol_24(&(sb), 480u); + var mat2x2_f16 : mat2x2 = tint_symbol_25(&(sb), 544u); + var mat2x3_f16 : mat2x3 = tint_symbol_26(&(sb), 552u); + var mat2x4_f16 : mat2x4 = tint_symbol_27(&(sb), 568u); + var mat3x2_f16 : mat3x2 = tint_symbol_28(&(sb), 584u); + var mat3x3_f16 : mat3x3 = tint_symbol_29(&(sb), 600u); + var mat3x4_f16 : mat3x4 = tint_symbol_30(&(sb), 624u); + var mat4x2_f16 : mat4x2 = tint_symbol_31(&(sb), 648u); + var mat4x3_f16 : mat4x3 = tint_symbol_32(&(sb), 664u); + var mat4x4_f16 : mat4x4 = tint_symbol_33(&(sb), 696u); + var arr2_vec3_f32 : array, 2> = tint_symbol_34(&(sb), 736u); + var arr2_vec3_f16 : array, 2> = tint_symbol_35(&(sb), 768u); } @group(0) @binding(0) var sb : SB; struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_vec3_f16 : array, 2>, } )"; @@ -443,192 +675,308 @@ struct SB { TEST_F(DecomposeMemoryAccessTest, UB_BasicLoad) { auto* src = R"( +enable f16; + struct UB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, }; @group(0) @binding(0) var ub : UB; @compute @workgroup_size(1) fn main() { - var a : i32 = ub.a; - var b : u32 = ub.b; - var c : f32 = ub.c; - var d : vec2 = ub.d; - var e : vec2 = ub.e; - var f : vec2 = ub.f; - var g : vec3 = ub.g; - var h : vec3 = ub.h; - var i : vec3 = ub.i; - var j : vec4 = ub.j; - var k : vec4 = ub.k; - var l : vec4 = ub.l; - var m : mat2x2 = ub.m; - var n : mat2x3 = ub.n; - var o : mat2x4 = ub.o; - var p : mat3x2 = ub.p; - var q : mat3x3 = ub.q; - var r : mat3x4 = ub.r; - var s : mat4x2 = ub.s; - var t : mat4x3 = ub.t; - var u : mat4x4 = ub.u; - var v : array, 2> = ub.v; + var scalar_f32 : f32 = ub.scalar_f32; + var scalar_i32 : i32 = ub.scalar_i32; + var scalar_u32 : u32 = ub.scalar_u32; + var scalar_f16 : f16 = ub.scalar_f16; + var vec2_f32 : vec2 = ub.vec2_f32; + var vec2_i32 : vec2 = ub.vec2_i32; + var vec2_u32 : vec2 = ub.vec2_u32; + var vec2_f16 : vec2 = ub.vec2_f16; + var vec3_f32 : vec3 = ub.vec3_f32; + var vec3_i32 : vec3 = ub.vec3_i32; + var vec3_u32 : vec3 = ub.vec3_u32; + var vec3_f16 : vec3 = ub.vec3_f16; + var vec4_f32 : vec4 = ub.vec4_f32; + var vec4_i32 : vec4 = ub.vec4_i32; + var vec4_u32 : vec4 = ub.vec4_u32; + var vec4_f16 : vec4 = ub.vec4_f16; + var mat2x2_f32 : mat2x2 = ub.mat2x2_f32; + var mat2x3_f32 : mat2x3 = ub.mat2x3_f32; + var mat2x4_f32 : mat2x4 = ub.mat2x4_f32; + var mat3x2_f32 : mat3x2 = ub.mat3x2_f32; + var mat3x3_f32 : mat3x3 = ub.mat3x3_f32; + var mat3x4_f32 : mat3x4 = ub.mat3x4_f32; + var mat4x2_f32 : mat4x2 = ub.mat4x2_f32; + var mat4x3_f32 : mat4x3 = ub.mat4x3_f32; + var mat4x4_f32 : mat4x4 = ub.mat4x4_f32; + var mat2x2_f16 : mat2x2 = ub.mat2x2_f16; + var mat2x3_f16 : mat2x3 = ub.mat2x3_f16; + var mat2x4_f16 : mat2x4 = ub.mat2x4_f16; + var mat3x2_f16 : mat3x2 = ub.mat3x2_f16; + var mat3x3_f16 : mat3x3 = ub.mat3x3_f16; + var mat3x4_f16 : mat3x4 = ub.mat3x4_f16; + var mat4x2_f16 : mat4x2 = ub.mat4x2_f16; + var mat4x3_f16 : mat4x3 = ub.mat4x3_f16; + var mat4x4_f16 : mat4x4 = ub.mat4x4_f16; + var arr2_vec3_f32 : array, 2> = ub.arr2_vec3_f32; + var arr2_mat4x2_f16 : array, 2> = ub.arr2_mat4x2_f16; } )"; auto* expect = R"( +enable f16; + struct UB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, } @group(0) @binding(0) var ub : UB; +@internal(intrinsic_load_uniform_f32) @internal(disable_validation__function_has_no_body) +fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 + @internal(intrinsic_load_uniform_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 @internal(intrinsic_load_uniform_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 -@internal(intrinsic_load_uniform_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 - -@internal(intrinsic_load_uniform_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 - -@internal(intrinsic_load_uniform_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_uniform_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 @internal(intrinsic_load_uniform_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_uniform_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_uniform_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_uniform_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_uniform_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 + +@internal(intrinsic_load_uniform_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_uniform_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_uniform_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_uniform_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_uniform_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 + +@internal(intrinsic_load_uniform_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { - return mat2x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u))); +@internal(intrinsic_load_uniform_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_uniform_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_uniform_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u))); } -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { - return mat2x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u))); +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u))); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { - return mat3x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u))); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u))); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u))); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { - return mat3x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u))); +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u))); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { - return mat4x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u))); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u)), tint_symbol_4(buffer, (offset + 24u))); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u))); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { - return mat4x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)), tint_symbol_11(buffer, (offset + 48u))); +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u)), tint_symbol_12(buffer, (offset + 48u))); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u))); +} + +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { + return mat2x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u))); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u))); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u))); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { + return mat3x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u))); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u))); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u)), tint_symbol_7(buffer, (offset + 12u))); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { + return mat4x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 24u))); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u)), tint_symbol_15(buffer, (offset + 24u))); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr : array, 2u>; - for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - arr[i_1] = tint_symbol_8(buffer, (offset + (i_1 * 16u))); + for(var i = 0u; (i < 2u); i = (i + 1u)) { + arr[i] = tint_symbol_8(buffer, (offset + (i * 16u))); } return arr; } +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { + var arr_1 : array, 2u>; + for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { + arr_1[i_1] = tint_symbol_31(buffer, (offset + (i_1 * 16u))); + } + return arr_1; +} + @compute @workgroup_size(1) fn main() { - var a : i32 = tint_symbol(&(ub), 0u); - var b : u32 = tint_symbol_1(&(ub), 4u); - var c : f32 = tint_symbol_2(&(ub), 8u); - var d : vec2 = tint_symbol_3(&(ub), 16u); - var e : vec2 = tint_symbol_4(&(ub), 24u); - var f : vec2 = tint_symbol_5(&(ub), 32u); - var g : vec3 = tint_symbol_6(&(ub), 48u); - var h : vec3 = tint_symbol_7(&(ub), 64u); - var i : vec3 = tint_symbol_8(&(ub), 80u); - var j : vec4 = tint_symbol_9(&(ub), 96u); - var k : vec4 = tint_symbol_10(&(ub), 112u); - var l : vec4 = tint_symbol_11(&(ub), 128u); - var m : mat2x2 = tint_symbol_12(&(ub), 144u); - var n : mat2x3 = tint_symbol_13(&(ub), 160u); - var o : mat2x4 = tint_symbol_14(&(ub), 192u); - var p : mat3x2 = tint_symbol_15(&(ub), 224u); - var q : mat3x3 = tint_symbol_16(&(ub), 256u); - var r : mat3x4 = tint_symbol_17(&(ub), 304u); - var s : mat4x2 = tint_symbol_18(&(ub), 352u); - var t : mat4x3 = tint_symbol_19(&(ub), 384u); - var u : mat4x4 = tint_symbol_20(&(ub), 448u); - var v : array, 2> = tint_symbol_21(&(ub), 512u); + var scalar_f32 : f32 = tint_symbol(&(ub), 0u); + var scalar_i32 : i32 = tint_symbol_1(&(ub), 4u); + var scalar_u32 : u32 = tint_symbol_2(&(ub), 8u); + var scalar_f16 : f16 = tint_symbol_3(&(ub), 12u); + var vec2_f32 : vec2 = tint_symbol_4(&(ub), 16u); + var vec2_i32 : vec2 = tint_symbol_5(&(ub), 24u); + var vec2_u32 : vec2 = tint_symbol_6(&(ub), 32u); + var vec2_f16 : vec2 = tint_symbol_7(&(ub), 40u); + var vec3_f32 : vec3 = tint_symbol_8(&(ub), 48u); + var vec3_i32 : vec3 = tint_symbol_9(&(ub), 64u); + var vec3_u32 : vec3 = tint_symbol_10(&(ub), 80u); + var vec3_f16 : vec3 = tint_symbol_11(&(ub), 96u); + var vec4_f32 : vec4 = tint_symbol_12(&(ub), 112u); + var vec4_i32 : vec4 = tint_symbol_13(&(ub), 128u); + var vec4_u32 : vec4 = tint_symbol_14(&(ub), 144u); + var vec4_f16 : vec4 = tint_symbol_15(&(ub), 160u); + var mat2x2_f32 : mat2x2 = tint_symbol_16(&(ub), 168u); + var mat2x3_f32 : mat2x3 = tint_symbol_17(&(ub), 192u); + var mat2x4_f32 : mat2x4 = tint_symbol_18(&(ub), 224u); + var mat3x2_f32 : mat3x2 = tint_symbol_19(&(ub), 256u); + var mat3x3_f32 : mat3x3 = tint_symbol_20(&(ub), 288u); + var mat3x4_f32 : mat3x4 = tint_symbol_21(&(ub), 336u); + var mat4x2_f32 : mat4x2 = tint_symbol_22(&(ub), 384u); + var mat4x3_f32 : mat4x3 = tint_symbol_23(&(ub), 416u); + var mat4x4_f32 : mat4x4 = tint_symbol_24(&(ub), 480u); + var mat2x2_f16 : mat2x2 = tint_symbol_25(&(ub), 544u); + var mat2x3_f16 : mat2x3 = tint_symbol_26(&(ub), 552u); + var mat2x4_f16 : mat2x4 = tint_symbol_27(&(ub), 568u); + var mat3x2_f16 : mat3x2 = tint_symbol_28(&(ub), 584u); + var mat3x3_f16 : mat3x3 = tint_symbol_29(&(ub), 600u); + var mat3x4_f16 : mat3x4 = tint_symbol_30(&(ub), 624u); + var mat4x2_f16 : mat4x2 = tint_symbol_31(&(ub), 648u); + var mat4x3_f16 : mat4x3 = tint_symbol_32(&(ub), 664u); + var mat4x4_f16 : mat4x4 = tint_symbol_33(&(ub), 696u); + var arr2_vec3_f32 : array, 2> = tint_symbol_34(&(ub), 736u); + var arr2_mat4x2_f16 : array, 2> = tint_symbol_35(&(ub), 768u); } )"; @@ -639,192 +987,308 @@ fn main() { TEST_F(DecomposeMemoryAccessTest, UB_BasicLoad_OutOfOrder) { auto* src = R"( +enable f16; + @compute @workgroup_size(1) fn main() { - var a : i32 = ub.a; - var b : u32 = ub.b; - var c : f32 = ub.c; - var d : vec2 = ub.d; - var e : vec2 = ub.e; - var f : vec2 = ub.f; - var g : vec3 = ub.g; - var h : vec3 = ub.h; - var i : vec3 = ub.i; - var j : vec4 = ub.j; - var k : vec4 = ub.k; - var l : vec4 = ub.l; - var m : mat2x2 = ub.m; - var n : mat2x3 = ub.n; - var o : mat2x4 = ub.o; - var p : mat3x2 = ub.p; - var q : mat3x3 = ub.q; - var r : mat3x4 = ub.r; - var s : mat4x2 = ub.s; - var t : mat4x3 = ub.t; - var u : mat4x4 = ub.u; - var v : array, 2> = ub.v; + var scalar_f32 : f32 = ub.scalar_f32; + var scalar_i32 : i32 = ub.scalar_i32; + var scalar_u32 : u32 = ub.scalar_u32; + var scalar_f16 : f16 = ub.scalar_f16; + var vec2_f32 : vec2 = ub.vec2_f32; + var vec2_i32 : vec2 = ub.vec2_i32; + var vec2_u32 : vec2 = ub.vec2_u32; + var vec2_f16 : vec2 = ub.vec2_f16; + var vec3_f32 : vec3 = ub.vec3_f32; + var vec3_i32 : vec3 = ub.vec3_i32; + var vec3_u32 : vec3 = ub.vec3_u32; + var vec3_f16 : vec3 = ub.vec3_f16; + var vec4_f32 : vec4 = ub.vec4_f32; + var vec4_i32 : vec4 = ub.vec4_i32; + var vec4_u32 : vec4 = ub.vec4_u32; + var vec4_f16 : vec4 = ub.vec4_f16; + var mat2x2_f32 : mat2x2 = ub.mat2x2_f32; + var mat2x3_f32 : mat2x3 = ub.mat2x3_f32; + var mat2x4_f32 : mat2x4 = ub.mat2x4_f32; + var mat3x2_f32 : mat3x2 = ub.mat3x2_f32; + var mat3x3_f32 : mat3x3 = ub.mat3x3_f32; + var mat3x4_f32 : mat3x4 = ub.mat3x4_f32; + var mat4x2_f32 : mat4x2 = ub.mat4x2_f32; + var mat4x3_f32 : mat4x3 = ub.mat4x3_f32; + var mat4x4_f32 : mat4x4 = ub.mat4x4_f32; + var mat2x2_f16 : mat2x2 = ub.mat2x2_f16; + var mat2x3_f16 : mat2x3 = ub.mat2x3_f16; + var mat2x4_f16 : mat2x4 = ub.mat2x4_f16; + var mat3x2_f16 : mat3x2 = ub.mat3x2_f16; + var mat3x3_f16 : mat3x3 = ub.mat3x3_f16; + var mat3x4_f16 : mat3x4 = ub.mat3x4_f16; + var mat4x2_f16 : mat4x2 = ub.mat4x2_f16; + var mat4x3_f16 : mat4x3 = ub.mat4x3_f16; + var mat4x4_f16 : mat4x4 = ub.mat4x4_f16; + var arr2_vec3_f32 : array, 2> = ub.arr2_vec3_f32; + var arr2_mat4x2_f16 : array, 2> = ub.arr2_mat4x2_f16; } @group(0) @binding(0) var ub : UB; struct UB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, }; )"; auto* expect = R"( -@internal(intrinsic_load_uniform_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 - -@internal(intrinsic_load_uniform_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 +enable f16; @internal(intrinsic_load_uniform_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 +fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 -@internal(intrinsic_load_uniform_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_uniform_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 -@internal(intrinsic_load_uniform_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_uniform_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 + +@internal(intrinsic_load_uniform_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 @internal(intrinsic_load_uniform_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_uniform_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_uniform_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_uniform_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_uniform_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 + +@internal(intrinsic_load_uniform_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_uniform_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_uniform_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_uniform_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_uniform_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 + +@internal(intrinsic_load_uniform_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { - return mat2x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u))); +@internal(intrinsic_load_uniform_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_uniform_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_uniform_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u))); } -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { - return mat2x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u))); +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u))); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { - return mat3x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u))); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u))); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u))); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { - return mat3x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u))); +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u))); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { - return mat4x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u))); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u)), tint_symbol_4(buffer, (offset + 24u))); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u))); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { - return mat4x4(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)), tint_symbol_11(buffer, (offset + 48u))); +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u)), tint_symbol_12(buffer, (offset + 48u))); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u))); +} + +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { + return mat2x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u))); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u))); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u))); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { + return mat3x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u))); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u))); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u)), tint_symbol_7(buffer, (offset + 12u))); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { + return mat4x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 24u))); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u)), tint_symbol_15(buffer, (offset + 24u))); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr : array, 2u>; - for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - arr[i_1] = tint_symbol_8(buffer, (offset + (i_1 * 16u))); + for(var i = 0u; (i < 2u); i = (i + 1u)) { + arr[i] = tint_symbol_8(buffer, (offset + (i * 16u))); } return arr; } +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { + var arr_1 : array, 2u>; + for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { + arr_1[i_1] = tint_symbol_31(buffer, (offset + (i_1 * 16u))); + } + return arr_1; +} + @compute @workgroup_size(1) fn main() { - var a : i32 = tint_symbol(&(ub), 0u); - var b : u32 = tint_symbol_1(&(ub), 4u); - var c : f32 = tint_symbol_2(&(ub), 8u); - var d : vec2 = tint_symbol_3(&(ub), 16u); - var e : vec2 = tint_symbol_4(&(ub), 24u); - var f : vec2 = tint_symbol_5(&(ub), 32u); - var g : vec3 = tint_symbol_6(&(ub), 48u); - var h : vec3 = tint_symbol_7(&(ub), 64u); - var i : vec3 = tint_symbol_8(&(ub), 80u); - var j : vec4 = tint_symbol_9(&(ub), 96u); - var k : vec4 = tint_symbol_10(&(ub), 112u); - var l : vec4 = tint_symbol_11(&(ub), 128u); - var m : mat2x2 = tint_symbol_12(&(ub), 144u); - var n : mat2x3 = tint_symbol_13(&(ub), 160u); - var o : mat2x4 = tint_symbol_14(&(ub), 192u); - var p : mat3x2 = tint_symbol_15(&(ub), 224u); - var q : mat3x3 = tint_symbol_16(&(ub), 256u); - var r : mat3x4 = tint_symbol_17(&(ub), 304u); - var s : mat4x2 = tint_symbol_18(&(ub), 352u); - var t : mat4x3 = tint_symbol_19(&(ub), 384u); - var u : mat4x4 = tint_symbol_20(&(ub), 448u); - var v : array, 2> = tint_symbol_21(&(ub), 512u); + var scalar_f32 : f32 = tint_symbol(&(ub), 0u); + var scalar_i32 : i32 = tint_symbol_1(&(ub), 4u); + var scalar_u32 : u32 = tint_symbol_2(&(ub), 8u); + var scalar_f16 : f16 = tint_symbol_3(&(ub), 12u); + var vec2_f32 : vec2 = tint_symbol_4(&(ub), 16u); + var vec2_i32 : vec2 = tint_symbol_5(&(ub), 24u); + var vec2_u32 : vec2 = tint_symbol_6(&(ub), 32u); + var vec2_f16 : vec2 = tint_symbol_7(&(ub), 40u); + var vec3_f32 : vec3 = tint_symbol_8(&(ub), 48u); + var vec3_i32 : vec3 = tint_symbol_9(&(ub), 64u); + var vec3_u32 : vec3 = tint_symbol_10(&(ub), 80u); + var vec3_f16 : vec3 = tint_symbol_11(&(ub), 96u); + var vec4_f32 : vec4 = tint_symbol_12(&(ub), 112u); + var vec4_i32 : vec4 = tint_symbol_13(&(ub), 128u); + var vec4_u32 : vec4 = tint_symbol_14(&(ub), 144u); + var vec4_f16 : vec4 = tint_symbol_15(&(ub), 160u); + var mat2x2_f32 : mat2x2 = tint_symbol_16(&(ub), 168u); + var mat2x3_f32 : mat2x3 = tint_symbol_17(&(ub), 192u); + var mat2x4_f32 : mat2x4 = tint_symbol_18(&(ub), 224u); + var mat3x2_f32 : mat3x2 = tint_symbol_19(&(ub), 256u); + var mat3x3_f32 : mat3x3 = tint_symbol_20(&(ub), 288u); + var mat3x4_f32 : mat3x4 = tint_symbol_21(&(ub), 336u); + var mat4x2_f32 : mat4x2 = tint_symbol_22(&(ub), 384u); + var mat4x3_f32 : mat4x3 = tint_symbol_23(&(ub), 416u); + var mat4x4_f32 : mat4x4 = tint_symbol_24(&(ub), 480u); + var mat2x2_f16 : mat2x2 = tint_symbol_25(&(ub), 544u); + var mat2x3_f16 : mat2x3 = tint_symbol_26(&(ub), 552u); + var mat2x4_f16 : mat2x4 = tint_symbol_27(&(ub), 568u); + var mat3x2_f16 : mat3x2 = tint_symbol_28(&(ub), 584u); + var mat3x3_f16 : mat3x3 = tint_symbol_29(&(ub), 600u); + var mat3x4_f16 : mat3x4 = tint_symbol_30(&(ub), 624u); + var mat4x2_f16 : mat4x2 = tint_symbol_31(&(ub), 648u); + var mat4x3_f16 : mat4x3 = tint_symbol_32(&(ub), 664u); + var mat4x4_f16 : mat4x4 = tint_symbol_33(&(ub), 696u); + var arr2_vec3_f32 : array, 2> = tint_symbol_34(&(ub), 736u); + var arr2_mat4x2_f16 : array, 2> = tint_symbol_35(&(ub), 768u); } @group(0) @binding(0) var ub : UB; struct UB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, } )"; @@ -835,209 +1299,342 @@ struct UB { TEST_F(DecomposeMemoryAccessTest, SB_BasicStore) { auto* src = R"( +enable f16; + struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, }; @group(0) @binding(0) var sb : SB; @compute @workgroup_size(1) fn main() { - sb.a = i32(); - sb.b = u32(); - sb.c = f32(); - sb.d = vec2(); - sb.e = vec2(); - sb.f = vec2(); - sb.g = vec3(); - sb.h = vec3(); - sb.i = vec3(); - sb.j = vec4(); - sb.k = vec4(); - sb.l = vec4(); - sb.m = mat2x2(); - sb.n = mat2x3(); - sb.o = mat2x4(); - sb.p = mat3x2(); - sb.q = mat3x3(); - sb.r = mat3x4(); - sb.s = mat4x2(); - sb.t = mat4x3(); - sb.u = mat4x4(); - sb.v = array, 2>(); + sb.scalar_f32 = f32(); + sb.scalar_i32 = i32(); + sb.scalar_u32 = u32(); + sb.scalar_f16 = f16(); + sb.vec2_f32 = vec2(); + sb.vec2_i32 = vec2(); + sb.vec2_u32 = vec2(); + sb.vec2_f16 = vec2(); + sb.vec3_f32 = vec3(); + sb.vec3_i32 = vec3(); + sb.vec3_u32 = vec3(); + sb.vec3_f16 = vec3(); + sb.vec4_f32 = vec4(); + sb.vec4_i32 = vec4(); + sb.vec4_u32 = vec4(); + sb.vec4_f16 = vec4(); + sb.mat2x2_f32 = mat2x2(); + sb.mat2x3_f32 = mat2x3(); + sb.mat2x4_f32 = mat2x4(); + sb.mat3x2_f32 = mat3x2(); + sb.mat3x3_f32 = mat3x3(); + sb.mat3x4_f32 = mat3x4(); + sb.mat4x2_f32 = mat4x2(); + sb.mat4x3_f32 = mat4x3(); + sb.mat4x4_f32 = mat4x4(); + sb.mat2x2_f16 = mat2x2(); + sb.mat2x3_f16 = mat2x3(); + sb.mat2x4_f16 = mat2x4(); + sb.mat3x2_f16 = mat3x2(); + sb.mat3x3_f16 = mat3x3(); + sb.mat3x4_f16 = mat3x4(); + sb.mat4x2_f16 = mat4x2(); + sb.mat4x3_f16 = mat4x3(); + sb.mat4x4_f16 = mat4x4(); + sb.arr2_vec3_f32 = array, 2>(); + sb.arr2_mat4x2_f16 = array, 2>(); } )"; auto* expect = R"( +enable f16; + struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, } @group(0) @binding(0) var sb : SB; +@internal(intrinsic_store_storage_f32) @internal(disable_validation__function_has_no_body) +fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f32) + @internal(intrinsic_store_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : i32) +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : i32) @internal(intrinsic_store_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : u32) +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : u32) -@internal(intrinsic_store_storage_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f32) - -@internal(intrinsic_store_storage_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) - -@internal(intrinsic_store_storage_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +@internal(intrinsic_store_storage_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f16) @internal(intrinsic_store_storage_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) -@internal(intrinsic_store_storage_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) +@internal(intrinsic_store_storage_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) -@internal(intrinsic_store_storage_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) +@internal(intrinsic_store_storage_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) + +@internal(intrinsic_store_storage_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) @internal(intrinsic_store_storage_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) -@internal(intrinsic_store_storage_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +@internal(intrinsic_store_storage_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) -@internal(intrinsic_store_storage_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +@internal(intrinsic_store_storage_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) + +@internal(intrinsic_store_storage_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) @internal(intrinsic_store_storage_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { - tint_symbol_5(buffer, (offset + 0u), value[0u]); - tint_symbol_5(buffer, (offset + 8u), value[1u]); +@internal(intrinsic_store_storage_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +@internal(intrinsic_store_storage_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +@internal(intrinsic_store_storage_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { + tint_symbol_4(buffer, (offset + 0u), value[0u]); + tint_symbol_4(buffer, (offset + 8u), value[1u]); } -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 16u), value[1u]); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { - tint_symbol_11(buffer, (offset + 0u), value[0u]); - tint_symbol_11(buffer, (offset + 16u), value[1u]); +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 16u), value[1u]); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { - tint_symbol_5(buffer, (offset + 0u), value[0u]); - tint_symbol_5(buffer, (offset + 8u), value[1u]); - tint_symbol_5(buffer, (offset + 16u), value[2u]); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { + tint_symbol_4(buffer, (offset + 0u), value[0u]); + tint_symbol_4(buffer, (offset + 8u), value[1u]); + tint_symbol_4(buffer, (offset + 16u), value[2u]); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 32u), value[2u]); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { - tint_symbol_11(buffer, (offset + 0u), value[0u]); - tint_symbol_11(buffer, (offset + 16u), value[1u]); - tint_symbol_11(buffer, (offset + 32u), value[2u]); +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 16u), value[1u]); + tint_symbol_12(buffer, (offset + 32u), value[2u]); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { - tint_symbol_5(buffer, (offset + 0u), value[0u]); - tint_symbol_5(buffer, (offset + 8u), value[1u]); - tint_symbol_5(buffer, (offset + 16u), value[2u]); - tint_symbol_5(buffer, (offset + 24u), value[3u]); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { + tint_symbol_4(buffer, (offset + 0u), value[0u]); + tint_symbol_4(buffer, (offset + 8u), value[1u]); + tint_symbol_4(buffer, (offset + 16u), value[2u]); + tint_symbol_4(buffer, (offset + 24u), value[3u]); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 32u), value[2u]); tint_symbol_8(buffer, (offset + 48u), value[3u]); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { - tint_symbol_11(buffer, (offset + 0u), value[0u]); - tint_symbol_11(buffer, (offset + 16u), value[1u]); - tint_symbol_11(buffer, (offset + 32u), value[2u]); - tint_symbol_11(buffer, (offset + 48u), value[3u]); +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 16u), value[1u]); + tint_symbol_12(buffer, (offset + 32u), value[2u]); + tint_symbol_12(buffer, (offset + 48u), value[3u]); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { + tint_symbol_7(buffer, (offset + 0u), value[0u]); + tint_symbol_7(buffer, (offset + 4u), value[1u]); +} + +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { + tint_symbol_11(buffer, (offset + 0u), value[0u]); + tint_symbol_11(buffer, (offset + 8u), value[1u]); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { + tint_symbol_15(buffer, (offset + 0u), value[0u]); + tint_symbol_15(buffer, (offset + 8u), value[1u]); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { + tint_symbol_7(buffer, (offset + 0u), value[0u]); + tint_symbol_7(buffer, (offset + 4u), value[1u]); + tint_symbol_7(buffer, (offset + 8u), value[2u]); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { + tint_symbol_11(buffer, (offset + 0u), value[0u]); + tint_symbol_11(buffer, (offset + 8u), value[1u]); + tint_symbol_11(buffer, (offset + 16u), value[2u]); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { + tint_symbol_15(buffer, (offset + 0u), value[0u]); + tint_symbol_15(buffer, (offset + 8u), value[1u]); + tint_symbol_15(buffer, (offset + 16u), value[2u]); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { + tint_symbol_7(buffer, (offset + 0u), value[0u]); + tint_symbol_7(buffer, (offset + 4u), value[1u]); + tint_symbol_7(buffer, (offset + 8u), value[2u]); + tint_symbol_7(buffer, (offset + 12u), value[3u]); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { + tint_symbol_11(buffer, (offset + 0u), value[0u]); + tint_symbol_11(buffer, (offset + 8u), value[1u]); + tint_symbol_11(buffer, (offset + 16u), value[2u]); + tint_symbol_11(buffer, (offset + 24u), value[3u]); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { + tint_symbol_15(buffer, (offset + 0u), value[0u]); + tint_symbol_15(buffer, (offset + 8u), value[1u]); + tint_symbol_15(buffer, (offset + 16u), value[2u]); + tint_symbol_15(buffer, (offset + 24u), value[3u]); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { var array = value; + for(var i = 0u; (i < 2u); i = (i + 1u)) { + tint_symbol_8(buffer, (offset + (i * 16u)), array[i]); + } +} + +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { + var array_1 = value; for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - tint_symbol_8(buffer, (offset + (i_1 * 16u)), array[i_1]); + tint_symbol_31(buffer, (offset + (i_1 * 16u)), array_1[i_1]); } } @compute @workgroup_size(1) fn main() { - tint_symbol(&(sb), 0u, i32()); - tint_symbol_1(&(sb), 4u, u32()); - tint_symbol_2(&(sb), 8u, f32()); - tint_symbol_3(&(sb), 16u, vec2()); - tint_symbol_4(&(sb), 24u, vec2()); - tint_symbol_5(&(sb), 32u, vec2()); - tint_symbol_6(&(sb), 48u, vec3()); - tint_symbol_7(&(sb), 64u, vec3()); - tint_symbol_8(&(sb), 80u, vec3()); - tint_symbol_9(&(sb), 96u, vec4()); - tint_symbol_10(&(sb), 112u, vec4()); - tint_symbol_11(&(sb), 128u, vec4()); - tint_symbol_12(&(sb), 144u, mat2x2()); - tint_symbol_13(&(sb), 160u, mat2x3()); - tint_symbol_14(&(sb), 192u, mat2x4()); - tint_symbol_15(&(sb), 224u, mat3x2()); - tint_symbol_16(&(sb), 256u, mat3x3()); - tint_symbol_17(&(sb), 304u, mat3x4()); - tint_symbol_18(&(sb), 352u, mat4x2()); - tint_symbol_19(&(sb), 384u, mat4x3()); - tint_symbol_20(&(sb), 448u, mat4x4()); - tint_symbol_21(&(sb), 512u, array, 2>()); + tint_symbol(&(sb), 0u, f32()); + tint_symbol_1(&(sb), 4u, i32()); + tint_symbol_2(&(sb), 8u, u32()); + tint_symbol_3(&(sb), 12u, f16()); + tint_symbol_4(&(sb), 16u, vec2()); + tint_symbol_5(&(sb), 24u, vec2()); + tint_symbol_6(&(sb), 32u, vec2()); + tint_symbol_7(&(sb), 40u, vec2()); + tint_symbol_8(&(sb), 48u, vec3()); + tint_symbol_9(&(sb), 64u, vec3()); + tint_symbol_10(&(sb), 80u, vec3()); + tint_symbol_11(&(sb), 96u, vec3()); + tint_symbol_12(&(sb), 112u, vec4()); + tint_symbol_13(&(sb), 128u, vec4()); + tint_symbol_14(&(sb), 144u, vec4()); + tint_symbol_15(&(sb), 160u, vec4()); + tint_symbol_16(&(sb), 168u, mat2x2()); + tint_symbol_17(&(sb), 192u, mat2x3()); + tint_symbol_18(&(sb), 224u, mat2x4()); + tint_symbol_19(&(sb), 256u, mat3x2()); + tint_symbol_20(&(sb), 288u, mat3x3()); + tint_symbol_21(&(sb), 336u, mat3x4()); + tint_symbol_22(&(sb), 384u, mat4x2()); + tint_symbol_23(&(sb), 416u, mat4x3()); + tint_symbol_24(&(sb), 480u, mat4x4()); + tint_symbol_25(&(sb), 544u, mat2x2()); + tint_symbol_26(&(sb), 552u, mat2x3()); + tint_symbol_27(&(sb), 568u, mat2x4()); + tint_symbol_28(&(sb), 584u, mat3x2()); + tint_symbol_29(&(sb), 600u, mat3x3()); + tint_symbol_30(&(sb), 624u, mat3x4()); + tint_symbol_31(&(sb), 648u, mat4x2()); + tint_symbol_32(&(sb), 664u, mat4x3()); + tint_symbol_33(&(sb), 696u, mat4x4()); + tint_symbol_34(&(sb), 736u, array, 2>()); + tint_symbol_35(&(sb), 768u, array, 2>()); } )"; @@ -1048,209 +1645,342 @@ fn main() { TEST_F(DecomposeMemoryAccessTest, SB_BasicStore_OutOfOrder) { auto* src = R"( +enable f16; + @compute @workgroup_size(1) fn main() { - sb.a = i32(); - sb.b = u32(); - sb.c = f32(); - sb.d = vec2(); - sb.e = vec2(); - sb.f = vec2(); - sb.g = vec3(); - sb.h = vec3(); - sb.i = vec3(); - sb.j = vec4(); - sb.k = vec4(); - sb.l = vec4(); - sb.m = mat2x2(); - sb.n = mat2x3(); - sb.o = mat2x4(); - sb.p = mat3x2(); - sb.q = mat3x3(); - sb.r = mat3x4(); - sb.s = mat4x2(); - sb.t = mat4x3(); - sb.u = mat4x4(); - sb.v = array, 2>(); + sb.scalar_f32 = f32(); + sb.scalar_i32 = i32(); + sb.scalar_u32 = u32(); + sb.scalar_f16 = f16(); + sb.vec2_f32 = vec2(); + sb.vec2_i32 = vec2(); + sb.vec2_u32 = vec2(); + sb.vec2_f16 = vec2(); + sb.vec3_f32 = vec3(); + sb.vec3_i32 = vec3(); + sb.vec3_u32 = vec3(); + sb.vec3_f16 = vec3(); + sb.vec4_f32 = vec4(); + sb.vec4_i32 = vec4(); + sb.vec4_u32 = vec4(); + sb.vec4_f16 = vec4(); + sb.mat2x2_f32 = mat2x2(); + sb.mat2x3_f32 = mat2x3(); + sb.mat2x4_f32 = mat2x4(); + sb.mat3x2_f32 = mat3x2(); + sb.mat3x3_f32 = mat3x3(); + sb.mat3x4_f32 = mat3x4(); + sb.mat4x2_f32 = mat4x2(); + sb.mat4x3_f32 = mat4x3(); + sb.mat4x4_f32 = mat4x4(); + sb.mat2x2_f16 = mat2x2(); + sb.mat2x3_f16 = mat2x3(); + sb.mat2x4_f16 = mat2x4(); + sb.mat3x2_f16 = mat3x2(); + sb.mat3x3_f16 = mat3x3(); + sb.mat3x4_f16 = mat3x4(); + sb.mat4x2_f16 = mat4x2(); + sb.mat4x3_f16 = mat4x3(); + sb.mat4x4_f16 = mat4x4(); + sb.arr2_vec3_f32 = array, 2>(); + sb.arr2_mat4x2_f16 = array, 2>(); } @group(0) @binding(0) var sb : SB; struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, }; )"; auto* expect = R"( -@internal(intrinsic_store_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : i32) - -@internal(intrinsic_store_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : u32) +enable f16; @internal(intrinsic_store_storage_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f32) +fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f32) -@internal(intrinsic_store_storage_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +@internal(intrinsic_store_storage_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : i32) -@internal(intrinsic_store_storage_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +@internal(intrinsic_store_storage_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : u32) + +@internal(intrinsic_store_storage_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f16) @internal(intrinsic_store_storage_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) -@internal(intrinsic_store_storage_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) +@internal(intrinsic_store_storage_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) -@internal(intrinsic_store_storage_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) +@internal(intrinsic_store_storage_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) + +@internal(intrinsic_store_storage_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) @internal(intrinsic_store_storage_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) -@internal(intrinsic_store_storage_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +@internal(intrinsic_store_storage_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) -@internal(intrinsic_store_storage_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +@internal(intrinsic_store_storage_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) + +@internal(intrinsic_store_storage_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) @internal(intrinsic_store_storage_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { - tint_symbol_5(buffer, (offset + 0u), value[0u]); - tint_symbol_5(buffer, (offset + 8u), value[1u]); +@internal(intrinsic_store_storage_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +@internal(intrinsic_store_storage_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +@internal(intrinsic_store_storage_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { + tint_symbol_4(buffer, (offset + 0u), value[0u]); + tint_symbol_4(buffer, (offset + 8u), value[1u]); } -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 16u), value[1u]); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { - tint_symbol_11(buffer, (offset + 0u), value[0u]); - tint_symbol_11(buffer, (offset + 16u), value[1u]); +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 16u), value[1u]); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { - tint_symbol_5(buffer, (offset + 0u), value[0u]); - tint_symbol_5(buffer, (offset + 8u), value[1u]); - tint_symbol_5(buffer, (offset + 16u), value[2u]); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { + tint_symbol_4(buffer, (offset + 0u), value[0u]); + tint_symbol_4(buffer, (offset + 8u), value[1u]); + tint_symbol_4(buffer, (offset + 16u), value[2u]); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 32u), value[2u]); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { - tint_symbol_11(buffer, (offset + 0u), value[0u]); - tint_symbol_11(buffer, (offset + 16u), value[1u]); - tint_symbol_11(buffer, (offset + 32u), value[2u]); +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 16u), value[1u]); + tint_symbol_12(buffer, (offset + 32u), value[2u]); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { - tint_symbol_5(buffer, (offset + 0u), value[0u]); - tint_symbol_5(buffer, (offset + 8u), value[1u]); - tint_symbol_5(buffer, (offset + 16u), value[2u]); - tint_symbol_5(buffer, (offset + 24u), value[3u]); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { + tint_symbol_4(buffer, (offset + 0u), value[0u]); + tint_symbol_4(buffer, (offset + 8u), value[1u]); + tint_symbol_4(buffer, (offset + 16u), value[2u]); + tint_symbol_4(buffer, (offset + 24u), value[3u]); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 32u), value[2u]); tint_symbol_8(buffer, (offset + 48u), value[3u]); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { - tint_symbol_11(buffer, (offset + 0u), value[0u]); - tint_symbol_11(buffer, (offset + 16u), value[1u]); - tint_symbol_11(buffer, (offset + 32u), value[2u]); - tint_symbol_11(buffer, (offset + 48u), value[3u]); +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 16u), value[1u]); + tint_symbol_12(buffer, (offset + 32u), value[2u]); + tint_symbol_12(buffer, (offset + 48u), value[3u]); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { + tint_symbol_7(buffer, (offset + 0u), value[0u]); + tint_symbol_7(buffer, (offset + 4u), value[1u]); +} + +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { + tint_symbol_11(buffer, (offset + 0u), value[0u]); + tint_symbol_11(buffer, (offset + 8u), value[1u]); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { + tint_symbol_15(buffer, (offset + 0u), value[0u]); + tint_symbol_15(buffer, (offset + 8u), value[1u]); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { + tint_symbol_7(buffer, (offset + 0u), value[0u]); + tint_symbol_7(buffer, (offset + 4u), value[1u]); + tint_symbol_7(buffer, (offset + 8u), value[2u]); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { + tint_symbol_11(buffer, (offset + 0u), value[0u]); + tint_symbol_11(buffer, (offset + 8u), value[1u]); + tint_symbol_11(buffer, (offset + 16u), value[2u]); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { + tint_symbol_15(buffer, (offset + 0u), value[0u]); + tint_symbol_15(buffer, (offset + 8u), value[1u]); + tint_symbol_15(buffer, (offset + 16u), value[2u]); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { + tint_symbol_7(buffer, (offset + 0u), value[0u]); + tint_symbol_7(buffer, (offset + 4u), value[1u]); + tint_symbol_7(buffer, (offset + 8u), value[2u]); + tint_symbol_7(buffer, (offset + 12u), value[3u]); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { + tint_symbol_11(buffer, (offset + 0u), value[0u]); + tint_symbol_11(buffer, (offset + 8u), value[1u]); + tint_symbol_11(buffer, (offset + 16u), value[2u]); + tint_symbol_11(buffer, (offset + 24u), value[3u]); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { + tint_symbol_15(buffer, (offset + 0u), value[0u]); + tint_symbol_15(buffer, (offset + 8u), value[1u]); + tint_symbol_15(buffer, (offset + 16u), value[2u]); + tint_symbol_15(buffer, (offset + 24u), value[3u]); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { var array = value; + for(var i = 0u; (i < 2u); i = (i + 1u)) { + tint_symbol_8(buffer, (offset + (i * 16u)), array[i]); + } +} + +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { + var array_1 = value; for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - tint_symbol_8(buffer, (offset + (i_1 * 16u)), array[i_1]); + tint_symbol_31(buffer, (offset + (i_1 * 16u)), array_1[i_1]); } } @compute @workgroup_size(1) fn main() { - tint_symbol(&(sb), 0u, i32()); - tint_symbol_1(&(sb), 4u, u32()); - tint_symbol_2(&(sb), 8u, f32()); - tint_symbol_3(&(sb), 16u, vec2()); - tint_symbol_4(&(sb), 24u, vec2()); - tint_symbol_5(&(sb), 32u, vec2()); - tint_symbol_6(&(sb), 48u, vec3()); - tint_symbol_7(&(sb), 64u, vec3()); - tint_symbol_8(&(sb), 80u, vec3()); - tint_symbol_9(&(sb), 96u, vec4()); - tint_symbol_10(&(sb), 112u, vec4()); - tint_symbol_11(&(sb), 128u, vec4()); - tint_symbol_12(&(sb), 144u, mat2x2()); - tint_symbol_13(&(sb), 160u, mat2x3()); - tint_symbol_14(&(sb), 192u, mat2x4()); - tint_symbol_15(&(sb), 224u, mat3x2()); - tint_symbol_16(&(sb), 256u, mat3x3()); - tint_symbol_17(&(sb), 304u, mat3x4()); - tint_symbol_18(&(sb), 352u, mat4x2()); - tint_symbol_19(&(sb), 384u, mat4x3()); - tint_symbol_20(&(sb), 448u, mat4x4()); - tint_symbol_21(&(sb), 512u, array, 2>()); + tint_symbol(&(sb), 0u, f32()); + tint_symbol_1(&(sb), 4u, i32()); + tint_symbol_2(&(sb), 8u, u32()); + tint_symbol_3(&(sb), 12u, f16()); + tint_symbol_4(&(sb), 16u, vec2()); + tint_symbol_5(&(sb), 24u, vec2()); + tint_symbol_6(&(sb), 32u, vec2()); + tint_symbol_7(&(sb), 40u, vec2()); + tint_symbol_8(&(sb), 48u, vec3()); + tint_symbol_9(&(sb), 64u, vec3()); + tint_symbol_10(&(sb), 80u, vec3()); + tint_symbol_11(&(sb), 96u, vec3()); + tint_symbol_12(&(sb), 112u, vec4()); + tint_symbol_13(&(sb), 128u, vec4()); + tint_symbol_14(&(sb), 144u, vec4()); + tint_symbol_15(&(sb), 160u, vec4()); + tint_symbol_16(&(sb), 168u, mat2x2()); + tint_symbol_17(&(sb), 192u, mat2x3()); + tint_symbol_18(&(sb), 224u, mat2x4()); + tint_symbol_19(&(sb), 256u, mat3x2()); + tint_symbol_20(&(sb), 288u, mat3x3()); + tint_symbol_21(&(sb), 336u, mat3x4()); + tint_symbol_22(&(sb), 384u, mat4x2()); + tint_symbol_23(&(sb), 416u, mat4x3()); + tint_symbol_24(&(sb), 480u, mat4x4()); + tint_symbol_25(&(sb), 544u, mat2x2()); + tint_symbol_26(&(sb), 552u, mat2x3()); + tint_symbol_27(&(sb), 568u, mat2x4()); + tint_symbol_28(&(sb), 584u, mat3x2()); + tint_symbol_29(&(sb), 600u, mat3x3()); + tint_symbol_30(&(sb), 624u, mat3x4()); + tint_symbol_31(&(sb), 648u, mat4x2()); + tint_symbol_32(&(sb), 664u, mat4x3()); + tint_symbol_33(&(sb), 696u, mat4x4()); + tint_symbol_34(&(sb), 736u, array, 2>()); + tint_symbol_35(&(sb), 768u, array, 2>()); } @group(0) @binding(0) var sb : SB; struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, } )"; @@ -1261,29 +1991,45 @@ struct SB { TEST_F(DecomposeMemoryAccessTest, LoadStructure) { auto* src = R"( +enable f16; + struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, }; @group(0) @binding(0) var sb : SB; @@ -1295,115 +2041,187 @@ fn main() { )"; auto* expect = R"( +enable f16; + struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, } @group(0) @binding(0) var sb : SB; +@internal(intrinsic_load_storage_f32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 + @internal(intrinsic_load_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 @internal(intrinsic_load_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 -@internal(intrinsic_load_storage_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 - -@internal(intrinsic_load_storage_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 - -@internal(intrinsic_load_storage_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_storage_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 @internal(intrinsic_load_storage_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_storage_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_storage_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_storage_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_storage_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 + +@internal(intrinsic_load_storage_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_storage_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_storage_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_storage_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_storage_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_storage_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 + +@internal(intrinsic_load_storage_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_storage_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { - return mat2x2(tint_symbol_6(buffer, (offset + 0u)), tint_symbol_6(buffer, (offset + 8u))); +@internal(intrinsic_load_storage_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_storage_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_storage_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u))); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_9(buffer, (offset + 0u)), tint_symbol_9(buffer, (offset + 16u))); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { - return mat2x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u))); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_13(buffer, (offset + 0u)), tint_symbol_13(buffer, (offset + 16u))); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { - return mat3x2(tint_symbol_6(buffer, (offset + 0u)), tint_symbol_6(buffer, (offset + 8u)), tint_symbol_6(buffer, (offset + 16u))); +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u))); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_9(buffer, (offset + 0u)), tint_symbol_9(buffer, (offset + 16u)), tint_symbol_9(buffer, (offset + 32u))); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { - return mat3x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u))); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_13(buffer, (offset + 0u)), tint_symbol_13(buffer, (offset + 16u)), tint_symbol_13(buffer, (offset + 32u))); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { - return mat4x2(tint_symbol_6(buffer, (offset + 0u)), tint_symbol_6(buffer, (offset + 8u)), tint_symbol_6(buffer, (offset + 16u)), tint_symbol_6(buffer, (offset + 24u))); +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u))); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_9(buffer, (offset + 0u)), tint_symbol_9(buffer, (offset + 16u)), tint_symbol_9(buffer, (offset + 32u)), tint_symbol_9(buffer, (offset + 48u))); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { - return mat4x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u)), tint_symbol_12(buffer, (offset + 48u))); +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_13(buffer, (offset + 0u)), tint_symbol_13(buffer, (offset + 16u)), tint_symbol_13(buffer, (offset + 32u)), tint_symbol_13(buffer, (offset + 48u))); } -fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 4u))); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { + return mat2x3(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 8u))); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_16(buffer, (offset + 0u)), tint_symbol_16(buffer, (offset + 8u))); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 4u)), tint_symbol_8(buffer, (offset + 8u))); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { + return mat3x3(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 8u)), tint_symbol_12(buffer, (offset + 16u))); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_16(buffer, (offset + 0u)), tint_symbol_16(buffer, (offset + 8u)), tint_symbol_16(buffer, (offset + 16u))); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 4u)), tint_symbol_8(buffer, (offset + 8u)), tint_symbol_8(buffer, (offset + 12u))); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { + return mat4x3(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 8u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 24u))); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_16(buffer, (offset + 0u)), tint_symbol_16(buffer, (offset + 8u)), tint_symbol_16(buffer, (offset + 16u)), tint_symbol_16(buffer, (offset + 24u))); +} + +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr : array, 2u>; - for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - arr[i_1] = tint_symbol_9(buffer, (offset + (i_1 * 16u))); + for(var i = 0u; (i < 2u); i = (i + 1u)) { + arr[i] = tint_symbol_9(buffer, (offset + (i * 16u))); } return arr; } +fn tint_symbol_36(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { + var arr_1 : array, 2u>; + for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { + arr_1[i_1] = tint_symbol_32(buffer, (offset + (i_1 * 16u))); + } + return arr_1; +} + fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> SB { - return SB(tint_symbol_1(buffer, (offset + 0u)), tint_symbol_2(buffer, (offset + 4u)), tint_symbol_3(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u)), tint_symbol_6(buffer, (offset + 32u)), tint_symbol_7(buffer, (offset + 48u)), tint_symbol_8(buffer, (offset + 64u)), tint_symbol_9(buffer, (offset + 80u)), tint_symbol_10(buffer, (offset + 96u)), tint_symbol_11(buffer, (offset + 112u)), tint_symbol_12(buffer, (offset + 128u)), tint_symbol_13(buffer, (offset + 144u)), tint_symbol_14(buffer, (offset + 160u)), tint_symbol_15(buffer, (offset + 192u)), tint_symbol_16(buffer, (offset + 224u)), tint_symbol_17(buffer, (offset + 256u)), tint_symbol_18(buffer, (offset + 304u)), tint_symbol_19(buffer, (offset + 352u)), tint_symbol_20(buffer, (offset + 384u)), tint_symbol_21(buffer, (offset + 448u)), tint_symbol_22(buffer, (offset + 512u))); + return SB(tint_symbol_1(buffer, (offset + 0u)), tint_symbol_2(buffer, (offset + 4u)), tint_symbol_3(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 12u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_6(buffer, (offset + 24u)), tint_symbol_7(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 40u)), tint_symbol_9(buffer, (offset + 48u)), tint_symbol_10(buffer, (offset + 64u)), tint_symbol_11(buffer, (offset + 80u)), tint_symbol_12(buffer, (offset + 96u)), tint_symbol_13(buffer, (offset + 112u)), tint_symbol_14(buffer, (offset + 128u)), tint_symbol_15(buffer, (offset + 144u)), tint_symbol_16(buffer, (offset + 160u)), tint_symbol_17(buffer, (offset + 168u)), tint_symbol_18(buffer, (offset + 192u)), tint_symbol_19(buffer, (offset + 224u)), tint_symbol_20(buffer, (offset + 256u)), tint_symbol_21(buffer, (offset + 288u)), tint_symbol_22(buffer, (offset + 336u)), tint_symbol_23(buffer, (offset + 384u)), tint_symbol_24(buffer, (offset + 416u)), tint_symbol_25(buffer, (offset + 480u)), tint_symbol_26(buffer, (offset + 544u)), tint_symbol_27(buffer, (offset + 552u)), tint_symbol_28(buffer, (offset + 568u)), tint_symbol_29(buffer, (offset + 584u)), tint_symbol_30(buffer, (offset + 600u)), tint_symbol_31(buffer, (offset + 624u)), tint_symbol_32(buffer, (offset + 648u)), tint_symbol_33(buffer, (offset + 664u)), tint_symbol_34(buffer, (offset + 696u)), tint_symbol_35(buffer, (offset + 736u)), tint_symbol_36(buffer, (offset + 768u))); } @compute @workgroup_size(1) @@ -1419,6 +2237,8 @@ fn main() { TEST_F(DecomposeMemoryAccessTest, LoadStructure_OutOfOrder) { auto* src = R"( +enable f16; + @compute @workgroup_size(1) fn main() { var x : SB = sb; @@ -1427,114 +2247,186 @@ fn main() { @group(0) @binding(0) var sb : SB; struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, }; )"; auto* expect = R"( -@internal(intrinsic_load_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 - -@internal(intrinsic_load_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 +enable f16; @internal(intrinsic_load_storage_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 -@internal(intrinsic_load_storage_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_storage_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 -@internal(intrinsic_load_storage_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +@internal(intrinsic_load_storage_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 + +@internal(intrinsic_load_storage_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 @internal(intrinsic_load_storage_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_storage_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_storage_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 -@internal(intrinsic_load_storage_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +@internal(intrinsic_load_storage_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 + +@internal(intrinsic_load_storage_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_storage_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_storage_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_storage_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 -@internal(intrinsic_load_storage_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +@internal(intrinsic_load_storage_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 + +@internal(intrinsic_load_storage_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_storage_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { - return mat2x2(tint_symbol_6(buffer, (offset + 0u)), tint_symbol_6(buffer, (offset + 8u))); +@internal(intrinsic_load_storage_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_storage_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +@internal(intrinsic_load_storage_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 + +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u))); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_9(buffer, (offset + 0u)), tint_symbol_9(buffer, (offset + 16u))); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { - return mat2x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u))); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_13(buffer, (offset + 0u)), tint_symbol_13(buffer, (offset + 16u))); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { - return mat3x2(tint_symbol_6(buffer, (offset + 0u)), tint_symbol_6(buffer, (offset + 8u)), tint_symbol_6(buffer, (offset + 16u))); +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u))); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_9(buffer, (offset + 0u)), tint_symbol_9(buffer, (offset + 16u)), tint_symbol_9(buffer, (offset + 32u))); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { - return mat3x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u))); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_13(buffer, (offset + 0u)), tint_symbol_13(buffer, (offset + 16u)), tint_symbol_13(buffer, (offset + 32u))); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { - return mat4x2(tint_symbol_6(buffer, (offset + 0u)), tint_symbol_6(buffer, (offset + 8u)), tint_symbol_6(buffer, (offset + 16u)), tint_symbol_6(buffer, (offset + 24u))); +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u))); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_9(buffer, (offset + 0u)), tint_symbol_9(buffer, (offset + 16u)), tint_symbol_9(buffer, (offset + 32u)), tint_symbol_9(buffer, (offset + 48u))); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { - return mat4x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u)), tint_symbol_12(buffer, (offset + 48u))); +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_13(buffer, (offset + 0u)), tint_symbol_13(buffer, (offset + 16u)), tint_symbol_13(buffer, (offset + 32u)), tint_symbol_13(buffer, (offset + 48u))); } -fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { + return mat2x2(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 4u))); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { + return mat2x3(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 8u))); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { + return mat2x4(tint_symbol_16(buffer, (offset + 0u)), tint_symbol_16(buffer, (offset + 8u))); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { + return mat3x2(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 4u)), tint_symbol_8(buffer, (offset + 8u))); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { + return mat3x3(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 8u)), tint_symbol_12(buffer, (offset + 16u))); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { + return mat3x4(tint_symbol_16(buffer, (offset + 0u)), tint_symbol_16(buffer, (offset + 8u)), tint_symbol_16(buffer, (offset + 16u))); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { + return mat4x2(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 4u)), tint_symbol_8(buffer, (offset + 8u)), tint_symbol_8(buffer, (offset + 12u))); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { + return mat4x3(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 8u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 24u))); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { + return mat4x4(tint_symbol_16(buffer, (offset + 0u)), tint_symbol_16(buffer, (offset + 8u)), tint_symbol_16(buffer, (offset + 16u)), tint_symbol_16(buffer, (offset + 24u))); +} + +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr : array, 2u>; - for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - arr[i_1] = tint_symbol_9(buffer, (offset + (i_1 * 16u))); + for(var i = 0u; (i < 2u); i = (i + 1u)) { + arr[i] = tint_symbol_9(buffer, (offset + (i * 16u))); } return arr; } +fn tint_symbol_36(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { + var arr_1 : array, 2u>; + for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { + arr_1[i_1] = tint_symbol_32(buffer, (offset + (i_1 * 16u))); + } + return arr_1; +} + fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> SB { - return SB(tint_symbol_1(buffer, (offset + 0u)), tint_symbol_2(buffer, (offset + 4u)), tint_symbol_3(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u)), tint_symbol_6(buffer, (offset + 32u)), tint_symbol_7(buffer, (offset + 48u)), tint_symbol_8(buffer, (offset + 64u)), tint_symbol_9(buffer, (offset + 80u)), tint_symbol_10(buffer, (offset + 96u)), tint_symbol_11(buffer, (offset + 112u)), tint_symbol_12(buffer, (offset + 128u)), tint_symbol_13(buffer, (offset + 144u)), tint_symbol_14(buffer, (offset + 160u)), tint_symbol_15(buffer, (offset + 192u)), tint_symbol_16(buffer, (offset + 224u)), tint_symbol_17(buffer, (offset + 256u)), tint_symbol_18(buffer, (offset + 304u)), tint_symbol_19(buffer, (offset + 352u)), tint_symbol_20(buffer, (offset + 384u)), tint_symbol_21(buffer, (offset + 448u)), tint_symbol_22(buffer, (offset + 512u))); + return SB(tint_symbol_1(buffer, (offset + 0u)), tint_symbol_2(buffer, (offset + 4u)), tint_symbol_3(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 12u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_6(buffer, (offset + 24u)), tint_symbol_7(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 40u)), tint_symbol_9(buffer, (offset + 48u)), tint_symbol_10(buffer, (offset + 64u)), tint_symbol_11(buffer, (offset + 80u)), tint_symbol_12(buffer, (offset + 96u)), tint_symbol_13(buffer, (offset + 112u)), tint_symbol_14(buffer, (offset + 128u)), tint_symbol_15(buffer, (offset + 144u)), tint_symbol_16(buffer, (offset + 160u)), tint_symbol_17(buffer, (offset + 168u)), tint_symbol_18(buffer, (offset + 192u)), tint_symbol_19(buffer, (offset + 224u)), tint_symbol_20(buffer, (offset + 256u)), tint_symbol_21(buffer, (offset + 288u)), tint_symbol_22(buffer, (offset + 336u)), tint_symbol_23(buffer, (offset + 384u)), tint_symbol_24(buffer, (offset + 416u)), tint_symbol_25(buffer, (offset + 480u)), tint_symbol_26(buffer, (offset + 544u)), tint_symbol_27(buffer, (offset + 552u)), tint_symbol_28(buffer, (offset + 568u)), tint_symbol_29(buffer, (offset + 584u)), tint_symbol_30(buffer, (offset + 600u)), tint_symbol_31(buffer, (offset + 624u)), tint_symbol_32(buffer, (offset + 648u)), tint_symbol_33(buffer, (offset + 664u)), tint_symbol_34(buffer, (offset + 696u)), tint_symbol_35(buffer, (offset + 736u)), tint_symbol_36(buffer, (offset + 768u))); } @compute @workgroup_size(1) @@ -1545,28 +2437,42 @@ fn main() { @group(0) @binding(0) var sb : SB; struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, } )"; @@ -1577,29 +2483,45 @@ struct SB { TEST_F(DecomposeMemoryAccessTest, StoreStructure) { auto* src = R"( +enable f16; + struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, }; @group(0) @binding(0) var sb : SB; @@ -1611,153 +2533,256 @@ fn main() { )"; auto* expect = R"( +enable f16; + struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, } @group(0) @binding(0) var sb : SB; +@internal(intrinsic_store_storage_f32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f32) + @internal(intrinsic_store_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : i32) +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : i32) @internal(intrinsic_store_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : u32) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : u32) -@internal(intrinsic_store_storage_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f32) - -@internal(intrinsic_store_storage_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) - -@internal(intrinsic_store_storage_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +@internal(intrinsic_store_storage_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f16) @internal(intrinsic_store_storage_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) -@internal(intrinsic_store_storage_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) +@internal(intrinsic_store_storage_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) -@internal(intrinsic_store_storage_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) +@internal(intrinsic_store_storage_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) + +@internal(intrinsic_store_storage_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) @internal(intrinsic_store_storage_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) -@internal(intrinsic_store_storage_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +@internal(intrinsic_store_storage_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) -@internal(intrinsic_store_storage_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +@internal(intrinsic_store_storage_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) + +@internal(intrinsic_store_storage_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) @internal(intrinsic_store_storage_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { - tint_symbol_6(buffer, (offset + 0u), value[0u]); - tint_symbol_6(buffer, (offset + 8u), value[1u]); +@internal(intrinsic_store_storage_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +@internal(intrinsic_store_storage_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +@internal(intrinsic_store_storage_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { + tint_symbol_5(buffer, (offset + 0u), value[0u]); + tint_symbol_5(buffer, (offset + 8u), value[1u]); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { tint_symbol_9(buffer, (offset + 0u), value[0u]); tint_symbol_9(buffer, (offset + 16u), value[1u]); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { - tint_symbol_12(buffer, (offset + 0u), value[0u]); - tint_symbol_12(buffer, (offset + 16u), value[1u]); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { + tint_symbol_13(buffer, (offset + 0u), value[0u]); + tint_symbol_13(buffer, (offset + 16u), value[1u]); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { - tint_symbol_6(buffer, (offset + 0u), value[0u]); - tint_symbol_6(buffer, (offset + 8u), value[1u]); - tint_symbol_6(buffer, (offset + 16u), value[2u]); +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { + tint_symbol_5(buffer, (offset + 0u), value[0u]); + tint_symbol_5(buffer, (offset + 8u), value[1u]); + tint_symbol_5(buffer, (offset + 16u), value[2u]); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { tint_symbol_9(buffer, (offset + 0u), value[0u]); tint_symbol_9(buffer, (offset + 16u), value[1u]); tint_symbol_9(buffer, (offset + 32u), value[2u]); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { - tint_symbol_12(buffer, (offset + 0u), value[0u]); - tint_symbol_12(buffer, (offset + 16u), value[1u]); - tint_symbol_12(buffer, (offset + 32u), value[2u]); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { + tint_symbol_13(buffer, (offset + 0u), value[0u]); + tint_symbol_13(buffer, (offset + 16u), value[1u]); + tint_symbol_13(buffer, (offset + 32u), value[2u]); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { - tint_symbol_6(buffer, (offset + 0u), value[0u]); - tint_symbol_6(buffer, (offset + 8u), value[1u]); - tint_symbol_6(buffer, (offset + 16u), value[2u]); - tint_symbol_6(buffer, (offset + 24u), value[3u]); +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { + tint_symbol_5(buffer, (offset + 0u), value[0u]); + tint_symbol_5(buffer, (offset + 8u), value[1u]); + tint_symbol_5(buffer, (offset + 16u), value[2u]); + tint_symbol_5(buffer, (offset + 24u), value[3u]); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { tint_symbol_9(buffer, (offset + 0u), value[0u]); tint_symbol_9(buffer, (offset + 16u), value[1u]); tint_symbol_9(buffer, (offset + 32u), value[2u]); tint_symbol_9(buffer, (offset + 48u), value[3u]); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { - tint_symbol_12(buffer, (offset + 0u), value[0u]); - tint_symbol_12(buffer, (offset + 16u), value[1u]); - tint_symbol_12(buffer, (offset + 32u), value[2u]); - tint_symbol_12(buffer, (offset + 48u), value[3u]); +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { + tint_symbol_13(buffer, (offset + 0u), value[0u]); + tint_symbol_13(buffer, (offset + 16u), value[1u]); + tint_symbol_13(buffer, (offset + 32u), value[2u]); + tint_symbol_13(buffer, (offset + 48u), value[3u]); } -fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { + tint_symbol_8(buffer, (offset + 0u), value[0u]); + tint_symbol_8(buffer, (offset + 4u), value[1u]); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 8u), value[1u]); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { + tint_symbol_16(buffer, (offset + 0u), value[0u]); + tint_symbol_16(buffer, (offset + 8u), value[1u]); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { + tint_symbol_8(buffer, (offset + 0u), value[0u]); + tint_symbol_8(buffer, (offset + 4u), value[1u]); + tint_symbol_8(buffer, (offset + 8u), value[2u]); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 8u), value[1u]); + tint_symbol_12(buffer, (offset + 16u), value[2u]); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { + tint_symbol_16(buffer, (offset + 0u), value[0u]); + tint_symbol_16(buffer, (offset + 8u), value[1u]); + tint_symbol_16(buffer, (offset + 16u), value[2u]); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { + tint_symbol_8(buffer, (offset + 0u), value[0u]); + tint_symbol_8(buffer, (offset + 4u), value[1u]); + tint_symbol_8(buffer, (offset + 8u), value[2u]); + tint_symbol_8(buffer, (offset + 12u), value[3u]); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 8u), value[1u]); + tint_symbol_12(buffer, (offset + 16u), value[2u]); + tint_symbol_12(buffer, (offset + 24u), value[3u]); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { + tint_symbol_16(buffer, (offset + 0u), value[0u]); + tint_symbol_16(buffer, (offset + 8u), value[1u]); + tint_symbol_16(buffer, (offset + 16u), value[2u]); + tint_symbol_16(buffer, (offset + 24u), value[3u]); +} + +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { var array = value; + for(var i = 0u; (i < 2u); i = (i + 1u)) { + tint_symbol_9(buffer, (offset + (i * 16u)), array[i]); + } +} + +fn tint_symbol_36(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { + var array_1 = value; for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - tint_symbol_9(buffer, (offset + (i_1 * 16u)), array[i_1]); + tint_symbol_32(buffer, (offset + (i_1 * 16u)), array_1[i_1]); } } fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : SB) { - tint_symbol_1(buffer, (offset + 0u), value.a); - tint_symbol_2(buffer, (offset + 4u), value.b); - tint_symbol_3(buffer, (offset + 8u), value.c); - tint_symbol_4(buffer, (offset + 16u), value.d); - tint_symbol_5(buffer, (offset + 24u), value.e); - tint_symbol_6(buffer, (offset + 32u), value.f); - tint_symbol_7(buffer, (offset + 48u), value.g); - tint_symbol_8(buffer, (offset + 64u), value.h); - tint_symbol_9(buffer, (offset + 80u), value.i); - tint_symbol_10(buffer, (offset + 96u), value.j); - tint_symbol_11(buffer, (offset + 112u), value.k); - tint_symbol_12(buffer, (offset + 128u), value.l); - tint_symbol_13(buffer, (offset + 144u), value.m); - tint_symbol_14(buffer, (offset + 160u), value.n); - tint_symbol_15(buffer, (offset + 192u), value.o); - tint_symbol_16(buffer, (offset + 224u), value.p); - tint_symbol_17(buffer, (offset + 256u), value.q); - tint_symbol_18(buffer, (offset + 304u), value.r); - tint_symbol_19(buffer, (offset + 352u), value.s); - tint_symbol_20(buffer, (offset + 384u), value.t); - tint_symbol_21(buffer, (offset + 448u), value.u); - tint_symbol_22(buffer, (offset + 512u), value.v); + tint_symbol_1(buffer, (offset + 0u), value.scalar_f32); + tint_symbol_2(buffer, (offset + 4u), value.scalar_i32); + tint_symbol_3(buffer, (offset + 8u), value.scalar_u32); + tint_symbol_4(buffer, (offset + 12u), value.scalar_f16); + tint_symbol_5(buffer, (offset + 16u), value.vec2_f32); + tint_symbol_6(buffer, (offset + 24u), value.vec2_i32); + tint_symbol_7(buffer, (offset + 32u), value.vec2_u32); + tint_symbol_8(buffer, (offset + 40u), value.vec2_f16); + tint_symbol_9(buffer, (offset + 48u), value.vec3_f32); + tint_symbol_10(buffer, (offset + 64u), value.vec3_i32); + tint_symbol_11(buffer, (offset + 80u), value.vec3_u32); + tint_symbol_12(buffer, (offset + 96u), value.vec3_f16); + tint_symbol_13(buffer, (offset + 112u), value.vec4_f32); + tint_symbol_14(buffer, (offset + 128u), value.vec4_i32); + tint_symbol_15(buffer, (offset + 144u), value.vec4_u32); + tint_symbol_16(buffer, (offset + 160u), value.vec4_f16); + tint_symbol_17(buffer, (offset + 168u), value.mat2x2_f32); + tint_symbol_18(buffer, (offset + 192u), value.mat2x3_f32); + tint_symbol_19(buffer, (offset + 224u), value.mat2x4_f32); + tint_symbol_20(buffer, (offset + 256u), value.mat3x2_f32); + tint_symbol_21(buffer, (offset + 288u), value.mat3x3_f32); + tint_symbol_22(buffer, (offset + 336u), value.mat3x4_f32); + tint_symbol_23(buffer, (offset + 384u), value.mat4x2_f32); + tint_symbol_24(buffer, (offset + 416u), value.mat4x3_f32); + tint_symbol_25(buffer, (offset + 480u), value.mat4x4_f32); + tint_symbol_26(buffer, (offset + 544u), value.mat2x2_f16); + tint_symbol_27(buffer, (offset + 552u), value.mat2x3_f16); + tint_symbol_28(buffer, (offset + 568u), value.mat2x4_f16); + tint_symbol_29(buffer, (offset + 584u), value.mat3x2_f16); + tint_symbol_30(buffer, (offset + 600u), value.mat3x3_f16); + tint_symbol_31(buffer, (offset + 624u), value.mat3x4_f16); + tint_symbol_32(buffer, (offset + 648u), value.mat4x2_f16); + tint_symbol_33(buffer, (offset + 664u), value.mat4x3_f16); + tint_symbol_34(buffer, (offset + 696u), value.mat4x4_f16); + tint_symbol_35(buffer, (offset + 736u), value.arr2_vec3_f32); + tint_symbol_36(buffer, (offset + 768u), value.arr2_mat4x2_f16); } @compute @workgroup_size(1) @@ -1773,6 +2798,8 @@ fn main() { TEST_F(DecomposeMemoryAccessTest, StoreStructure_OutOfOrder) { auto* src = R"( +enable f16; + @compute @workgroup_size(1) fn main() { sb = SB(); @@ -1781,152 +2808,255 @@ fn main() { @group(0) @binding(0) var sb : SB; struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, }; )"; auto* expect = R"( -@internal(intrinsic_store_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : i32) - -@internal(intrinsic_store_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : u32) +enable f16; @internal(intrinsic_store_storage_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f32) +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f32) -@internal(intrinsic_store_storage_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +@internal(intrinsic_store_storage_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : i32) -@internal(intrinsic_store_storage_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +@internal(intrinsic_store_storage_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : u32) + +@internal(intrinsic_store_storage_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : f16) @internal(intrinsic_store_storage_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) -@internal(intrinsic_store_storage_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) +@internal(intrinsic_store_storage_vec2_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) -@internal(intrinsic_store_storage_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) +@internal(intrinsic_store_storage_vec2_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) + +@internal(intrinsic_store_storage_vec2_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec2) @internal(intrinsic_store_storage_vec3_f32) @internal(disable_validation__function_has_no_body) fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) -@internal(intrinsic_store_storage_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +@internal(intrinsic_store_storage_vec3_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) -@internal(intrinsic_store_storage_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +@internal(intrinsic_store_storage_vec3_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) + +@internal(intrinsic_store_storage_vec3_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec3) @internal(intrinsic_store_storage_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { - tint_symbol_6(buffer, (offset + 0u), value[0u]); - tint_symbol_6(buffer, (offset + 8u), value[1u]); +@internal(intrinsic_store_storage_vec4_i32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +@internal(intrinsic_store_storage_vec4_u32) @internal(disable_validation__function_has_no_body) +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +@internal(intrinsic_store_storage_vec4_f16) @internal(disable_validation__function_has_no_body) +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : vec4) + +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { + tint_symbol_5(buffer, (offset + 0u), value[0u]); + tint_symbol_5(buffer, (offset + 8u), value[1u]); } -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { tint_symbol_9(buffer, (offset + 0u), value[0u]); tint_symbol_9(buffer, (offset + 16u), value[1u]); } -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { - tint_symbol_12(buffer, (offset + 0u), value[0u]); - tint_symbol_12(buffer, (offset + 16u), value[1u]); +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { + tint_symbol_13(buffer, (offset + 0u), value[0u]); + tint_symbol_13(buffer, (offset + 16u), value[1u]); } -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { - tint_symbol_6(buffer, (offset + 0u), value[0u]); - tint_symbol_6(buffer, (offset + 8u), value[1u]); - tint_symbol_6(buffer, (offset + 16u), value[2u]); +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { + tint_symbol_5(buffer, (offset + 0u), value[0u]); + tint_symbol_5(buffer, (offset + 8u), value[1u]); + tint_symbol_5(buffer, (offset + 16u), value[2u]); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { tint_symbol_9(buffer, (offset + 0u), value[0u]); tint_symbol_9(buffer, (offset + 16u), value[1u]); tint_symbol_9(buffer, (offset + 32u), value[2u]); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { - tint_symbol_12(buffer, (offset + 0u), value[0u]); - tint_symbol_12(buffer, (offset + 16u), value[1u]); - tint_symbol_12(buffer, (offset + 32u), value[2u]); +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { + tint_symbol_13(buffer, (offset + 0u), value[0u]); + tint_symbol_13(buffer, (offset + 16u), value[1u]); + tint_symbol_13(buffer, (offset + 32u), value[2u]); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { - tint_symbol_6(buffer, (offset + 0u), value[0u]); - tint_symbol_6(buffer, (offset + 8u), value[1u]); - tint_symbol_6(buffer, (offset + 16u), value[2u]); - tint_symbol_6(buffer, (offset + 24u), value[3u]); +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { + tint_symbol_5(buffer, (offset + 0u), value[0u]); + tint_symbol_5(buffer, (offset + 8u), value[1u]); + tint_symbol_5(buffer, (offset + 16u), value[2u]); + tint_symbol_5(buffer, (offset + 24u), value[3u]); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { tint_symbol_9(buffer, (offset + 0u), value[0u]); tint_symbol_9(buffer, (offset + 16u), value[1u]); tint_symbol_9(buffer, (offset + 32u), value[2u]); tint_symbol_9(buffer, (offset + 48u), value[3u]); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { - tint_symbol_12(buffer, (offset + 0u), value[0u]); - tint_symbol_12(buffer, (offset + 16u), value[1u]); - tint_symbol_12(buffer, (offset + 32u), value[2u]); - tint_symbol_12(buffer, (offset + 48u), value[3u]); +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { + tint_symbol_13(buffer, (offset + 0u), value[0u]); + tint_symbol_13(buffer, (offset + 16u), value[1u]); + tint_symbol_13(buffer, (offset + 32u), value[2u]); + tint_symbol_13(buffer, (offset + 48u), value[3u]); } -fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x2) { + tint_symbol_8(buffer, (offset + 0u), value[0u]); + tint_symbol_8(buffer, (offset + 4u), value[1u]); +} + +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x3) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 8u), value[1u]); +} + +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat2x4) { + tint_symbol_16(buffer, (offset + 0u), value[0u]); + tint_symbol_16(buffer, (offset + 8u), value[1u]); +} + +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x2) { + tint_symbol_8(buffer, (offset + 0u), value[0u]); + tint_symbol_8(buffer, (offset + 4u), value[1u]); + tint_symbol_8(buffer, (offset + 8u), value[2u]); +} + +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x3) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 8u), value[1u]); + tint_symbol_12(buffer, (offset + 16u), value[2u]); +} + +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat3x4) { + tint_symbol_16(buffer, (offset + 0u), value[0u]); + tint_symbol_16(buffer, (offset + 8u), value[1u]); + tint_symbol_16(buffer, (offset + 16u), value[2u]); +} + +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x2) { + tint_symbol_8(buffer, (offset + 0u), value[0u]); + tint_symbol_8(buffer, (offset + 4u), value[1u]); + tint_symbol_8(buffer, (offset + 8u), value[2u]); + tint_symbol_8(buffer, (offset + 12u), value[3u]); +} + +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x3) { + tint_symbol_12(buffer, (offset + 0u), value[0u]); + tint_symbol_12(buffer, (offset + 8u), value[1u]); + tint_symbol_12(buffer, (offset + 16u), value[2u]); + tint_symbol_12(buffer, (offset + 24u), value[3u]); +} + +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : mat4x4) { + tint_symbol_16(buffer, (offset + 0u), value[0u]); + tint_symbol_16(buffer, (offset + 8u), value[1u]); + tint_symbol_16(buffer, (offset + 16u), value[2u]); + tint_symbol_16(buffer, (offset + 24u), value[3u]); +} + +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { var array = value; + for(var i = 0u; (i < 2u); i = (i + 1u)) { + tint_symbol_9(buffer, (offset + (i * 16u)), array[i]); + } +} + +fn tint_symbol_36(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : array, 2u>) { + var array_1 = value; for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { - tint_symbol_9(buffer, (offset + (i_1 * 16u)), array[i_1]); + tint_symbol_32(buffer, (offset + (i_1 * 16u)), array_1[i_1]); } } fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32, value : SB) { - tint_symbol_1(buffer, (offset + 0u), value.a); - tint_symbol_2(buffer, (offset + 4u), value.b); - tint_symbol_3(buffer, (offset + 8u), value.c); - tint_symbol_4(buffer, (offset + 16u), value.d); - tint_symbol_5(buffer, (offset + 24u), value.e); - tint_symbol_6(buffer, (offset + 32u), value.f); - tint_symbol_7(buffer, (offset + 48u), value.g); - tint_symbol_8(buffer, (offset + 64u), value.h); - tint_symbol_9(buffer, (offset + 80u), value.i); - tint_symbol_10(buffer, (offset + 96u), value.j); - tint_symbol_11(buffer, (offset + 112u), value.k); - tint_symbol_12(buffer, (offset + 128u), value.l); - tint_symbol_13(buffer, (offset + 144u), value.m); - tint_symbol_14(buffer, (offset + 160u), value.n); - tint_symbol_15(buffer, (offset + 192u), value.o); - tint_symbol_16(buffer, (offset + 224u), value.p); - tint_symbol_17(buffer, (offset + 256u), value.q); - tint_symbol_18(buffer, (offset + 304u), value.r); - tint_symbol_19(buffer, (offset + 352u), value.s); - tint_symbol_20(buffer, (offset + 384u), value.t); - tint_symbol_21(buffer, (offset + 448u), value.u); - tint_symbol_22(buffer, (offset + 512u), value.v); + tint_symbol_1(buffer, (offset + 0u), value.scalar_f32); + tint_symbol_2(buffer, (offset + 4u), value.scalar_i32); + tint_symbol_3(buffer, (offset + 8u), value.scalar_u32); + tint_symbol_4(buffer, (offset + 12u), value.scalar_f16); + tint_symbol_5(buffer, (offset + 16u), value.vec2_f32); + tint_symbol_6(buffer, (offset + 24u), value.vec2_i32); + tint_symbol_7(buffer, (offset + 32u), value.vec2_u32); + tint_symbol_8(buffer, (offset + 40u), value.vec2_f16); + tint_symbol_9(buffer, (offset + 48u), value.vec3_f32); + tint_symbol_10(buffer, (offset + 64u), value.vec3_i32); + tint_symbol_11(buffer, (offset + 80u), value.vec3_u32); + tint_symbol_12(buffer, (offset + 96u), value.vec3_f16); + tint_symbol_13(buffer, (offset + 112u), value.vec4_f32); + tint_symbol_14(buffer, (offset + 128u), value.vec4_i32); + tint_symbol_15(buffer, (offset + 144u), value.vec4_u32); + tint_symbol_16(buffer, (offset + 160u), value.vec4_f16); + tint_symbol_17(buffer, (offset + 168u), value.mat2x2_f32); + tint_symbol_18(buffer, (offset + 192u), value.mat2x3_f32); + tint_symbol_19(buffer, (offset + 224u), value.mat2x4_f32); + tint_symbol_20(buffer, (offset + 256u), value.mat3x2_f32); + tint_symbol_21(buffer, (offset + 288u), value.mat3x3_f32); + tint_symbol_22(buffer, (offset + 336u), value.mat3x4_f32); + tint_symbol_23(buffer, (offset + 384u), value.mat4x2_f32); + tint_symbol_24(buffer, (offset + 416u), value.mat4x3_f32); + tint_symbol_25(buffer, (offset + 480u), value.mat4x4_f32); + tint_symbol_26(buffer, (offset + 544u), value.mat2x2_f16); + tint_symbol_27(buffer, (offset + 552u), value.mat2x3_f16); + tint_symbol_28(buffer, (offset + 568u), value.mat2x4_f16); + tint_symbol_29(buffer, (offset + 584u), value.mat3x2_f16); + tint_symbol_30(buffer, (offset + 600u), value.mat3x3_f16); + tint_symbol_31(buffer, (offset + 624u), value.mat3x4_f16); + tint_symbol_32(buffer, (offset + 648u), value.mat4x2_f16); + tint_symbol_33(buffer, (offset + 664u), value.mat4x3_f16); + tint_symbol_34(buffer, (offset + 696u), value.mat4x4_f16); + tint_symbol_35(buffer, (offset + 736u), value.arr2_vec3_f32); + tint_symbol_36(buffer, (offset + 768u), value.arr2_mat4x2_f16); } @compute @workgroup_size(1) @@ -1937,28 +3067,42 @@ fn main() { @group(0) @binding(0) var sb : SB; struct SB { - a : i32, - b : u32, - c : f32, - d : vec2, - e : vec2, - f : vec2, - g : vec3, - h : vec3, - i : vec3, - j : vec4, - k : vec4, - l : vec4, - m : mat2x2, - n : mat2x3, - o : mat2x4, - p : mat3x2, - q : mat3x3, - r : mat3x4, - s : mat4x2, - t : mat4x3, - u : mat4x4, - v : array, 2>, + scalar_f32 : f32, + scalar_i32 : i32, + scalar_u32 : u32, + scalar_f16 : f16, + vec2_f32 : vec2, + vec2_i32 : vec2, + vec2_u32 : vec2, + vec2_f16 : vec2, + vec3_f32 : vec3, + vec3_i32 : vec3, + vec3_u32 : vec3, + vec3_f16 : vec3, + vec4_f32 : vec4, + vec4_i32 : vec4, + vec4_u32 : vec4, + vec4_f16 : vec4, + mat2x2_f32 : mat2x2, + mat2x3_f32 : mat2x3, + mat2x4_f32 : mat2x4, + mat3x2_f32 : mat3x2, + mat3x3_f32 : mat3x3, + mat3x4_f32 : mat3x4, + mat4x2_f32 : mat4x2, + mat4x3_f32 : mat4x3, + mat4x4_f32 : mat4x4, + mat2x2_f16 : mat2x2, + mat2x3_f16 : mat2x3, + mat2x4_f16 : mat2x4, + mat3x2_f16 : mat3x2, + mat3x3_f16 : mat3x3, + mat3x4_f16 : mat3x4, + mat4x2_f16 : mat4x2, + mat4x3_f16 : mat4x3, + mat4x4_f16 : mat4x4, + arr2_vec3_f32 : array, 2>, + arr2_mat4x2_f16 : array, 2>, } )"; diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc index 8b566fefcd..a371f245fa 100644 --- a/src/tint/transform/std140.cc +++ b/src/tint/transform/std140.cc @@ -265,8 +265,8 @@ struct Std140::State { }; /// @returns true if the given matrix needs decomposing to column vectors for std140 layout. - /// TODO(crbug.com/tint/1502): This may need adjusting for `f16` matrices. - static bool MatrixNeedsDecomposing(const sem::Matrix* mat) { return mat->ColumnStride() == 8; } + /// Std140 layout require matrix stride to be 16, otherwise decomposing is needed. + static bool MatrixNeedsDecomposing(const sem::Matrix* mat) { return mat->ColumnStride() != 16; } /// ForkTypes walks the user-declared types in dependency order, forking structures that are /// used as uniform buffers which (transitively) use matrices that need std140 decomposition to @@ -474,7 +474,7 @@ struct Std140::State { // natural size for the matrix. This extra padding needs to be // applied to the last column vector. attributes.Push( - b.MemberSize(AInt(size - mat->ColumnType()->Size() * (num_columns - 1)))); + b.MemberSize(AInt(size - mat->ColumnType()->Align() * (num_columns - 1)))); } // Build the member @@ -645,7 +645,8 @@ struct Std140::State { return "mat" + std::to_string(mat->columns()) + "x" + std::to_string(mat->rows()) + "_" + ConvertSuffix(mat->type()); }, - [&](const sem::F32*) { return "f32"; }, + [&](const sem::F32*) { return "f32"; }, // + [&](const sem::F16*) { return "f16"; }, [&](Default) { TINT_ICE(Transform, b.Diagnostics()) << "unhandled type for conversion name: " << src->FriendlyName(ty); diff --git a/src/tint/transform/std140.h b/src/tint/transform/std140.h index 49e663daf0..769932ffb3 100644 --- a/src/tint/transform/std140.h +++ b/src/tint/transform/std140.h @@ -20,11 +20,12 @@ namespace tint::transform { /// Std140 is a transform that forks types used in the uniform address space that contain -/// `matNx2` matrices into `N`x`vec2` column vectors. Types that transitively use these -/// forked types are also forked. `var` variables will use these forked types, and -/// expressions loading from these variables will do appropriate conversions to the regular WGSL -/// types. As `matNx2` matrices are the only type that violate std140-layout, this -/// transformation is sufficient to have any WGSL structure be std140-layout conformant. +/// `matNx2` matrices into `N`x`vec2` column vectors, and `matNxM` matrices into +/// `N`x`vecM` column vectors. Types that transitively use these forked types are also forked. +/// `var` variables will use these forked types, and expressions loading from these +/// variables will do appropriate conversions to the regular WGSL types. As `matNx2` and +/// `matNxM` matrices are the only type that violate std140-layout, this transformation is +/// sufficient to have any WGSL structure be std140-layout conformant. /// /// @note This transform requires the PromoteSideEffectsToDecl transform to have been run first. class Std140 final : public Castable { diff --git a/src/tint/transform/std140_exhaustive_test.cc b/src/tint/transform/std140_exhaustive_test.cc index 01d2daebf1..f50e1c4552 100644 --- a/src/tint/transform/std140_exhaustive_test.cc +++ b/src/tint/transform/std140_exhaustive_test.cc @@ -2838,6 +2838,15 @@ INSTANTIATE_TEST_SUITE_P(, {4, 2, MatrixType::f32}, {4, 3, MatrixType::f32}, {4, 4, MatrixType::f32}, + {2, 2, MatrixType::f16}, + {2, 3, MatrixType::f16}, + {2, 4, MatrixType::f16}, + {3, 2, MatrixType::f16}, + {3, 3, MatrixType::f16}, + {3, 4, MatrixType::f16}, + {4, 2, MatrixType::f16}, + {4, 3, MatrixType::f16}, + {4, 4, MatrixType::f16}, })); using Std140Test_MatrixArray = TransformTestWithParam; @@ -4866,6 +4875,15 @@ INSTANTIATE_TEST_SUITE_P(, {4, 2, MatrixType::f32}, {4, 3, MatrixType::f32}, {4, 4, MatrixType::f32}, + {2, 2, MatrixType::f16}, + {2, 3, MatrixType::f16}, + {2, 4, MatrixType::f16}, + {3, 2, MatrixType::f16}, + {3, 3, MatrixType::f16}, + {3, 4, MatrixType::f16}, + {4, 2, MatrixType::f16}, + {4, 3, MatrixType::f16}, + {4, 4, MatrixType::f16}, })); } // namespace diff --git a/src/tint/transform/std140_f16_test.cc b/src/tint/transform/std140_f16_test.cc new file mode 100644 index 0000000000..898bb7309e --- /dev/null +++ b/src/tint/transform/std140_f16_test.cc @@ -0,0 +1,3596 @@ +// Copyright 2022 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/tint/transform/std140.h" + +#include +#include +#include + +#include "src/tint/transform/test_helper.h" +#include "src/tint/utils/string.h" + +namespace tint::transform { +namespace { + +using Std140Test_F16 = TransformTest; + +TEST_F(Std140Test_F16, StructMatricesUniform) { + auto* src = R"( +enable f16; + +struct S2x2F16 { + m : mat2x2, +} +struct S3x2F16 { + m : mat3x2, +} +struct S4x2F16 { + m : mat4x2, +} +struct S2x3F16 { + m : mat2x3, +} +struct S3x3F16 { + m : mat3x3, +} +struct S4x3F16 { + m : mat4x3, +} +struct S2x4F16 { + m : mat2x4, +} +struct S3x4F16 { + m : mat3x4, +} +struct S4x4F16 { + m : mat4x4, +} + +@group(2) @binding(2) var s2x2f16 : S2x2F16; +@group(3) @binding(2) var s3x2f16 : S3x2F16; +@group(4) @binding(2) var s4x2f16 : S4x2F16; +@group(2) @binding(3) var s2x3f16 : S2x3F16; +@group(3) @binding(3) var s3x3f16 : S3x3F16; +@group(4) @binding(3) var s4x3f16 : S4x3F16; +@group(2) @binding(4) var s2x4f16 : S2x4F16; +@group(3) @binding(4) var s3x4f16 : S3x4F16; +@group(4) @binding(4) var s4x4f16 : S4x4F16; +)"; + + auto* expect = R"( +enable f16; + +struct S2x2F16 { + m : mat2x2, +} + +struct S2x2F16_std140 { + m_0 : vec2, + m_1 : vec2, +} + +struct S3x2F16 { + m : mat3x2, +} + +struct S3x2F16_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +struct S4x2F16 { + m : mat4x2, +} + +struct S4x2F16_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, + m_3 : vec2, +} + +struct S2x3F16 { + m : mat2x3, +} + +struct S2x3F16_std140 { + m_0 : vec3, + m_1 : vec3, +} + +struct S3x3F16 { + m : mat3x3, +} + +struct S3x3F16_std140 { + m_0 : vec3, + m_1 : vec3, + m_2 : vec3, +} + +struct S4x3F16 { + m : mat4x3, +} + +struct S4x3F16_std140 { + m_0 : vec3, + m_1 : vec3, + m_2 : vec3, + m_3 : vec3, +} + +struct S2x4F16 { + m : mat2x4, +} + +struct S2x4F16_std140 { + m_0 : vec4, + m_1 : vec4, +} + +struct S3x4F16 { + m : mat3x4, +} + +struct S3x4F16_std140 { + m_0 : vec4, + m_1 : vec4, + m_2 : vec4, +} + +struct S4x4F16 { + m : mat4x4, +} + +struct S4x4F16_std140 { + m_0 : vec4, + m_1 : vec4, + m_2 : vec4, + m_3 : vec4, +} + +@group(2) @binding(2) var s2x2f16 : S2x2F16_std140; + +@group(3) @binding(2) var s3x2f16 : S3x2F16_std140; + +@group(4) @binding(2) var s4x2f16 : S4x2F16_std140; + +@group(2) @binding(3) var s2x3f16 : S2x3F16_std140; + +@group(3) @binding(3) var s3x3f16 : S3x3F16_std140; + +@group(4) @binding(3) var s4x3f16 : S4x3F16_std140; + +@group(2) @binding(4) var s2x4f16 : S2x4F16_std140; + +@group(3) @binding(4) var s3x4f16 : S3x4F16_std140; + +@group(4) @binding(4) var s4x4f16 : S4x4F16_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +// In the following tests we only test `mat2x3`, and set all constant column index to 1, row +// index 0, inner array index 2, and outer array index 3. For exhaustive tests, i.e. tests on all +// matrix shape and different valid constant index, please refer to std140_exhaustive_test.cc + +TEST_F(Std140Test_F16, SingleStructMatUniform_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, CustomAlign_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + before : i32, + @align(128) + m : mat2x3, + after : i32, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +enable f16; + +struct S { + before : i32, + @align(128) + m : mat2x3, + after : i32, +} + +struct S_std140 { + before : i32, + @align(128i) + m_0 : vec3, + m_1 : vec3, + after : i32, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, CustomSizeMat_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + before : i32, + @size(128) + m : mat2x3, + after : i32, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +enable f16; + +struct S { + before : i32, + @size(128) + m : mat2x3, + after : i32, +} + +struct S_std140 { + before : i32, + m_0 : vec3, + @size(120) + m_1 : vec3, + after : i32, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, CustomAlignAndSize_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + before : i32, + @align(128) @size(128) + m : mat2x3, + after : i32, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +enable f16; + +struct S { + before : i32, + @align(128) @size(128) + m : mat2x3, + after : i32, +} + +struct S_std140 { + before : i32, + @align(128i) + m_0 : vec3, + @size(120) + m_1 : vec3, + after : i32, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatrixUsageInForLoop_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + for(var i = u32(s.m[0][0]); (i < u32(s.m[i][1])); i += u32(s.m[1][i])) { + } +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m_p0_1(p0 : u32) -> f16 { + switch(p0) { + case 0u: { + return s.m_0[1u]; + } + case 1u: { + return s.m_1[1u]; + } + default: { + return f16(); + } + } +} + +fn f() { + for(var i = u32(s.m_0[0u]); (i < u32(load_s_m_p0_1(u32(i)))); i += u32(s.m_1[i])) { + } +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadMatrix_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var m : mat2x3; + +fn f() { + let l = m; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var m : mat2x3_f16; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let l = conv_mat2x3_f16(m); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadColumn_ConstIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : mat2x3; + +fn f() { + let l = a[1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : mat2x3_f16; + +fn f() { + let l = a.col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadColumn_VariableIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : mat2x3; + +fn f() { + let I = 1; + let l = a[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : mat2x3_f16; + +fn load_a_p0(p0 : u32) -> vec3 { + switch(p0) { + case 0u: { + return a.col0; + } + case 1u: { + return a.col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadColumnSwizzle_ConstIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : mat2x3; + +fn f() { + let l = a[1].yzx; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : mat2x3_f16; + +fn f() { + let l = a.col1.yzx; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadColumnSwizzle_VariableIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : mat2x3; + +fn f() { + let I = 1; + let l = a[I].yzx; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : mat2x3_f16; + +fn load_a_p0_yzx(p0 : u32) -> vec3 { + switch(p0) { + case 0u: { + return a.col0.yzx; + } + case 1u: { + return a.col1.yzx; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_p0_yzx(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadScalar_ConstColumnIndex_ConstRowIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : mat2x3; + +fn f() { + let l = a[1][0]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : mat2x3_f16; + +fn f() { + let l = a.col1[0u]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadScalar_VariableColumnIndex_ConstRowIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : mat2x3; + +fn f() { + let I = 0; + let l = a[I][0]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : mat2x3_f16; + +fn load_a_p0_0(p0 : u32) -> f16 { + switch(p0) { + case 0u: { + return a.col0[0u]; + } + case 1u: { + return a.col1[0u]; + } + default: { + return f16(); + } + } +} + +fn f() { + let I = 0; + let l = load_a_p0_0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadScalar_ConstColumnIndex_VariableRowIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : mat2x3; + +fn f() { + let I = 0; + let l = a[1][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : mat2x3_f16; + +fn f() { + let I = 0; + let l = a.col1[I]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, MatUniform_LoadScalar_VariableColumnIndex_VariableRowIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : mat2x3; + +fn f() { + let I = 0; + let l = a[I][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : mat2x3_f16; + +fn load_a_p0_p1(p0 : u32, p1 : u32) -> f16 { + switch(p0) { + case 0u: { + return a.col0[p1]; + } + case 1u: { + return a.col1[p1]; + } + default: { + return f16(); + } + } +} + +fn f() { + let I = 0; + let l = load_a_p0_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_NameCollision_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m_1 : i32, + m : mat2x3, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +enable f16; + +struct S { + m_1 : i32, + m : mat2x3, +} + +struct S_std140 { + m_1 : i32, + m__0 : vec3, + m__1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_LoadStruct_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_S(val : S_std140) -> S { + return S(mat2x3(val.m_0, val.m_1)); +} + +fn f() { + let l = conv_S(s); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_LoadMatrix_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.m; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m() -> mat2x3 { + let s = &(s); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn f() { + let l = load_s_m(); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_LoadColumn_ConstIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.m[1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let l = s.m_1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_LoadColumn_VariableIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 0; + let l = s.m[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m_p0(p0 : u32) -> vec3 { + switch(p0) { + case 0u: { + return s.m_0; + } + case 1u: { + return s.m_1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 0; + let l = load_s_m_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_LoadScalar_ConstColumnIndex_ConstRowIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.m[1][0]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let l = s.m_1[0u]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_LoadScalar_VariableColumnIndex_ConstRowIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 0; + let l = s.m[I][0]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m_p0_0(p0 : u32) -> f16 { + switch(p0) { + case 0u: { + return s.m_0[0u]; + } + case 1u: { + return s.m_1[0u]; + } + default: { + return f16(); + } + } +} + +fn f() { + let I = 0; + let l = load_s_m_p0_0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_LoadScalar_ConstColumnIndex_VariableRowIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 0; + let l = s.m[1][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let I = 0; + let l = s.m_1[I]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructMatUniform_LoadScalar_VariableColumnIndex_VariableRowIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + m : mat2x3, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 0; + let l = s.m[I][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + m_1 : vec3, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m_p0_p1(p0 : u32, p1 : u32) -> f16 { + switch(p0) { + case 0u: { + return s.m_0[p1]; + } + case 1u: { + return s.m_1[p1]; + } + default: { + return f16(); + } + } +} + +fn f() { + let I = 0; + let l = load_s_m_p0_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_LoadArray_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn conv_S(val : S_std140) -> S { + return S(mat2x3(val.m_0, val.m_1)); +} + +fn conv_arr3_S(val : array) -> array { + var arr : array; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_S(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr3_S(a); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_LoadStruct_ConstIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn conv_S(val : S_std140) -> S { + return S(mat2x3(val.m_0, val.m_1)); +} + +fn f() { + let l = conv_S(a[2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_LoadStruct_VariableIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn conv_S(val : S_std140) -> S { + return S(mat2x3(val.m_0, val.m_1)); +} + +fn f() { + let I = 1; + let l = conv_S(a[I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_LoadMatrix_ConstArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2].m; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn load_a_2_m() -> mat2x3 { + let s = &(a[2u]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn f() { + let l = load_a_2_m(); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_LoadMatrix_VariableArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].m; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn load_a_p0_m(p0 : u32) -> mat2x3 { + let s = &(a[p0]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn f() { + let I = 1; + let l = load_a_p0_m(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayStructMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2].m[1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2u].m_1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayStructMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].m[1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].m_1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayStructMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[2].m[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn load_a_2_m_p0(p0 : u32) -> vec3 { + switch(p0) { + case 0u: { + return a[2u].m_0; + } + case 1u: { + return a[2u].m_1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_2_m_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayStructMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].m[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn load_a_p0_m_p1(p0 : u32, p1 : u32) -> vec3 { + switch(p1) { + case 0u: { + return a[p0].m_0; + } + case 1u: { + return a[p0].m_1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_p0_m_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructArrayStructMatUniform_Loads_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct Inner { + @size(64) + m : mat2x3, +} + +struct Outer { + a : array, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let J = 2; + let K = 0; + let l_a : array = a; + let l_a_1 : Outer = a[1]; + let l_a_I : Outer = a[I]; + let l_a_2_a : array = a[2].a; + let l_a_I_a : array = a[I].a; + let l_a_3_a_1 : Inner = a[3].a[1]; + let l_a_3_a_I : Inner = a[3].a[I]; + let l_a_I_a_1 : Inner = a[I].a[1]; + let l_a_I_a_J : Inner = a[I].a[J]; + let l_a_0_a_2_m : mat2x3 = a[0].a[2].m; + let l_a_0_a_I_m : mat2x3 = a[0].a[I].m; + let l_a_I_a_2_m : mat2x3 = a[I].a[2].m; + let l_a_I_a_J_m : mat2x3 = a[I].a[J].m; + let l_a_1_a_3_m_0 : vec3 = a[1].a[3].m[0]; + let l_a_I_a_J_m_K : vec3 = a[I].a[J].m[K]; + let l_a_2_a_0_m_1_0 : f16 = a[2].a[0].m[1][0]; + let l_a_I_a_J_m_K_I : f16 = a[I].a[J].m[K][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct Inner { + @size(64) + m : mat2x3, +} + +struct Inner_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +struct Outer { + a : array, +} + +struct Outer_std140 { + a : array, +} + +@group(0) @binding(0) var a : array; + +fn conv_Inner(val : Inner_std140) -> Inner { + return Inner(mat2x3(val.m_0, val.m_1)); +} + +fn conv_arr4_Inner(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_Inner(val[i]); + } + return arr; +} + +fn conv_Outer(val : Outer_std140) -> Outer { + return Outer(conv_arr4_Inner(val.a)); +} + +fn conv_arr4_Outer(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_Outer(val[i]); + } + return arr; +} + +fn load_a_0_a_2_m() -> mat2x3 { + let s = &(a[0u].a[2u]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn load_a_0_a_p0_m(p0 : u32) -> mat2x3 { + let s = &(a[0u].a[p0]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn load_a_p0_a_2_m(p0 : u32) -> mat2x3 { + let s = &(a[p0].a[2u]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn load_a_p0_a_p1_m(p0 : u32, p1 : u32) -> mat2x3 { + let s = &(a[p0].a[p1]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn load_a_p0_a_p1_m_p2(p0 : u32, p1 : u32, p2 : u32) -> vec3 { + switch(p2) { + case 0u: { + return a[p0].a[p1].m_0; + } + case 1u: { + return a[p0].a[p1].m_1; + } + default: { + return vec3(); + } + } +} + +fn load_a_p0_a_p1_m_p2_p3(p0 : u32, p1 : u32, p2 : u32, p3 : u32) -> f16 { + switch(p2) { + case 0u: { + return a[p0].a[p1].m_0[p3]; + } + case 1u: { + return a[p0].a[p1].m_1[p3]; + } + default: { + return f16(); + } + } +} + +fn f() { + let I = 1; + let J = 2; + let K = 0; + let l_a : array = conv_arr4_Outer(a); + let l_a_1 : Outer = conv_Outer(a[1u]); + let l_a_I : Outer = conv_Outer(a[I]); + let l_a_2_a : array = conv_arr4_Inner(a[2u].a); + let l_a_I_a : array = conv_arr4_Inner(a[I].a); + let l_a_3_a_1 : Inner = conv_Inner(a[3u].a[1u]); + let l_a_3_a_I : Inner = conv_Inner(a[3u].a[I]); + let l_a_I_a_1 : Inner = conv_Inner(a[I].a[1u]); + let l_a_I_a_J : Inner = conv_Inner(a[I].a[J]); + let l_a_0_a_2_m : mat2x3 = load_a_0_a_2_m(); + let l_a_0_a_I_m : mat2x3 = load_a_0_a_p0_m(u32(I)); + let l_a_I_a_2_m : mat2x3 = load_a_p0_a_2_m(u32(I)); + let l_a_I_a_J_m : mat2x3 = load_a_p0_a_p1_m(u32(I), u32(J)); + let l_a_1_a_3_m_0 : vec3 = a[1u].a[3u].m_0; + let l_a_I_a_J_m_K : vec3 = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); + let l_a_2_a_0_m_1_0 : f16 = a[2u].a[0u].m_1[0u]; + let l_a_I_a_J_m_K_I : f16 = load_a_p0_a_p1_m_p2_p3(u32(I), u32(J), u32(K), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructArrayStructMatUniform_LoadsViaPtrs_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct Inner { + @size(64) + m : mat2x3, +} + +struct Outer { + a : array, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let J = 2; + let K = 0; + let p_a = &(a); + let p_a_3 = &((*(p_a))[3]); + let p_a_I = &((*(p_a))[I]); + let p_a_3_a = &((*(p_a_3)).a); + let p_a_I_a = &((*(p_a_I)).a); + let p_a_3_a_2 = &((*(p_a_3_a))[2]); + let p_a_3_a_I = &((*(p_a_3_a))[I]); + let p_a_I_a_2 = &((*(p_a_I_a))[2]); + let p_a_I_a_J = &((*(p_a_I_a))[J]); + let p_a_3_a_2_m = &((*(p_a_3_a_2)).m); + let p_a_3_a_I_m = &((*(p_a_3_a_I)).m); + let p_a_I_a_2_m = &((*(p_a_I_a_2)).m); + let p_a_I_a_J_m = &((*(p_a_I_a_J)).m); + let p_a_3_a_2_m_1 = &((*(p_a_3_a_2_m))[1]); + let p_a_I_a_J_m_K = &((*(p_a_I_a_J_m))[K]); + let l_a : array = *(p_a); + let l_a_3 : Outer = *(p_a_3); + let l_a_I : Outer = *(p_a_I); + let l_a_3_a : array = *(p_a_3_a); + let l_a_I_a : array = *(p_a_I_a); + let l_a_3_a_2 : Inner = *(p_a_3_a_2); + let l_a_3_a_I : Inner = *(p_a_3_a_I); + let l_a_I_a_2 : Inner = *(p_a_I_a_2); + let l_a_I_a_J : Inner = *(p_a_I_a_J); + let l_a_3_a_2_m : mat2x3 = *(p_a_3_a_2_m); + let l_a_3_a_I_m : mat2x3 = *(p_a_3_a_I_m); + let l_a_I_a_2_m : mat2x3 = *(p_a_I_a_2_m); + let l_a_I_a_J_m : mat2x3 = *(p_a_I_a_J_m); + let l_a_3_a_2_m_1 : vec3 = *(p_a_3_a_2_m_1); + let l_a_I_a_J_m_K : vec3 = *(p_a_I_a_J_m_K); + let l_a_2_a_0_m_1_0 : f16 = (*(p_a_3_a_2_m_1))[0]; + let l_a_I_a_J_m_K_I : f16 = (*(p_a_I_a_J_m_K))[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct Inner { + @size(64) + m : mat2x3, +} + +struct Inner_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +struct Outer { + a : array, +} + +struct Outer_std140 { + a : array, +} + +@group(0) @binding(0) var a : array; + +fn conv_Inner(val : Inner_std140) -> Inner { + return Inner(mat2x3(val.m_0, val.m_1)); +} + +fn conv_arr4_Inner(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_Inner(val[i]); + } + return arr; +} + +fn conv_Outer(val : Outer_std140) -> Outer { + return Outer(conv_arr4_Inner(val.a)); +} + +fn conv_arr4_Outer(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_Outer(val[i]); + } + return arr; +} + +fn load_a_3_a_2_m() -> mat2x3 { + let s = &(a[3u].a[2u]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn load_a_3_a_p0_m(p0 : u32) -> mat2x3 { + let s = &(a[3u].a[p0]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn load_a_p0_a_2_m(p0 : u32) -> mat2x3 { + let s = &(a[p0].a[2u]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn load_a_p0_a_p1_m(p0 : u32, p1 : u32) -> mat2x3 { + let s = &(a[p0].a[p1]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn load_a_p0_a_p1_m_p2(p0 : u32, p1 : u32, p2 : u32) -> vec3 { + switch(p2) { + case 0u: { + return a[p0].a[p1].m_0; + } + case 1u: { + return a[p0].a[p1].m_1; + } + default: { + return vec3(); + } + } +} + +fn load_a_p0_a_p1_m_p2_p3(p0 : u32, p1 : u32, p2 : u32, p3 : u32) -> f16 { + switch(p2) { + case 0u: { + return a[p0].a[p1].m_0[p3]; + } + case 1u: { + return a[p0].a[p1].m_1[p3]; + } + default: { + return f16(); + } + } +} + +fn f() { + let I = 1; + let J = 2; + let K = 0; + let p_a = conv_arr4_Outer(a); + let p_a_3 = conv_Outer(a[3u]); + let p_a_I = conv_Outer(a[I]); + let p_a_3_a = conv_arr4_Inner(a[3u].a); + let p_a_I_a = conv_arr4_Inner(a[I].a); + let p_a_3_a_2 = conv_Inner(a[3u].a[2u]); + let p_a_3_a_I = conv_Inner(a[3u].a[I]); + let p_a_I_a_2 = conv_Inner(a[I].a[2u]); + let p_a_I_a_J = conv_Inner(a[I].a[J]); + let p_a_3_a_2_m = load_a_3_a_2_m(); + let p_a_3_a_I_m = load_a_3_a_p0_m(u32(I)); + let p_a_I_a_2_m = load_a_p0_a_2_m(u32(I)); + let p_a_I_a_J_m = load_a_p0_a_p1_m(u32(I), u32(J)); + let p_a_3_a_2_m_1 = a[3u].a[2u].m_1; + let p_a_I_a_J_m_K = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); + let l_a : array = conv_arr4_Outer(a); + let l_a_3 : Outer = conv_Outer(a[3u]); + let l_a_I : Outer = conv_Outer(a[I]); + let l_a_3_a : array = conv_arr4_Inner(a[3u].a); + let l_a_I_a : array = conv_arr4_Inner(a[I].a); + let l_a_3_a_2 : Inner = conv_Inner(a[3u].a[2u]); + let l_a_3_a_I : Inner = conv_Inner(a[3u].a[I]); + let l_a_I_a_2 : Inner = conv_Inner(a[I].a[2u]); + let l_a_I_a_J : Inner = conv_Inner(a[I].a[J]); + let l_a_3_a_2_m : mat2x3 = load_a_3_a_2_m(); + let l_a_3_a_I_m : mat2x3 = load_a_3_a_p0_m(u32(I)); + let l_a_I_a_2_m : mat2x3 = load_a_p0_a_2_m(u32(I)); + let l_a_I_a_J_m : mat2x3 = load_a_p0_a_p1_m(u32(I), u32(J)); + let l_a_3_a_2_m_1 : vec3 = a[3u].a[2u].m_1; + let l_a_I_a_J_m_K : vec3 = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); + let l_a_2_a_0_m_1_0 : f16 = a[3u].a[2u].m_1[0u]; + let l_a_I_a_J_m_K_I : f16 = load_a_p0_a_p1_m_p2_p3(u32(I), u32(J), u32(K), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_CopyArray_UniformToStorage_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var u : array; + +@group(0) @binding(1) var s : array; + +fn f() { + s = u; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var u : array; + +@group(0) @binding(1) var s : array; + +fn conv_S(val : S_std140) -> S { + return S(mat2x3(val.m_0, val.m_1)); +} + +fn conv_arr4_S(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_S(val[i]); + } + return arr; +} + +fn f() { + s = conv_arr4_S(u); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_CopyStruct_UniformToWorkgroup_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + v : vec4, + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var u : array; + +var w : array; + +fn f() { + w[0] = u[1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + v : vec4, + @size(64) + m : mat2x3, +} + +struct S_std140 { + v : vec4, + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var u : array; + +var w : array; + +fn conv_S(val : S_std140) -> S { + return S(val.v, mat2x3(val.m_0, val.m_1)); +} + +fn f() { + w[0] = conv_S(u[1u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_CopyMatrix_UniformToPrivate_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + v : vec4, + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var u : array; + +var p : array; + +fn f() { + p[2].m = u[1].m; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + v : vec4, + @size(64) + m : mat2x3, +} + +struct S_std140 { + v : vec4, + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var u : array; + +var p : array; + +fn load_u_1_m() -> mat2x3 { + let s = &(u[1u]); + return mat2x3((*(s)).m_0, (*(s)).m_1); +} + +fn f() { + p[2].m = load_u_1_m(); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_CopyColumn_UniformToStorage_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var u : array; + +@group(0) @binding(1) var s : array; + +fn f() { + s[3].m[1] = u[2].m[0]; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var u : array; + +@group(0) @binding(1) var s : array; + +fn f() { + s[3].m[1] = u[2u].m_0; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_CopyColumnSwizzle_UniformToWorkgroup_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var u : array; + +var w : array; + +fn f() { + w[3].m[1] = u[2].m[0].yzx.yzx; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + @size(64) + m : mat2x3, +} + +struct S_std140 { + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var u : array; + +var w : array; + +fn f() { + w[3].m[1] = u[2u].m_0.yzx.yzx; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayStructMatUniform_CopyScalar_UniformToPrivate_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + v : vec4, + @size(64) + m : mat2x3, +} + +@group(0) @binding(0) var u : array; + +var p : array; + +fn f() { + p[3].m[1].x = u[2].m[0].y; +} +)"; + + auto* expect = R"( +enable f16; + +struct S { + v : vec4, + @size(64) + m : mat2x3, +} + +struct S_std140 { + v : vec4, + m_0 : vec3, + @size(56) + m_1 : vec3, +} + +@group(0) @binding(0) var u : array; + +var p : array; + +fn f() { + p[3].m[1].x = u[2u].m_0[1u]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayMatUniform_LoadArray_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let l = a; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn conv_arr3_mat2x3_f16(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x3_f16(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr3_mat2x3_f16(a); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayMatUniform_LoadMatrix_ConstArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let l = a[2]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let l = conv_mat2x3_f16(a[2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayMatUniform_LoadMatrix_VariableArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let I = 1; + let l = a[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x3_f16(a[I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let l = a[2][1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2u].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let I = 1; + let l = a[I][1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let I = 1; + let l = a[2][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn load_a_2_p0(p0 : u32) -> vec3 { + switch(p0) { + case 0u: { + return a[2u].col0; + } + case 1u: { + return a[2u].col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_2_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let I = 1; + let l = a[I][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array; + +fn load_a_p0_p1(p0 : u32, p1 : u32) -> vec3 { + switch(p1) { + case 0u: { + return a[p0].col0; + } + case 1u: { + return a[p0].col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_p0_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructArrayMatUniform_LoadStruct_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn conv_arr3_mat2x3_f16(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x3_f16(val[i]); + } + return arr; +} + +fn conv_S(val : S_std140) -> S { + return S(conv_arr3_mat2x3_f16(val.a)); +} + +fn f() { + let l = conv_S(s); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructArrayMatUniform_LoadArray_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.a; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn conv_arr3_mat2x3_f16(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x3_f16(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr3_mat2x3_f16(s.a); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructArrayMatUniform_LoadMatrix_ConstArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.a[2]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let l = conv_mat2x3_f16(s.a[2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, StructArrayMatUniform_LoadMatrix_VariableArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 1; + let l = s.a[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x3_f16(s.a[I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + StructArrayMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.a[2][1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let l = s.a[2u].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + StructArrayMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 1; + let l = s.a[I][1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let I = 1; + let l = s.a[I].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + StructArrayMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 1; + let l = s.a[2][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_a_2_p0(p0 : u32) -> vec3 { + switch(p0) { + case 0u: { + return s.a[2u].col0; + } + case 1u: { + return s.a[2u].col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_s_a_2_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + StructArrayMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 1; + let l = s.a[I][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_a_p0_p1(p0 : u32, p1 : u32) -> vec3 { + switch(p1) { + case 0u: { + return s.a[p0].col0; + } + case 1u: { + return s.a[p0].col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_s_a_p0_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayArrayMatUniform_LoadArrays_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let l = a; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn conv_arr3_mat2x3_f16(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x3_f16(val[i]); + } + return arr; +} + +fn conv_arr4_arr3_mat2x3_f16(val : array, 4u>) -> array, 3u>, 4u> { + var arr : array, 3u>, 4u>; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_arr3_mat2x3_f16(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr4_arr3_mat2x3_f16(a); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayArrayMatUniform_LoadArray_ConstOuterArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let l = a[3]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn conv_arr3_mat2x3_f16(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x3_f16(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr3_mat2x3_f16(a[3u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, ArrayArrayMatUniform_LoadArray_VariableOuterArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn conv_arr3_mat2x3_f16(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x3_f16(val[i]); + } + return arr; +} + +fn f() { + let I = 1; + let l = conv_arr3_mat2x3_f16(a[I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayArrayMatUniform_LoadMatrix_ConstOuterArrayIndex_ConstInnerArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let l = a[3][2]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let l = conv_mat2x3_f16(a[3u][2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayArrayMatUniform_LoadMatrix_ConstOuterArrayIndex_VariableInnerArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[3][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x3_f16(a[3u][I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayArrayMatUniform_LoadMatrix_VariableOuterArrayIndex_ConstInnerArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[I][2]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x3_f16(a[I][2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F16, + ArrayArrayMatUniform_LoadMatrix_VariableOuterArrayIndex_VariableInnerArrayIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[I][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x3_f16(val : mat2x3_f16) -> mat2x3 { + return mat2x3(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x3_f16(a[I][I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F16, + ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_ConstInnerArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let l = a[3][2][1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn f() { + let l = a[3u][2u].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F16, + ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_ConstInnerArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[3][2][I]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn load_a_3_2_p0(p0 : u32) -> vec3 { + switch(p0) { + case 0u: { + return a[3u][2u].col0; + } + case 1u: { + return a[3u][2u].col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_3_2_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F16, + ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_VariableInnerArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[3][I][1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn f() { + let I = 1; + let l = a[3u][I].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F16, + ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_VariableInnerArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let J = 2; + let l = a[3][I][J]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn load_a_3_p0_p1(p0 : u32, p1 : u32) -> vec3 { + switch(p1) { + case 0u: { + return a[3u][p0].col0; + } + case 1u: { + return a[3u][p0].col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let J = 2; + let l = load_a_3_p0_p1(u32(I), u32(J)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F16, + ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_ConstInnerArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[I][2][1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn f() { + let I = 1; + let l = a[I][2u].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F16, + ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_ConstInnerArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let J = 2; + let l = a[I][2][J]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn load_a_p0_2_p1(p0 : u32, p1 : u32) -> vec3 { + switch(p1) { + case 0u: { + return a[p0][2u].col0; + } + case 1u: { + return a[p0][2u].col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 1; + let J = 2; + let l = load_a_p0_2_p1(u32(I), u32(J)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F16, + ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_VariableInnerArrayIndex_ConstColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let J = 2; + let l = a[I][J][1]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn f() { + let I = 1; + let J = 2; + let l = a[I][J].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F16, + ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_VariableInnerArrayIndex_VariableColumnIndex_Mat2x3F16) { + auto* src = R"( +enable f16; + +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 0; + let J = 1; + let K = 2; + let l = a[I][J][K]; +} +)"; + + auto* expect = R"( +enable f16; + +struct mat2x3_f16 { + col0 : vec3, + col1 : vec3, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn load_a_p0_p1_p2(p0 : u32, p1 : u32, p2 : u32) -> vec3 { + switch(p2) { + case 0u: { + return a[p0][p1].col0; + } + case 1u: { + return a[p0][p1].col1; + } + default: { + return vec3(); + } + } +} + +fn f() { + let I = 0; + let J = 1; + let K = 2; + let l = load_a_p0_p1_p2(u32(I), u32(J), u32(K)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +} // namespace +} // namespace tint::transform diff --git a/src/tint/transform/std140_f32_test.cc b/src/tint/transform/std140_f32_test.cc new file mode 100644 index 0000000000..b0bd46709f --- /dev/null +++ b/src/tint/transform/std140_f32_test.cc @@ -0,0 +1,3359 @@ +// Copyright 2022 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/tint/transform/std140.h" + +#include +#include +#include + +#include "src/tint/transform/test_helper.h" +#include "src/tint/utils/string.h" + +namespace tint::transform { +namespace { + +using Std140Test_F32 = TransformTest; + +TEST_F(Std140Test_F32, StructMatricesUniform) { + auto* src = R"( +struct S2x2F32 { + m : mat2x2, +} +struct S3x2F32 { + m : mat3x2, +} +struct S4x2F32 { + m : mat4x2, +} +struct S2x3F32 { + m : mat2x3, +} +struct S3x3F32 { + m : mat3x3, +} +struct S4x3F32 { + m : mat4x3, +} +struct S2x4F32 { + m : mat2x4, +} +struct S3x4F32 { + m : mat3x4, +} +struct S4x4F32 { + m : mat4x4, +} + +@group(2) @binding(2) var s2x2f32 : S2x2F32; +@group(3) @binding(2) var s3x2f32 : S3x2F32; +@group(4) @binding(2) var s4x2f32 : S4x2F32; +@group(2) @binding(3) var s2x3f32 : S2x3F32; +@group(3) @binding(3) var s3x3f32 : S3x3F32; +@group(4) @binding(3) var s4x3f32 : S4x3F32; +@group(2) @binding(4) var s2x4f32 : S2x4F32; +@group(3) @binding(4) var s3x4f32 : S3x4F32; +@group(4) @binding(4) var s4x4f32 : S4x4F32; +)"; + + auto* expect = R"( +struct S2x2F32 { + m : mat2x2, +} + +struct S2x2F32_std140 { + m_0 : vec2, + m_1 : vec2, +} + +struct S3x2F32 { + m : mat3x2, +} + +struct S3x2F32_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +struct S4x2F32 { + m : mat4x2, +} + +struct S4x2F32_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, + m_3 : vec2, +} + +struct S2x3F32 { + m : mat2x3, +} + +struct S3x3F32 { + m : mat3x3, +} + +struct S4x3F32 { + m : mat4x3, +} + +struct S2x4F32 { + m : mat2x4, +} + +struct S3x4F32 { + m : mat3x4, +} + +struct S4x4F32 { + m : mat4x4, +} + +@group(2) @binding(2) var s2x2f32 : S2x2F32_std140; + +@group(3) @binding(2) var s3x2f32 : S3x2F32_std140; + +@group(4) @binding(2) var s4x2f32 : S4x2F32_std140; + +@group(2) @binding(3) var s2x3f32 : S2x3F32; + +@group(3) @binding(3) var s3x3f32 : S3x3F32; + +@group(4) @binding(3) var s4x3f32 : S4x3F32; + +@group(2) @binding(4) var s2x4f32 : S2x4F32; + +@group(3) @binding(4) var s3x4f32 : S3x4F32; + +@group(4) @binding(4) var s4x4f32 : S4x4F32; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +// In the following tests we only test `mat2x2` for matrix used as array element type and +// `mat3x2` otherwise, and set all constant column index to 1, row index 0, inner array index +// 2, and outer array index 3. For exhaustive tests, i.e. tests on all matrix shape and different +// valid constant index, please refer to std140_exhaustive_test.cc + +TEST_F(Std140Test_F32, SingleStructMatUniform_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, CustomAlign_Mat3x2F32) { + auto* src = R"( +struct S { + before : i32, + @align(128) + m : mat3x2, + after : i32, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +struct S { + before : i32, + @align(128) + m : mat3x2, + after : i32, +} + +struct S_std140 { + before : i32, + @align(128i) + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, + after : i32, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, CustomSizeMat_Mat3x2F32) { + auto* src = R"( +struct S { + before : i32, + @size(128) + m : mat3x2, + after : i32, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +struct S { + before : i32, + @size(128) + m : mat3x2, + after : i32, +} + +struct S_std140 { + before : i32, + m_0 : vec2, + m_1 : vec2, + @size(112) + m_2 : vec2, + after : i32, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, CustomAlignAndSize_Mat3x2F32) { + auto* src = R"( +struct S { + before : i32, + @align(128) @size(128) + m : mat3x2, + after : i32, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +struct S { + before : i32, + @align(128) @size(128) + m : mat3x2, + after : i32, +} + +struct S_std140 { + before : i32, + @align(128i) + m_0 : vec2, + m_1 : vec2, + @size(112) + m_2 : vec2, + after : i32, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatrixUsageInForLoop_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + for(var i = u32(s.m[0][0]); (i < u32(s.m[i][1])); i += u32(s.m[1][i])) { + } +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m_p0_1(p0 : u32) -> f32 { + switch(p0) { + case 0u: { + return s.m_0[1u]; + } + case 1u: { + return s.m_1[1u]; + } + case 2u: { + return s.m_2[1u]; + } + default: { + return f32(); + } + } +} + +fn f() { + for(var i = u32(s.m_0[0u]); (i < u32(load_s_m_p0_1(u32(i)))); i += u32(s.m_1[i])) { + } +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadMatrix_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var m : mat3x2; + +fn f() { + let l = m; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var m : mat3x2_f32; + +fn conv_mat3x2_f32(val : mat3x2_f32) -> mat3x2 { + return mat3x2(val.col0, val.col1, val.col2); +} + +fn f() { + let l = conv_mat3x2_f32(m); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadColumn_ConstIndex_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : mat3x2; + +fn f() { + let l = a[1]; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var a : mat3x2_f32; + +fn f() { + let l = a.col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadColumn_VariableIndex_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : mat3x2; + +fn f() { + let I = 1; + let l = a[I]; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var a : mat3x2_f32; + +fn load_a_p0(p0 : u32) -> vec2 { + switch(p0) { + case 0u: { + return a.col0; + } + case 1u: { + return a.col1; + } + case 2u: { + return a.col2; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadColumnSwizzle_ConstIndex_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : mat3x2; + +fn f() { + let l = a[1].yx; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var a : mat3x2_f32; + +fn f() { + let l = a.col1.yx; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadColumnSwizzle_VariableIndex_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : mat3x2; + +fn f() { + let I = 1; + let l = a[I].yx; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var a : mat3x2_f32; + +fn load_a_p0_yx(p0 : u32) -> vec2 { + switch(p0) { + case 0u: { + return a.col0.yx; + } + case 1u: { + return a.col1.yx; + } + case 2u: { + return a.col2.yx; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_p0_yx(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadScalar_ConstColumnIndex_ConstRowIndex_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : mat3x2; + +fn f() { + let l = a[1][0]; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var a : mat3x2_f32; + +fn f() { + let l = a.col1[0u]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadScalar_VariableColumnIndex_ConstRowIndex_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : mat3x2; + +fn f() { + let I = 0; + let l = a[I][0]; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var a : mat3x2_f32; + +fn load_a_p0_0(p0 : u32) -> f32 { + switch(p0) { + case 0u: { + return a.col0[0u]; + } + case 1u: { + return a.col1[0u]; + } + case 2u: { + return a.col2[0u]; + } + default: { + return f32(); + } + } +} + +fn f() { + let I = 0; + let l = load_a_p0_0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadScalar_ConstColumnIndex_VariableRowIndex_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : mat3x2; + +fn f() { + let I = 0; + let l = a[1][I]; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var a : mat3x2_f32; + +fn f() { + let I = 0; + let l = a.col1[I]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, MatUniform_LoadScalar_VariableColumnIndex_VariableRowIndex_Mat3x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : mat3x2; + +fn f() { + let I = 0; + let l = a[I][I]; +} +)"; + + auto* expect = R"( +struct mat3x2_f32 { + col0 : vec2, + col1 : vec2, + col2 : vec2, +} + +@group(0) @binding(0) var a : mat3x2_f32; + +fn load_a_p0_p1(p0 : u32, p1 : u32) -> f32 { + switch(p0) { + case 0u: { + return a.col0[p1]; + } + case 1u: { + return a.col1[p1]; + } + case 2u: { + return a.col2[p1]; + } + default: { + return f32(); + } + } +} + +fn f() { + let I = 0; + let l = load_a_p0_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_NameCollision_Mat3x2F32) { + auto* src = R"( +struct S { + m_1 : i32, + m : mat3x2, +} + +@group(0) @binding(0) var s : S; +)"; + + auto* expect = R"( +struct S { + m_1 : i32, + m : mat3x2, +} + +struct S_std140 { + m_1 : i32, + m__0 : vec2, + m__1 : vec2, + m__2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_LoadStruct_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s; +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_S(val : S_std140) -> S { + return S(mat3x2(val.m_0, val.m_1, val.m_2)); +} + +fn f() { + let l = conv_S(s); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_LoadMatrix_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.m; +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m() -> mat3x2 { + let s = &(s); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn f() { + let l = load_s_m(); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_LoadColumn_ConstIndex_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.m[1]; +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let l = s.m_1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_LoadColumn_VariableIndex_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 0; + let l = s.m[I]; +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m_p0(p0 : u32) -> vec2 { + switch(p0) { + case 0u: { + return s.m_0; + } + case 1u: { + return s.m_1; + } + case 2u: { + return s.m_2; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 0; + let l = load_s_m_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_LoadScalar_ConstColumnIndex_ConstRowIndex_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.m[1][0]; +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let l = s.m_1[0u]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_LoadScalar_VariableColumnIndex_ConstRowIndex_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 0; + let l = s.m[I][0]; +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m_p0_0(p0 : u32) -> f32 { + switch(p0) { + case 0u: { + return s.m_0[0u]; + } + case 1u: { + return s.m_1[0u]; + } + case 2u: { + return s.m_2[0u]; + } + default: { + return f32(); + } + } +} + +fn f() { + let I = 0; + let l = load_s_m_p0_0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_LoadScalar_ConstColumnIndex_VariableRowIndex_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 0; + let l = s.m[1][I]; +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let I = 0; + let l = s.m_1[I]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructMatUniform_LoadScalar_VariableColumnIndex_VariableRowIndex_Mat3x2F32) { + auto* src = R"( +struct S { + m : mat3x2, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 0; + let l = s.m[I][I]; +} +)"; + + auto* expect = R"( +struct S { + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + m_2 : vec2, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_m_p0_p1(p0 : u32, p1 : u32) -> f32 { + switch(p0) { + case 0u: { + return s.m_0[p1]; + } + case 1u: { + return s.m_1[p1]; + } + case 2u: { + return s.m_2[p1]; + } + default: { + return f32(); + } + } +} + +fn f() { + let I = 0; + let l = load_s_m_p0_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadArray_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn conv_S(val : S_std140) -> S { + return S(mat3x2(val.m_0, val.m_1, val.m_2)); +} + +fn conv_arr3_S(val : array) -> array { + var arr : array; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_S(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr3_S(a); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadStruct_ConstIndex_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2]; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn conv_S(val : S_std140) -> S { + return S(mat3x2(val.m_0, val.m_1, val.m_2)); +} + +fn f() { + let l = conv_S(a[2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadStruct_VariableIndex_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I]; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn conv_S(val : S_std140) -> S { + return S(mat3x2(val.m_0, val.m_1, val.m_2)); +} + +fn f() { + let I = 1; + let l = conv_S(a[I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadMatrix_ConstArrayIndex_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2].m; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn load_a_2_m() -> mat3x2 { + let s = &(a[2u]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn f() { + let l = load_a_2_m(); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadMatrix_VariableArrayIndex_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].m; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn load_a_p0_m(p0 : u32) -> mat3x2 { + let s = &(a[p0]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn f() { + let I = 1; + let l = load_a_p0_m(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayStructMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2].m[1]; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2u].m_1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayStructMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].m[1]; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].m_1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayStructMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[2].m[I]; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn load_a_2_m_p0(p0 : u32) -> vec2 { + switch(p0) { + case 0u: { + return a[2u].m_0; + } + case 1u: { + return a[2u].m_1; + } + case 2u: { + return a[2u].m_2; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_2_m_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayStructMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].m[I]; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn load_a_p0_m_p1(p0 : u32, p1 : u32) -> vec2 { + switch(p1) { + case 0u: { + return a[p0].m_0; + } + case 1u: { + return a[p0].m_1; + } + case 2u: { + return a[p0].m_2; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_p0_m_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructArrayStructMatUniform_Loads_Mat3x2F32) { + auto* src = R"( +struct Inner { + @size(64) + m : mat3x2, +} + +struct Outer { + a : array, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let J = 2; + let K = 0; + let l_a : array = a; + let l_a_1 : Outer = a[1]; + let l_a_I : Outer = a[I]; + let l_a_2_a : array = a[2].a; + let l_a_I_a : array = a[I].a; + let l_a_3_a_1 : Inner = a[3].a[1]; + let l_a_3_a_I : Inner = a[3].a[I]; + let l_a_I_a_1 : Inner = a[I].a[1]; + let l_a_I_a_J : Inner = a[I].a[J]; + let l_a_0_a_2_m : mat3x2 = a[0].a[2].m; + let l_a_0_a_I_m : mat3x2 = a[0].a[I].m; + let l_a_I_a_2_m : mat3x2 = a[I].a[2].m; + let l_a_I_a_J_m : mat3x2 = a[I].a[J].m; + let l_a_1_a_3_m_0 : vec2 = a[1].a[3].m[0]; + let l_a_I_a_J_m_K : vec2 = a[I].a[J].m[K]; + let l_a_2_a_0_m_1_0 : f32 = a[2].a[0].m[1][0]; + let l_a_I_a_J_m_K_I : f32 = a[I].a[J].m[K][I]; +} +)"; + + auto* expect = R"( +struct Inner { + @size(64) + m : mat3x2, +} + +struct Inner_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +struct Outer { + a : array, +} + +struct Outer_std140 { + a : array, +} + +@group(0) @binding(0) var a : array; + +fn conv_Inner(val : Inner_std140) -> Inner { + return Inner(mat3x2(val.m_0, val.m_1, val.m_2)); +} + +fn conv_arr4_Inner(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_Inner(val[i]); + } + return arr; +} + +fn conv_Outer(val : Outer_std140) -> Outer { + return Outer(conv_arr4_Inner(val.a)); +} + +fn conv_arr4_Outer(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_Outer(val[i]); + } + return arr; +} + +fn load_a_0_a_2_m() -> mat3x2 { + let s = &(a[0u].a[2u]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn load_a_0_a_p0_m(p0 : u32) -> mat3x2 { + let s = &(a[0u].a[p0]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn load_a_p0_a_2_m(p0 : u32) -> mat3x2 { + let s = &(a[p0].a[2u]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn load_a_p0_a_p1_m(p0 : u32, p1 : u32) -> mat3x2 { + let s = &(a[p0].a[p1]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn load_a_p0_a_p1_m_p2(p0 : u32, p1 : u32, p2 : u32) -> vec2 { + switch(p2) { + case 0u: { + return a[p0].a[p1].m_0; + } + case 1u: { + return a[p0].a[p1].m_1; + } + case 2u: { + return a[p0].a[p1].m_2; + } + default: { + return vec2(); + } + } +} + +fn load_a_p0_a_p1_m_p2_p3(p0 : u32, p1 : u32, p2 : u32, p3 : u32) -> f32 { + switch(p2) { + case 0u: { + return a[p0].a[p1].m_0[p3]; + } + case 1u: { + return a[p0].a[p1].m_1[p3]; + } + case 2u: { + return a[p0].a[p1].m_2[p3]; + } + default: { + return f32(); + } + } +} + +fn f() { + let I = 1; + let J = 2; + let K = 0; + let l_a : array = conv_arr4_Outer(a); + let l_a_1 : Outer = conv_Outer(a[1u]); + let l_a_I : Outer = conv_Outer(a[I]); + let l_a_2_a : array = conv_arr4_Inner(a[2u].a); + let l_a_I_a : array = conv_arr4_Inner(a[I].a); + let l_a_3_a_1 : Inner = conv_Inner(a[3u].a[1u]); + let l_a_3_a_I : Inner = conv_Inner(a[3u].a[I]); + let l_a_I_a_1 : Inner = conv_Inner(a[I].a[1u]); + let l_a_I_a_J : Inner = conv_Inner(a[I].a[J]); + let l_a_0_a_2_m : mat3x2 = load_a_0_a_2_m(); + let l_a_0_a_I_m : mat3x2 = load_a_0_a_p0_m(u32(I)); + let l_a_I_a_2_m : mat3x2 = load_a_p0_a_2_m(u32(I)); + let l_a_I_a_J_m : mat3x2 = load_a_p0_a_p1_m(u32(I), u32(J)); + let l_a_1_a_3_m_0 : vec2 = a[1u].a[3u].m_0; + let l_a_I_a_J_m_K : vec2 = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); + let l_a_2_a_0_m_1_0 : f32 = a[2u].a[0u].m_1[0u]; + let l_a_I_a_J_m_K_I : f32 = load_a_p0_a_p1_m_p2_p3(u32(I), u32(J), u32(K), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructArrayStructMatUniform_LoadsViaPtrs_Mat3x2F32) { + auto* src = R"( +struct Inner { + @size(64) + m : mat3x2, +} + +struct Outer { + a : array, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let J = 2; + let K = 0; + let p_a = &(a); + let p_a_3 = &((*(p_a))[3]); + let p_a_I = &((*(p_a))[I]); + let p_a_3_a = &((*(p_a_3)).a); + let p_a_I_a = &((*(p_a_I)).a); + let p_a_3_a_2 = &((*(p_a_3_a))[2]); + let p_a_3_a_I = &((*(p_a_3_a))[I]); + let p_a_I_a_2 = &((*(p_a_I_a))[2]); + let p_a_I_a_J = &((*(p_a_I_a))[J]); + let p_a_3_a_2_m = &((*(p_a_3_a_2)).m); + let p_a_3_a_I_m = &((*(p_a_3_a_I)).m); + let p_a_I_a_2_m = &((*(p_a_I_a_2)).m); + let p_a_I_a_J_m = &((*(p_a_I_a_J)).m); + let p_a_3_a_2_m_1 = &((*(p_a_3_a_2_m))[1]); + let p_a_I_a_J_m_K = &((*(p_a_I_a_J_m))[K]); + let l_a : array = *(p_a); + let l_a_3 : Outer = *(p_a_3); + let l_a_I : Outer = *(p_a_I); + let l_a_3_a : array = *(p_a_3_a); + let l_a_I_a : array = *(p_a_I_a); + let l_a_3_a_2 : Inner = *(p_a_3_a_2); + let l_a_3_a_I : Inner = *(p_a_3_a_I); + let l_a_I_a_2 : Inner = *(p_a_I_a_2); + let l_a_I_a_J : Inner = *(p_a_I_a_J); + let l_a_3_a_2_m : mat3x2 = *(p_a_3_a_2_m); + let l_a_3_a_I_m : mat3x2 = *(p_a_3_a_I_m); + let l_a_I_a_2_m : mat3x2 = *(p_a_I_a_2_m); + let l_a_I_a_J_m : mat3x2 = *(p_a_I_a_J_m); + let l_a_3_a_2_m_1 : vec2 = *(p_a_3_a_2_m_1); + let l_a_I_a_J_m_K : vec2 = *(p_a_I_a_J_m_K); + let l_a_2_a_0_m_1_0 : f32 = (*(p_a_3_a_2_m_1))[0]; + let l_a_I_a_J_m_K_I : f32 = (*(p_a_I_a_J_m_K))[I]; +} +)"; + + auto* expect = R"( +struct Inner { + @size(64) + m : mat3x2, +} + +struct Inner_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +struct Outer { + a : array, +} + +struct Outer_std140 { + a : array, +} + +@group(0) @binding(0) var a : array; + +fn conv_Inner(val : Inner_std140) -> Inner { + return Inner(mat3x2(val.m_0, val.m_1, val.m_2)); +} + +fn conv_arr4_Inner(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_Inner(val[i]); + } + return arr; +} + +fn conv_Outer(val : Outer_std140) -> Outer { + return Outer(conv_arr4_Inner(val.a)); +} + +fn conv_arr4_Outer(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_Outer(val[i]); + } + return arr; +} + +fn load_a_3_a_2_m() -> mat3x2 { + let s = &(a[3u].a[2u]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn load_a_3_a_p0_m(p0 : u32) -> mat3x2 { + let s = &(a[3u].a[p0]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn load_a_p0_a_2_m(p0 : u32) -> mat3x2 { + let s = &(a[p0].a[2u]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn load_a_p0_a_p1_m(p0 : u32, p1 : u32) -> mat3x2 { + let s = &(a[p0].a[p1]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn load_a_p0_a_p1_m_p2(p0 : u32, p1 : u32, p2 : u32) -> vec2 { + switch(p2) { + case 0u: { + return a[p0].a[p1].m_0; + } + case 1u: { + return a[p0].a[p1].m_1; + } + case 2u: { + return a[p0].a[p1].m_2; + } + default: { + return vec2(); + } + } +} + +fn load_a_p0_a_p1_m_p2_p3(p0 : u32, p1 : u32, p2 : u32, p3 : u32) -> f32 { + switch(p2) { + case 0u: { + return a[p0].a[p1].m_0[p3]; + } + case 1u: { + return a[p0].a[p1].m_1[p3]; + } + case 2u: { + return a[p0].a[p1].m_2[p3]; + } + default: { + return f32(); + } + } +} + +fn f() { + let I = 1; + let J = 2; + let K = 0; + let p_a = conv_arr4_Outer(a); + let p_a_3 = conv_Outer(a[3u]); + let p_a_I = conv_Outer(a[I]); + let p_a_3_a = conv_arr4_Inner(a[3u].a); + let p_a_I_a = conv_arr4_Inner(a[I].a); + let p_a_3_a_2 = conv_Inner(a[3u].a[2u]); + let p_a_3_a_I = conv_Inner(a[3u].a[I]); + let p_a_I_a_2 = conv_Inner(a[I].a[2u]); + let p_a_I_a_J = conv_Inner(a[I].a[J]); + let p_a_3_a_2_m = load_a_3_a_2_m(); + let p_a_3_a_I_m = load_a_3_a_p0_m(u32(I)); + let p_a_I_a_2_m = load_a_p0_a_2_m(u32(I)); + let p_a_I_a_J_m = load_a_p0_a_p1_m(u32(I), u32(J)); + let p_a_3_a_2_m_1 = a[3u].a[2u].m_1; + let p_a_I_a_J_m_K = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); + let l_a : array = conv_arr4_Outer(a); + let l_a_3 : Outer = conv_Outer(a[3u]); + let l_a_I : Outer = conv_Outer(a[I]); + let l_a_3_a : array = conv_arr4_Inner(a[3u].a); + let l_a_I_a : array = conv_arr4_Inner(a[I].a); + let l_a_3_a_2 : Inner = conv_Inner(a[3u].a[2u]); + let l_a_3_a_I : Inner = conv_Inner(a[3u].a[I]); + let l_a_I_a_2 : Inner = conv_Inner(a[I].a[2u]); + let l_a_I_a_J : Inner = conv_Inner(a[I].a[J]); + let l_a_3_a_2_m : mat3x2 = load_a_3_a_2_m(); + let l_a_3_a_I_m : mat3x2 = load_a_3_a_p0_m(u32(I)); + let l_a_I_a_2_m : mat3x2 = load_a_p0_a_2_m(u32(I)); + let l_a_I_a_J_m : mat3x2 = load_a_p0_a_p1_m(u32(I), u32(J)); + let l_a_3_a_2_m_1 : vec2 = a[3u].a[2u].m_1; + let l_a_I_a_J_m_K : vec2 = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); + let l_a_2_a_0_m_1_0 : f32 = a[3u].a[2u].m_1[0u]; + let l_a_I_a_J_m_K_I : f32 = load_a_p0_a_p1_m_p2_p3(u32(I), u32(J), u32(K), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyArray_UniformToStorage_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var u : array; + +@group(0) @binding(1) var s : array; + +fn f() { + s = u; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var u : array; + +@group(0) @binding(1) var s : array; + +fn conv_S(val : S_std140) -> S { + return S(mat3x2(val.m_0, val.m_1, val.m_2)); +} + +fn conv_arr4_S(val : array) -> array { + var arr : array; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_S(val[i]); + } + return arr; +} + +fn f() { + s = conv_arr4_S(u); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyStruct_UniformToWorkgroup_Mat3x2F32) { + auto* src = R"( +struct S { + v : vec4, + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var u : array; + +var w : array; + +fn f() { + w[0] = u[1]; +} +)"; + + auto* expect = R"( +struct S { + v : vec4, + @size(64) + m : mat3x2, +} + +struct S_std140 { + v : vec4, + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var u : array; + +var w : array; + +fn conv_S(val : S_std140) -> S { + return S(val.v, mat3x2(val.m_0, val.m_1, val.m_2)); +} + +fn f() { + w[0] = conv_S(u[1u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyMatrix_UniformToPrivate_Mat3x2F32) { + auto* src = R"( +struct S { + v : vec4, + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var u : array; + +var p : array; + +fn f() { + p[2].m = u[1].m; +} +)"; + + auto* expect = R"( +struct S { + v : vec4, + @size(64) + m : mat3x2, +} + +struct S_std140 { + v : vec4, + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var u : array; + +var p : array; + +fn load_u_1_m() -> mat3x2 { + let s = &(u[1u]); + return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); +} + +fn f() { + p[2].m = load_u_1_m(); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyColumn_UniformToStorage_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var u : array; + +@group(0) @binding(1) var s : array; + +fn f() { + s[3].m[1] = u[2].m[0]; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var u : array; + +@group(0) @binding(1) var s : array; + +fn f() { + s[3].m[1] = u[2u].m_0; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyColumnSwizzle_UniformToWorkgroup_Mat3x2F32) { + auto* src = R"( +struct S { + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var u : array; + +var w : array; + +fn f() { + w[3].m[1] = u[2].m[0].yx.yx; +} +)"; + + auto* expect = R"( +struct S { + @size(64) + m : mat3x2, +} + +struct S_std140 { + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var u : array; + +var w : array; + +fn f() { + w[3].m[1] = u[2u].m_0.yx.yx; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyScalar_UniformToPrivate_Mat3x2F32) { + auto* src = R"( +struct S { + v : vec4, + @size(64) + m : mat3x2, +} + +@group(0) @binding(0) var u : array; + +var p : array; + +fn f() { + p[3].m[1].x = u[2].m[0].y; +} +)"; + + auto* expect = R"( +struct S { + v : vec4, + @size(64) + m : mat3x2, +} + +struct S_std140 { + v : vec4, + m_0 : vec2, + m_1 : vec2, + @size(48) + m_2 : vec2, +} + +@group(0) @binding(0) var u : array; + +var p : array; + +fn f() { + p[3].m[1].x = u[2u].m_0[1u]; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayMatUniform_LoadArray_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let l = a; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x2_f32(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr3_mat2x2_f32(a); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayMatUniform_LoadMatrix_ConstArrayIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let l = a[2]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn f() { + let l = conv_mat2x2_f32(a[2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayMatUniform_LoadMatrix_VariableArrayIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let I = 1; + let l = a[I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x2_f32(a[I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let l = a[2][1]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let l = a[2u].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let I = 1; + let l = a[I][1]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn f() { + let I = 1; + let l = a[I].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let I = 1; + let l = a[2][I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn load_a_2_p0(p0 : u32) -> vec2 { + switch(p0) { + case 0u: { + return a[2u].col0; + } + case 1u: { + return a[2u].col1; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_2_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>; + +fn f() { + let I = 1; + let l = a[I][I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array; + +fn load_a_p0_p1(p0 : u32, p1 : u32) -> vec2 { + switch(p1) { + case 0u: { + return a[p0].col0; + } + case 1u: { + return a[p0].col1; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_p0_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructArrayMatUniform_LoadStruct_Mat2x2F32) { + auto* src = R"( +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x2_f32(val[i]); + } + return arr; +} + +fn conv_S(val : S_std140) -> S { + return S(conv_arr3_mat2x2_f32(val.a)); +} + +fn f() { + let l = conv_S(s); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructArrayMatUniform_LoadArray_Mat2x2F32) { + auto* src = R"( +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.a; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x2_f32(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr3_mat2x2_f32(s.a); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructArrayMatUniform_LoadMatrix_ConstArrayIndex_Mat2x2F32) { + auto* src = R"( +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.a[2]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn f() { + let l = conv_mat2x2_f32(s.a[2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, StructArrayMatUniform_LoadMatrix_VariableArrayIndex_Mat2x2F32) { + auto* src = R"( +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 1; + let l = s.a[I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x2_f32(s.a[I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + StructArrayMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat2x2F32) { + auto* src = R"( +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let l = s.a[2][1]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let l = s.a[2u].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + StructArrayMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat2x2F32) { + auto* src = R"( +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 1; + let l = s.a[I][1]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn f() { + let I = 1; + let l = s.a[I].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + StructArrayMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat2x2F32) { + auto* src = R"( +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 1; + let l = s.a[2][I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_a_2_p0(p0 : u32) -> vec2 { + switch(p0) { + case 0u: { + return s.a[2u].col0; + } + case 1u: { + return s.a[2u].col1; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_s_a_2_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + StructArrayMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat2x2F32) { + auto* src = R"( +struct S { + a : array, 3>, +} + +@group(0) @binding(0) var s : S; + +fn f() { + let I = 1; + let l = s.a[I][I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +struct S { + a : array, 3>, +} + +struct S_std140 { + a : array, +} + +@group(0) @binding(0) var s : S_std140; + +fn load_s_a_p0_p1(p0 : u32, p1 : u32) -> vec2 { + switch(p1) { + case 0u: { + return s.a[p0].col0; + } + case 1u: { + return s.a[p0].col1; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_s_a_p0_p1(u32(I), u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayArrayMatUniform_LoadArrays_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let l = a; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x2_f32(val[i]); + } + return arr; +} + +fn conv_arr4_arr3_mat2x2_f32(val : array, 4u>) -> array, 3u>, 4u> { + var arr : array, 3u>, 4u>; + for(var i : u32; (i < 4u); i = (i + 1)) { + arr[i] = conv_arr3_mat2x2_f32(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr4_arr3_mat2x2_f32(a); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayArrayMatUniform_LoadArray_ConstOuterArrayIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let l = a[3]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x2_f32(val[i]); + } + return arr; +} + +fn f() { + let l = conv_arr3_mat2x2_f32(a[3u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, ArrayArrayMatUniform_LoadArray_VariableOuterArrayIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { + var arr : array, 3u>; + for(var i : u32; (i < 3u); i = (i + 1)) { + arr[i] = conv_mat2x2_f32(val[i]); + } + return arr; +} + +fn f() { + let I = 1; + let l = conv_arr3_mat2x2_f32(a[I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayArrayMatUniform_LoadMatrix_ConstOuterArrayIndex_ConstInnerArrayIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let l = a[3][2]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn f() { + let l = conv_mat2x2_f32(a[3u][2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayArrayMatUniform_LoadMatrix_ConstOuterArrayIndex_VariableInnerArrayIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[3][I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x2_f32(a[3u][I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayArrayMatUniform_LoadMatrix_VariableOuterArrayIndex_ConstInnerArrayIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[I][2]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x2_f32(a[I][2u]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(Std140Test_F32, + ArrayArrayMatUniform_LoadMatrix_VariableOuterArrayIndex_VariableInnerArrayIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[I][I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { + return mat2x2(val.col0, val.col1); +} + +fn f() { + let I = 1; + let l = conv_mat2x2_f32(a[I][I]); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F32, + ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_ConstInnerArrayIndex_ConstColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let l = a[3][2][1]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn f() { + let l = a[3u][2u].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F32, + ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_ConstInnerArrayIndex_VariableColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[3][2][I]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn load_a_3_2_p0(p0 : u32) -> vec2 { + switch(p0) { + case 0u: { + return a[3u][2u].col0; + } + case 1u: { + return a[3u][2u].col1; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let l = load_a_3_2_p0(u32(I)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F32, + ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_VariableInnerArrayIndex_ConstColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[3][I][1]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn f() { + let I = 1; + let l = a[3u][I].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F32, + ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_VariableInnerArrayIndex_VariableColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let J = 2; + let l = a[3][I][J]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn load_a_3_p0_p1(p0 : u32, p1 : u32) -> vec2 { + switch(p1) { + case 0u: { + return a[3u][p0].col0; + } + case 1u: { + return a[3u][p0].col1; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let J = 2; + let l = load_a_3_p0_p1(u32(I), u32(J)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F32, + ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_ConstInnerArrayIndex_ConstColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let l = a[I][2][1]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn f() { + let I = 1; + let l = a[I][2u].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F32, + ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_ConstInnerArrayIndex_VariableColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let J = 2; + let l = a[I][2][J]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn load_a_p0_2_p1(p0 : u32, p1 : u32) -> vec2 { + switch(p1) { + case 0u: { + return a[p0][2u].col0; + } + case 1u: { + return a[p0][2u].col1; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 1; + let J = 2; + let l = load_a_p0_2_p1(u32(I), u32(J)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F32, + ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_VariableInnerArrayIndex_ConstColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 1; + let J = 2; + let l = a[I][J][1]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn f() { + let I = 1; + let J = 2; + let l = a[I][J].col1; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F( + Std140Test_F32, + ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_VariableInnerArrayIndex_VariableColumnIndex_Mat2x2F32) { + auto* src = R"( +@group(0) @binding(0) var a : array, 3>, 4>; + +fn f() { + let I = 0; + let J = 1; + let K = 2; + let l = a[I][J][K]; +} +)"; + + auto* expect = R"( +struct mat2x2_f32 { + col0 : vec2, + col1 : vec2, +} + +@group(0) @binding(0) var a : array, 4u>; + +fn load_a_p0_p1_p2(p0 : u32, p1 : u32, p2 : u32) -> vec2 { + switch(p2) { + case 0u: { + return a[p0][p1].col0; + } + case 1u: { + return a[p0][p1].col1; + } + default: { + return vec2(); + } + } +} + +fn f() { + let I = 0; + let J = 1; + let K = 2; + let l = load_a_p0_p1_p2(u32(I), u32(J), u32(K)); +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +} // namespace +} // namespace tint::transform diff --git a/src/tint/transform/std140_test.cc b/src/tint/transform/std140_test.cc index 1ec2e09be4..73221bca18 100644 --- a/src/tint/transform/std140_test.cc +++ b/src/tint/transform/std140_test.cc @@ -21,6 +21,12 @@ #include "src/tint/transform/test_helper.h" #include "src/tint/utils/string.h" +// This file contains the should-run tests and a trival empty module test for Std140 transform. +// For testing transform results with clear readability, please refer to std140_f32_test.cc for f32 +// matricies and std140_f16_test.cc for f16 matricies. For exhaustive tests that run Std140 +// transform on all shape of both f32 and f16 matricies and loop on all valid literal index when +// required, please refer to std140_exhaustive_test.cc. + namespace tint::transform { namespace { @@ -96,6 +102,8 @@ using Std140TestShouldRun = TransformTestWithParam; TEST_P(Std140TestShouldRun, StructStorage) { std::string src = R"( +enable f16; + struct S { m : ${mat}, } @@ -110,6 +118,8 @@ struct S { TEST_P(Std140TestShouldRun, StructUniform) { std::string src = R"( +enable f16; + struct S { m : ${mat}, } @@ -124,6 +134,8 @@ struct S { TEST_P(Std140TestShouldRun, ArrayStorage) { std::string src = R"( +enable f16; + @group(0) @binding(0) var s : array<${mat}, 2>; )"; @@ -141,6 +153,8 @@ TEST_P(Std140TestShouldRun, ArrayUniform) { } std::string src = R"( +enable f16; + @group(0) @binding(0) var s : array<${mat}, 2>; )"; @@ -161,6 +175,15 @@ INSTANTIATE_TEST_SUITE_P(Std140TestShouldRun, {4, 2, MatrixType::f32}, {4, 3, MatrixType::f32}, {4, 4, MatrixType::f32}, + {2, 2, MatrixType::f16}, + {2, 3, MatrixType::f16}, + {2, 4, MatrixType::f16}, + {3, 2, MatrixType::f16}, + {3, 3, MatrixType::f16}, + {3, 4, MatrixType::f16}, + {4, 2, MatrixType::f16}, + {4, 3, MatrixType::f16}, + {4, 4, MatrixType::f16}, })); TEST_F(Std140Test, EmptyModule) { @@ -173,3336 +196,5 @@ TEST_F(Std140Test, EmptyModule) { EXPECT_EQ(expect, str(got)); } -using Std140Test_F32 = Std140Test; - -TEST_F(Std140Test_F32, StructMatricesUniform) { - auto* src = R"( -struct S2x2F32 { - m : mat2x2, -} -struct S3x2F32 { - m : mat3x2, -} -struct S4x2F32 { - m : mat4x2, -} -struct S2x3F32 { - m : mat2x3, -} -struct S3x3F32 { - m : mat3x3, -} -struct S4x3F32 { - m : mat4x3, -} -struct S2x4F32 { - m : mat2x4, -} -struct S3x4F32 { - m : mat3x4, -} -struct S4x4F32 { - m : mat4x4, -} - -@group(2) @binding(2) var s2x2f32 : S2x2F32; -@group(3) @binding(2) var s3x2f32 : S3x2F32; -@group(4) @binding(2) var s4x2f32 : S4x2F32; -@group(2) @binding(3) var s2x3f32 : S2x3F32; -@group(3) @binding(3) var s3x3f32 : S3x3F32; -@group(4) @binding(3) var s4x3f32 : S4x3F32; -@group(2) @binding(4) var s2x4f32 : S2x4F32; -@group(3) @binding(4) var s3x4f32 : S3x4F32; -@group(4) @binding(4) var s4x4f32 : S4x4F32; -)"; - - auto* expect = R"( -struct S2x2F32 { - m : mat2x2, -} - -struct S2x2F32_std140 { - m_0 : vec2, - m_1 : vec2, -} - -struct S3x2F32 { - m : mat3x2, -} - -struct S3x2F32_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -struct S4x2F32 { - m : mat4x2, -} - -struct S4x2F32_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, - m_3 : vec2, -} - -struct S2x3F32 { - m : mat2x3, -} - -struct S3x3F32 { - m : mat3x3, -} - -struct S4x3F32 { - m : mat4x3, -} - -struct S2x4F32 { - m : mat2x4, -} - -struct S3x4F32 { - m : mat3x4, -} - -struct S4x4F32 { - m : mat4x4, -} - -@group(2) @binding(2) var s2x2f32 : S2x2F32_std140; - -@group(3) @binding(2) var s3x2f32 : S3x2F32_std140; - -@group(4) @binding(2) var s4x2f32 : S4x2F32_std140; - -@group(2) @binding(3) var s2x3f32 : S2x3F32; - -@group(3) @binding(3) var s3x3f32 : S3x3F32; - -@group(4) @binding(3) var s4x3f32 : S4x3F32; - -@group(2) @binding(4) var s2x4f32 : S2x4F32; - -@group(3) @binding(4) var s3x4f32 : S3x4F32; - -@group(4) @binding(4) var s4x4f32 : S4x4F32; -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -// In the following tests we only test `mat2x2` for matrix used as array element type and -// `mat3x2` otherwise, and set all constant column index to 1, row index 0, inner array index -// 2, and outer array index 3. For exhaustive tests, i.e. tests on all matrix shape and different -// valid constant index, please refer to std140_exhaustive_test.cc - -TEST_F(Std140Test_F32, SingleStructMatUniform_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, CustomAlign_Mat3x2F32) { - auto* src = R"( -struct S { - before : i32, - @align(128) - m : mat3x2, - after : i32, -} - -@group(0) @binding(0) var s : S; -)"; - - auto* expect = R"( -struct S { - before : i32, - @align(128) - m : mat3x2, - after : i32, -} - -struct S_std140 { - before : i32, - @align(128i) - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, - after : i32, -} - -@group(0) @binding(0) var s : S_std140; -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, CustomSizeMat_Mat3x2F32) { - auto* src = R"( -struct S { - before : i32, - @size(128) - m : mat3x2, - after : i32, -} - -@group(0) @binding(0) var s : S; -)"; - - auto* expect = R"( -struct S { - before : i32, - @size(128) - m : mat3x2, - after : i32, -} - -struct S_std140 { - before : i32, - m_0 : vec2, - m_1 : vec2, - @size(112) - m_2 : vec2, - after : i32, -} - -@group(0) @binding(0) var s : S_std140; -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, CustomAlignAndSize_Mat3x2F32) { - auto* src = R"( -struct S { - before : i32, - @align(128) @size(128) - m : mat3x2, - after : i32, -} - -@group(0) @binding(0) var s : S; -)"; - - auto* expect = R"( -struct S { - before : i32, - @align(128) @size(128) - m : mat3x2, - after : i32, -} - -struct S_std140 { - before : i32, - @align(128i) - m_0 : vec2, - m_1 : vec2, - @size(112) - m_2 : vec2, - after : i32, -} - -@group(0) @binding(0) var s : S_std140; -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatrixUsageInForLoop_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - for(var i = u32(s.m[0][0]); (i < u32(s.m[i][1])); i += u32(s.m[1][i])) { - } -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn load_s_m_p0_1(p0 : u32) -> f32 { - switch(p0) { - case 0u: { - return s.m_0[1u]; - } - case 1u: { - return s.m_1[1u]; - } - case 2u: { - return s.m_2[1u]; - } - default: { - return f32(); - } - } -} - -fn f() { - for(var i = u32(s.m_0[0u]); (i < u32(load_s_m_p0_1(u32(i)))); i += u32(s.m_1[i])) { - } -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadMatrix_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var m : mat3x2; - -fn f() { - let l = m; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var m : mat3x2_f32; - -fn conv_mat3x2_f32(val : mat3x2_f32) -> mat3x2 { - return mat3x2(val.col0, val.col1, val.col2); -} - -fn f() { - let l = conv_mat3x2_f32(m); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadColumn_ConstIndex_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : mat3x2; - -fn f() { - let l = a[1]; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var a : mat3x2_f32; - -fn f() { - let l = a.col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadColumn_VariableIndex_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : mat3x2; - -fn f() { - let I = 1; - let l = a[I]; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var a : mat3x2_f32; - -fn load_a_p0(p0 : u32) -> vec2 { - switch(p0) { - case 0u: { - return a.col0; - } - case 1u: { - return a.col1; - } - case 2u: { - return a.col2; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_a_p0(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadColumnSwizzle_ConstIndex_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : mat3x2; - -fn f() { - let l = a[1].yx; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var a : mat3x2_f32; - -fn f() { - let l = a.col1.yx; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadColumnSwizzle_VariableIndex_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : mat3x2; - -fn f() { - let I = 1; - let l = a[I].yx; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var a : mat3x2_f32; - -fn load_a_p0_yx(p0 : u32) -> vec2 { - switch(p0) { - case 0u: { - return a.col0.yx; - } - case 1u: { - return a.col1.yx; - } - case 2u: { - return a.col2.yx; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_a_p0_yx(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadScalar_ConstColumnIndex_ConstRowIndex_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : mat3x2; - -fn f() { - let l = a[1][0]; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var a : mat3x2_f32; - -fn f() { - let l = a.col1[0u]; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadScalar_VariableColumnIndex_ConstRowIndex_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : mat3x2; - -fn f() { - let I = 0; - let l = a[I][0]; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var a : mat3x2_f32; - -fn load_a_p0_0(p0 : u32) -> f32 { - switch(p0) { - case 0u: { - return a.col0[0u]; - } - case 1u: { - return a.col1[0u]; - } - case 2u: { - return a.col2[0u]; - } - default: { - return f32(); - } - } -} - -fn f() { - let I = 0; - let l = load_a_p0_0(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadScalar_ConstColumnIndex_VariableRowIndex_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : mat3x2; - -fn f() { - let I = 0; - let l = a[1][I]; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var a : mat3x2_f32; - -fn f() { - let I = 0; - let l = a.col1[I]; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, MatUniform_LoadScalar_VariableColumnIndex_VariableRowIndex_Mat3x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : mat3x2; - -fn f() { - let I = 0; - let l = a[I][I]; -} -)"; - - auto* expect = R"( -struct mat3x2_f32 { - col0 : vec2, - col1 : vec2, - col2 : vec2, -} - -@group(0) @binding(0) var a : mat3x2_f32; - -fn load_a_p0_p1(p0 : u32, p1 : u32) -> f32 { - switch(p0) { - case 0u: { - return a.col0[p1]; - } - case 1u: { - return a.col1[p1]; - } - case 2u: { - return a.col2[p1]; - } - default: { - return f32(); - } - } -} - -fn f() { - let I = 0; - let l = load_a_p0_p1(u32(I), u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_NameCollision_Mat3x2F32) { - auto* src = R"( -struct S { - m_1 : i32, - m : mat3x2, -} - -@group(0) @binding(0) var s : S; -)"; - - auto* expect = R"( -struct S { - m_1 : i32, - m : mat3x2, -} - -struct S_std140 { - m_1 : i32, - m__0 : vec2, - m__1 : vec2, - m__2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_LoadStruct_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let l = s; -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn conv_S(val : S_std140) -> S { - return S(mat3x2(val.m_0, val.m_1, val.m_2)); -} - -fn f() { - let l = conv_S(s); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_LoadMatrix_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let l = s.m; -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn load_s_m() -> mat3x2 { - let s = &(s); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn f() { - let l = load_s_m(); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_LoadColumn_ConstIndex_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let l = s.m[1]; -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn f() { - let l = s.m_1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_LoadColumn_VariableIndex_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let I = 0; - let l = s.m[I]; -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn load_s_m_p0(p0 : u32) -> vec2 { - switch(p0) { - case 0u: { - return s.m_0; - } - case 1u: { - return s.m_1; - } - case 2u: { - return s.m_2; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 0; - let l = load_s_m_p0(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_LoadScalar_ConstColumnIndex_ConstRowIndex_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let l = s.m[1][0]; -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn f() { - let l = s.m_1[0u]; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_LoadScalar_VariableColumnIndex_ConstRowIndex_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let I = 0; - let l = s.m[I][0]; -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn load_s_m_p0_0(p0 : u32) -> f32 { - switch(p0) { - case 0u: { - return s.m_0[0u]; - } - case 1u: { - return s.m_1[0u]; - } - case 2u: { - return s.m_2[0u]; - } - default: { - return f32(); - } - } -} - -fn f() { - let I = 0; - let l = load_s_m_p0_0(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_LoadScalar_ConstColumnIndex_VariableRowIndex_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let I = 0; - let l = s.m[1][I]; -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn f() { - let I = 0; - let l = s.m_1[I]; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructMatUniform_LoadScalar_VariableColumnIndex_VariableRowIndex_Mat3x2F32) { - auto* src = R"( -struct S { - m : mat3x2, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let I = 0; - let l = s.m[I][I]; -} -)"; - - auto* expect = R"( -struct S { - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - m_2 : vec2, -} - -@group(0) @binding(0) var s : S_std140; - -fn load_s_m_p0_p1(p0 : u32, p1 : u32) -> f32 { - switch(p0) { - case 0u: { - return s.m_0[p1]; - } - case 1u: { - return s.m_1[p1]; - } - case 2u: { - return s.m_2[p1]; - } - default: { - return f32(); - } - } -} - -fn f() { - let I = 0; - let l = load_s_m_p0_p1(u32(I), u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadArray_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let l = a; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn conv_S(val : S_std140) -> S { - return S(mat3x2(val.m_0, val.m_1, val.m_2)); -} - -fn conv_arr3_S(val : array) -> array { - var arr : array; - for(var i : u32; (i < 3u); i = (i + 1)) { - arr[i] = conv_S(val[i]); - } - return arr; -} - -fn f() { - let l = conv_arr3_S(a); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadStruct_ConstIndex_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let l = a[2]; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn conv_S(val : S_std140) -> S { - return S(mat3x2(val.m_0, val.m_1, val.m_2)); -} - -fn f() { - let l = conv_S(a[2u]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadStruct_VariableIndex_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let l = a[I]; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn conv_S(val : S_std140) -> S { - return S(mat3x2(val.m_0, val.m_1, val.m_2)); -} - -fn f() { - let I = 1; - let l = conv_S(a[I]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadMatrix_ConstArrayIndex_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let l = a[2].m; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn load_a_2_m() -> mat3x2 { - let s = &(a[2u]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn f() { - let l = load_a_2_m(); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_LoadMatrix_VariableArrayIndex_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let l = a[I].m; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn load_a_p0_m(p0 : u32) -> mat3x2 { - let s = &(a[p0]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn f() { - let I = 1; - let l = load_a_p0_m(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayStructMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let l = a[2].m[1]; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let l = a[2u].m_1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayStructMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let l = a[I].m[1]; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let l = a[I].m_1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayStructMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let l = a[2].m[I]; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn load_a_2_m_p0(p0 : u32) -> vec2 { - switch(p0) { - case 0u: { - return a[2u].m_0; - } - case 1u: { - return a[2u].m_1; - } - case 2u: { - return a[2u].m_2; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_a_2_m_p0(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayStructMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let l = a[I].m[I]; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn load_a_p0_m_p1(p0 : u32, p1 : u32) -> vec2 { - switch(p1) { - case 0u: { - return a[p0].m_0; - } - case 1u: { - return a[p0].m_1; - } - case 2u: { - return a[p0].m_2; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_a_p0_m_p1(u32(I), u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructArrayStructMatUniform_Loads_Mat3x2F32) { - auto* src = R"( -struct Inner { - @size(64) - m : mat3x2, -} - -struct Outer { - a : array, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let J = 2; - let K = 0; - let l_a : array = a; - let l_a_1 : Outer = a[1]; - let l_a_I : Outer = a[I]; - let l_a_2_a : array = a[2].a; - let l_a_I_a : array = a[I].a; - let l_a_3_a_1 : Inner = a[3].a[1]; - let l_a_3_a_I : Inner = a[3].a[I]; - let l_a_I_a_1 : Inner = a[I].a[1]; - let l_a_I_a_J : Inner = a[I].a[J]; - let l_a_0_a_2_m : mat3x2 = a[0].a[2].m; - let l_a_0_a_I_m : mat3x2 = a[0].a[I].m; - let l_a_I_a_2_m : mat3x2 = a[I].a[2].m; - let l_a_I_a_J_m : mat3x2 = a[I].a[J].m; - let l_a_1_a_3_m_0 : vec2 = a[1].a[3].m[0]; - let l_a_I_a_J_m_K : vec2 = a[I].a[J].m[K]; - let l_a_2_a_0_m_1_0 : f32 = a[2].a[0].m[1][0]; - let l_a_I_a_J_m_K_I : f32 = a[I].a[J].m[K][I]; -} -)"; - - auto* expect = R"( -struct Inner { - @size(64) - m : mat3x2, -} - -struct Inner_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -struct Outer { - a : array, -} - -struct Outer_std140 { - a : array, -} - -@group(0) @binding(0) var a : array; - -fn conv_Inner(val : Inner_std140) -> Inner { - return Inner(mat3x2(val.m_0, val.m_1, val.m_2)); -} - -fn conv_arr4_Inner(val : array) -> array { - var arr : array; - for(var i : u32; (i < 4u); i = (i + 1)) { - arr[i] = conv_Inner(val[i]); - } - return arr; -} - -fn conv_Outer(val : Outer_std140) -> Outer { - return Outer(conv_arr4_Inner(val.a)); -} - -fn conv_arr4_Outer(val : array) -> array { - var arr : array; - for(var i : u32; (i < 4u); i = (i + 1)) { - arr[i] = conv_Outer(val[i]); - } - return arr; -} - -fn load_a_0_a_2_m() -> mat3x2 { - let s = &(a[0u].a[2u]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn load_a_0_a_p0_m(p0 : u32) -> mat3x2 { - let s = &(a[0u].a[p0]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn load_a_p0_a_2_m(p0 : u32) -> mat3x2 { - let s = &(a[p0].a[2u]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn load_a_p0_a_p1_m(p0 : u32, p1 : u32) -> mat3x2 { - let s = &(a[p0].a[p1]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn load_a_p0_a_p1_m_p2(p0 : u32, p1 : u32, p2 : u32) -> vec2 { - switch(p2) { - case 0u: { - return a[p0].a[p1].m_0; - } - case 1u: { - return a[p0].a[p1].m_1; - } - case 2u: { - return a[p0].a[p1].m_2; - } - default: { - return vec2(); - } - } -} - -fn load_a_p0_a_p1_m_p2_p3(p0 : u32, p1 : u32, p2 : u32, p3 : u32) -> f32 { - switch(p2) { - case 0u: { - return a[p0].a[p1].m_0[p3]; - } - case 1u: { - return a[p0].a[p1].m_1[p3]; - } - case 2u: { - return a[p0].a[p1].m_2[p3]; - } - default: { - return f32(); - } - } -} - -fn f() { - let I = 1; - let J = 2; - let K = 0; - let l_a : array = conv_arr4_Outer(a); - let l_a_1 : Outer = conv_Outer(a[1u]); - let l_a_I : Outer = conv_Outer(a[I]); - let l_a_2_a : array = conv_arr4_Inner(a[2u].a); - let l_a_I_a : array = conv_arr4_Inner(a[I].a); - let l_a_3_a_1 : Inner = conv_Inner(a[3u].a[1u]); - let l_a_3_a_I : Inner = conv_Inner(a[3u].a[I]); - let l_a_I_a_1 : Inner = conv_Inner(a[I].a[1u]); - let l_a_I_a_J : Inner = conv_Inner(a[I].a[J]); - let l_a_0_a_2_m : mat3x2 = load_a_0_a_2_m(); - let l_a_0_a_I_m : mat3x2 = load_a_0_a_p0_m(u32(I)); - let l_a_I_a_2_m : mat3x2 = load_a_p0_a_2_m(u32(I)); - let l_a_I_a_J_m : mat3x2 = load_a_p0_a_p1_m(u32(I), u32(J)); - let l_a_1_a_3_m_0 : vec2 = a[1u].a[3u].m_0; - let l_a_I_a_J_m_K : vec2 = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); - let l_a_2_a_0_m_1_0 : f32 = a[2u].a[0u].m_1[0u]; - let l_a_I_a_J_m_K_I : f32 = load_a_p0_a_p1_m_p2_p3(u32(I), u32(J), u32(K), u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructArrayStructMatUniform_LoadsViaPtrs_Mat3x2F32) { - auto* src = R"( -struct Inner { - @size(64) - m : mat3x2, -} - -struct Outer { - a : array, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let J = 2; - let K = 0; - let p_a = &(a); - let p_a_3 = &((*(p_a))[3]); - let p_a_I = &((*(p_a))[I]); - let p_a_3_a = &((*(p_a_3)).a); - let p_a_I_a = &((*(p_a_I)).a); - let p_a_3_a_2 = &((*(p_a_3_a))[2]); - let p_a_3_a_I = &((*(p_a_3_a))[I]); - let p_a_I_a_2 = &((*(p_a_I_a))[2]); - let p_a_I_a_J = &((*(p_a_I_a))[J]); - let p_a_3_a_2_m = &((*(p_a_3_a_2)).m); - let p_a_3_a_I_m = &((*(p_a_3_a_I)).m); - let p_a_I_a_2_m = &((*(p_a_I_a_2)).m); - let p_a_I_a_J_m = &((*(p_a_I_a_J)).m); - let p_a_3_a_2_m_1 = &((*(p_a_3_a_2_m))[1]); - let p_a_I_a_J_m_K = &((*(p_a_I_a_J_m))[K]); - let l_a : array = *(p_a); - let l_a_3 : Outer = *(p_a_3); - let l_a_I : Outer = *(p_a_I); - let l_a_3_a : array = *(p_a_3_a); - let l_a_I_a : array = *(p_a_I_a); - let l_a_3_a_2 : Inner = *(p_a_3_a_2); - let l_a_3_a_I : Inner = *(p_a_3_a_I); - let l_a_I_a_2 : Inner = *(p_a_I_a_2); - let l_a_I_a_J : Inner = *(p_a_I_a_J); - let l_a_3_a_2_m : mat3x2 = *(p_a_3_a_2_m); - let l_a_3_a_I_m : mat3x2 = *(p_a_3_a_I_m); - let l_a_I_a_2_m : mat3x2 = *(p_a_I_a_2_m); - let l_a_I_a_J_m : mat3x2 = *(p_a_I_a_J_m); - let l_a_3_a_2_m_1 : vec2 = *(p_a_3_a_2_m_1); - let l_a_I_a_J_m_K : vec2 = *(p_a_I_a_J_m_K); - let l_a_2_a_0_m_1_0 : f32 = (*(p_a_3_a_2_m_1))[0]; - let l_a_I_a_J_m_K_I : f32 = (*(p_a_I_a_J_m_K))[I]; -} -)"; - - auto* expect = R"( -struct Inner { - @size(64) - m : mat3x2, -} - -struct Inner_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -struct Outer { - a : array, -} - -struct Outer_std140 { - a : array, -} - -@group(0) @binding(0) var a : array; - -fn conv_Inner(val : Inner_std140) -> Inner { - return Inner(mat3x2(val.m_0, val.m_1, val.m_2)); -} - -fn conv_arr4_Inner(val : array) -> array { - var arr : array; - for(var i : u32; (i < 4u); i = (i + 1)) { - arr[i] = conv_Inner(val[i]); - } - return arr; -} - -fn conv_Outer(val : Outer_std140) -> Outer { - return Outer(conv_arr4_Inner(val.a)); -} - -fn conv_arr4_Outer(val : array) -> array { - var arr : array; - for(var i : u32; (i < 4u); i = (i + 1)) { - arr[i] = conv_Outer(val[i]); - } - return arr; -} - -fn load_a_3_a_2_m() -> mat3x2 { - let s = &(a[3u].a[2u]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn load_a_3_a_p0_m(p0 : u32) -> mat3x2 { - let s = &(a[3u].a[p0]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn load_a_p0_a_2_m(p0 : u32) -> mat3x2 { - let s = &(a[p0].a[2u]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn load_a_p0_a_p1_m(p0 : u32, p1 : u32) -> mat3x2 { - let s = &(a[p0].a[p1]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn load_a_p0_a_p1_m_p2(p0 : u32, p1 : u32, p2 : u32) -> vec2 { - switch(p2) { - case 0u: { - return a[p0].a[p1].m_0; - } - case 1u: { - return a[p0].a[p1].m_1; - } - case 2u: { - return a[p0].a[p1].m_2; - } - default: { - return vec2(); - } - } -} - -fn load_a_p0_a_p1_m_p2_p3(p0 : u32, p1 : u32, p2 : u32, p3 : u32) -> f32 { - switch(p2) { - case 0u: { - return a[p0].a[p1].m_0[p3]; - } - case 1u: { - return a[p0].a[p1].m_1[p3]; - } - case 2u: { - return a[p0].a[p1].m_2[p3]; - } - default: { - return f32(); - } - } -} - -fn f() { - let I = 1; - let J = 2; - let K = 0; - let p_a = conv_arr4_Outer(a); - let p_a_3 = conv_Outer(a[3u]); - let p_a_I = conv_Outer(a[I]); - let p_a_3_a = conv_arr4_Inner(a[3u].a); - let p_a_I_a = conv_arr4_Inner(a[I].a); - let p_a_3_a_2 = conv_Inner(a[3u].a[2u]); - let p_a_3_a_I = conv_Inner(a[3u].a[I]); - let p_a_I_a_2 = conv_Inner(a[I].a[2u]); - let p_a_I_a_J = conv_Inner(a[I].a[J]); - let p_a_3_a_2_m = load_a_3_a_2_m(); - let p_a_3_a_I_m = load_a_3_a_p0_m(u32(I)); - let p_a_I_a_2_m = load_a_p0_a_2_m(u32(I)); - let p_a_I_a_J_m = load_a_p0_a_p1_m(u32(I), u32(J)); - let p_a_3_a_2_m_1 = a[3u].a[2u].m_1; - let p_a_I_a_J_m_K = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); - let l_a : array = conv_arr4_Outer(a); - let l_a_3 : Outer = conv_Outer(a[3u]); - let l_a_I : Outer = conv_Outer(a[I]); - let l_a_3_a : array = conv_arr4_Inner(a[3u].a); - let l_a_I_a : array = conv_arr4_Inner(a[I].a); - let l_a_3_a_2 : Inner = conv_Inner(a[3u].a[2u]); - let l_a_3_a_I : Inner = conv_Inner(a[3u].a[I]); - let l_a_I_a_2 : Inner = conv_Inner(a[I].a[2u]); - let l_a_I_a_J : Inner = conv_Inner(a[I].a[J]); - let l_a_3_a_2_m : mat3x2 = load_a_3_a_2_m(); - let l_a_3_a_I_m : mat3x2 = load_a_3_a_p0_m(u32(I)); - let l_a_I_a_2_m : mat3x2 = load_a_p0_a_2_m(u32(I)); - let l_a_I_a_J_m : mat3x2 = load_a_p0_a_p1_m(u32(I), u32(J)); - let l_a_3_a_2_m_1 : vec2 = a[3u].a[2u].m_1; - let l_a_I_a_J_m_K : vec2 = load_a_p0_a_p1_m_p2(u32(I), u32(J), u32(K)); - let l_a_2_a_0_m_1_0 : f32 = a[3u].a[2u].m_1[0u]; - let l_a_I_a_J_m_K_I : f32 = load_a_p0_a_p1_m_p2_p3(u32(I), u32(J), u32(K), u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyArray_UniformToStorage_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var u : array; - -@group(0) @binding(1) var s : array; - -fn f() { - s = u; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var u : array; - -@group(0) @binding(1) var s : array; - -fn conv_S(val : S_std140) -> S { - return S(mat3x2(val.m_0, val.m_1, val.m_2)); -} - -fn conv_arr4_S(val : array) -> array { - var arr : array; - for(var i : u32; (i < 4u); i = (i + 1)) { - arr[i] = conv_S(val[i]); - } - return arr; -} - -fn f() { - s = conv_arr4_S(u); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyStruct_UniformToWorkgroup_Mat3x2F32) { - auto* src = R"( -struct S { - v : vec4, - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var u : array; - -var w : array; - -fn f() { - w[0] = u[1]; -} -)"; - - auto* expect = R"( -struct S { - v : vec4, - @size(64) - m : mat3x2, -} - -struct S_std140 { - v : vec4, - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var u : array; - -var w : array; - -fn conv_S(val : S_std140) -> S { - return S(val.v, mat3x2(val.m_0, val.m_1, val.m_2)); -} - -fn f() { - w[0] = conv_S(u[1u]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyMatrix_UniformToPrivate_Mat3x2F32) { - auto* src = R"( -struct S { - v : vec4, - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var u : array; - -var p : array; - -fn f() { - p[2].m = u[1].m; -} -)"; - - auto* expect = R"( -struct S { - v : vec4, - @size(64) - m : mat3x2, -} - -struct S_std140 { - v : vec4, - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var u : array; - -var p : array; - -fn load_u_1_m() -> mat3x2 { - let s = &(u[1u]); - return mat3x2((*(s)).m_0, (*(s)).m_1, (*(s)).m_2); -} - -fn f() { - p[2].m = load_u_1_m(); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyColumn_UniformToStorage_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var u : array; - -@group(0) @binding(1) var s : array; - -fn f() { - s[3].m[1] = u[2].m[0]; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var u : array; - -@group(0) @binding(1) var s : array; - -fn f() { - s[3].m[1] = u[2u].m_0; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyColumnSwizzle_UniformToWorkgroup_Mat3x2F32) { - auto* src = R"( -struct S { - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var u : array; - -var w : array; - -fn f() { - w[3].m[1] = u[2].m[0].yx.yx; -} -)"; - - auto* expect = R"( -struct S { - @size(64) - m : mat3x2, -} - -struct S_std140 { - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var u : array; - -var w : array; - -fn f() { - w[3].m[1] = u[2u].m_0.yx.yx; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayStructMatUniform_CopyScalar_UniformToPrivate_Mat3x2F32) { - auto* src = R"( -struct S { - v : vec4, - @size(64) - m : mat3x2, -} - -@group(0) @binding(0) var u : array; - -var p : array; - -fn f() { - p[3].m[1].x = u[2].m[0].y; -} -)"; - - auto* expect = R"( -struct S { - v : vec4, - @size(64) - m : mat3x2, -} - -struct S_std140 { - v : vec4, - m_0 : vec2, - m_1 : vec2, - @size(48) - m_2 : vec2, -} - -@group(0) @binding(0) var u : array; - -var p : array; - -fn f() { - p[3].m[1].x = u[2u].m_0[1u]; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayMatUniform_LoadArray_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>; - -fn f() { - let l = a; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { - var arr : array, 3u>; - for(var i : u32; (i < 3u); i = (i + 1)) { - arr[i] = conv_mat2x2_f32(val[i]); - } - return arr; -} - -fn f() { - let l = conv_arr3_mat2x2_f32(a); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayMatUniform_LoadMatrix_ConstArrayIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>; - -fn f() { - let l = a[2]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn f() { - let l = conv_mat2x2_f32(a[2u]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayMatUniform_LoadMatrix_VariableArrayIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>; - -fn f() { - let I = 1; - let l = a[I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn f() { - let I = 1; - let l = conv_mat2x2_f32(a[I]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>; - -fn f() { - let l = a[2][1]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let l = a[2u].col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>; - -fn f() { - let I = 1; - let l = a[I][1]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn f() { - let I = 1; - let l = a[I].col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>; - -fn f() { - let I = 1; - let l = a[2][I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn load_a_2_p0(p0 : u32) -> vec2 { - switch(p0) { - case 0u: { - return a[2u].col0; - } - case 1u: { - return a[2u].col1; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_a_2_p0(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>; - -fn f() { - let I = 1; - let l = a[I][I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array; - -fn load_a_p0_p1(p0 : u32, p1 : u32) -> vec2 { - switch(p1) { - case 0u: { - return a[p0].col0; - } - case 1u: { - return a[p0].col1; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_a_p0_p1(u32(I), u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructArrayMatUniform_LoadStruct_Mat2x2F32) { - auto* src = R"( -struct S { - a : array, 3>, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let l = s; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -struct S { - a : array, 3>, -} - -struct S_std140 { - a : array, -} - -@group(0) @binding(0) var s : S_std140; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { - var arr : array, 3u>; - for(var i : u32; (i < 3u); i = (i + 1)) { - arr[i] = conv_mat2x2_f32(val[i]); - } - return arr; -} - -fn conv_S(val : S_std140) -> S { - return S(conv_arr3_mat2x2_f32(val.a)); -} - -fn f() { - let l = conv_S(s); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructArrayMatUniform_LoadArray_Mat2x2F32) { - auto* src = R"( -struct S { - a : array, 3>, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let l = s.a; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -struct S { - a : array, 3>, -} - -struct S_std140 { - a : array, -} - -@group(0) @binding(0) var s : S_std140; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { - var arr : array, 3u>; - for(var i : u32; (i < 3u); i = (i + 1)) { - arr[i] = conv_mat2x2_f32(val[i]); - } - return arr; -} - -fn f() { - let l = conv_arr3_mat2x2_f32(s.a); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructArrayMatUniform_LoadMatrix_ConstArrayIndex_Mat2x2F32) { - auto* src = R"( -struct S { - a : array, 3>, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let l = s.a[2]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -struct S { - a : array, 3>, -} - -struct S_std140 { - a : array, -} - -@group(0) @binding(0) var s : S_std140; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn f() { - let l = conv_mat2x2_f32(s.a[2u]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, StructArrayMatUniform_LoadMatrix_VariableArrayIndex_Mat2x2F32) { - auto* src = R"( -struct S { - a : array, 3>, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let I = 1; - let l = s.a[I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -struct S { - a : array, 3>, -} - -struct S_std140 { - a : array, -} - -@group(0) @binding(0) var s : S_std140; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn f() { - let I = 1; - let l = conv_mat2x2_f32(s.a[I]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - StructArrayMatUniform_LoadColumn_ConstArrayIndex_ConstColumnIndex_Mat2x2F32) { - auto* src = R"( -struct S { - a : array, 3>, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let l = s.a[2][1]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -struct S { - a : array, 3>, -} - -struct S_std140 { - a : array, -} - -@group(0) @binding(0) var s : S_std140; - -fn f() { - let l = s.a[2u].col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - StructArrayMatUniform_LoadColumn_VariableArrayIndex_ConstColumnIndex_Mat2x2F32) { - auto* src = R"( -struct S { - a : array, 3>, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let I = 1; - let l = s.a[I][1]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -struct S { - a : array, 3>, -} - -struct S_std140 { - a : array, -} - -@group(0) @binding(0) var s : S_std140; - -fn f() { - let I = 1; - let l = s.a[I].col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - StructArrayMatUniform_LoadColumn_ConstArrayIndex_VariableColumnIndex_Mat2x2F32) { - auto* src = R"( -struct S { - a : array, 3>, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let I = 1; - let l = s.a[2][I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -struct S { - a : array, 3>, -} - -struct S_std140 { - a : array, -} - -@group(0) @binding(0) var s : S_std140; - -fn load_s_a_2_p0(p0 : u32) -> vec2 { - switch(p0) { - case 0u: { - return s.a[2u].col0; - } - case 1u: { - return s.a[2u].col1; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_s_a_2_p0(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - StructArrayMatUniform_LoadColumn_VariableArrayIndex_VariableColumnIndex_Mat2x2F32) { - auto* src = R"( -struct S { - a : array, 3>, -} - -@group(0) @binding(0) var s : S; - -fn f() { - let I = 1; - let l = s.a[I][I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -struct S { - a : array, 3>, -} - -struct S_std140 { - a : array, -} - -@group(0) @binding(0) var s : S_std140; - -fn load_s_a_p0_p1(p0 : u32, p1 : u32) -> vec2 { - switch(p1) { - case 0u: { - return s.a[p0].col0; - } - case 1u: { - return s.a[p0].col1; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_s_a_p0_p1(u32(I), u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayArrayMatUniform_LoadArrays_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let l = a; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { - var arr : array, 3u>; - for(var i : u32; (i < 3u); i = (i + 1)) { - arr[i] = conv_mat2x2_f32(val[i]); - } - return arr; -} - -fn conv_arr4_arr3_mat2x2_f32(val : array, 4u>) -> array, 3u>, 4u> { - var arr : array, 3u>, 4u>; - for(var i : u32; (i < 4u); i = (i + 1)) { - arr[i] = conv_arr3_mat2x2_f32(val[i]); - } - return arr; -} - -fn f() { - let l = conv_arr4_arr3_mat2x2_f32(a); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayArrayMatUniform_LoadArray_ConstOuterArrayIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let l = a[3]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { - var arr : array, 3u>; - for(var i : u32; (i < 3u); i = (i + 1)) { - arr[i] = conv_mat2x2_f32(val[i]); - } - return arr; -} - -fn f() { - let l = conv_arr3_mat2x2_f32(a[3u]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, ArrayArrayMatUniform_LoadArray_VariableOuterArrayIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let l = a[I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn conv_arr3_mat2x2_f32(val : array) -> array, 3u> { - var arr : array, 3u>; - for(var i : u32; (i < 3u); i = (i + 1)) { - arr[i] = conv_mat2x2_f32(val[i]); - } - return arr; -} - -fn f() { - let I = 1; - let l = conv_arr3_mat2x2_f32(a[I]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayArrayMatUniform_LoadMatrix_ConstOuterArrayIndex_ConstInnerArrayIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let l = a[3][2]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn f() { - let l = conv_mat2x2_f32(a[3u][2u]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayArrayMatUniform_LoadMatrix_ConstOuterArrayIndex_VariableInnerArrayIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let l = a[3][I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn f() { - let I = 1; - let l = conv_mat2x2_f32(a[3u][I]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayArrayMatUniform_LoadMatrix_VariableOuterArrayIndex_ConstInnerArrayIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let l = a[I][2]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn f() { - let I = 1; - let l = conv_mat2x2_f32(a[I][2u]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(Std140Test_F32, - ArrayArrayMatUniform_LoadMatrix_VariableOuterArrayIndex_VariableInnerArrayIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let l = a[I][I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn conv_mat2x2_f32(val : mat2x2_f32) -> mat2x2 { - return mat2x2(val.col0, val.col1); -} - -fn f() { - let I = 1; - let l = conv_mat2x2_f32(a[I][I]); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F( - Std140Test_F32, - ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_ConstInnerArrayIndex_ConstColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let l = a[3][2][1]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn f() { - let l = a[3u][2u].col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F( - Std140Test_F32, - ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_ConstInnerArrayIndex_VariableColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let l = a[3][2][I]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn load_a_3_2_p0(p0 : u32) -> vec2 { - switch(p0) { - case 0u: { - return a[3u][2u].col0; - } - case 1u: { - return a[3u][2u].col1; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let l = load_a_3_2_p0(u32(I)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F( - Std140Test_F32, - ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_VariableInnerArrayIndex_ConstColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let l = a[3][I][1]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn f() { - let I = 1; - let l = a[3u][I].col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F( - Std140Test_F32, - ArrayArrayMatUniform_LoadColumn_ConstOuterArrayIndex_VariableInnerArrayIndex_VariableColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let J = 2; - let l = a[3][I][J]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn load_a_3_p0_p1(p0 : u32, p1 : u32) -> vec2 { - switch(p1) { - case 0u: { - return a[3u][p0].col0; - } - case 1u: { - return a[3u][p0].col1; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let J = 2; - let l = load_a_3_p0_p1(u32(I), u32(J)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F( - Std140Test_F32, - ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_ConstInnerArrayIndex_ConstColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let l = a[I][2][1]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn f() { - let I = 1; - let l = a[I][2u].col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F( - Std140Test_F32, - ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_ConstInnerArrayIndex_VariableColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let J = 2; - let l = a[I][2][J]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn load_a_p0_2_p1(p0 : u32, p1 : u32) -> vec2 { - switch(p1) { - case 0u: { - return a[p0][2u].col0; - } - case 1u: { - return a[p0][2u].col1; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 1; - let J = 2; - let l = load_a_p0_2_p1(u32(I), u32(J)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F( - Std140Test_F32, - ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_VariableInnerArrayIndex_ConstColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 1; - let J = 2; - let l = a[I][J][1]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn f() { - let I = 1; - let J = 2; - let l = a[I][J].col1; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F( - Std140Test_F32, - ArrayArrayMatUniform_LoadColumn_VariableOuterArrayIndex_VariableInnerArrayIndex_VariableColumnIndex_Mat2x2F32) { - auto* src = R"( -@group(0) @binding(0) var a : array, 3>, 4>; - -fn f() { - let I = 0; - let J = 1; - let K = 2; - let l = a[I][J][K]; -} -)"; - - auto* expect = R"( -struct mat2x2_f32 { - col0 : vec2, - col1 : vec2, -} - -@group(0) @binding(0) var a : array, 4u>; - -fn load_a_p0_p1_p2(p0 : u32, p1 : u32, p2 : u32) -> vec2 { - switch(p2) { - case 0u: { - return a[p0][p1].col0; - } - case 1u: { - return a[p0][p1].col1; - } - default: { - return vec2(); - } - } -} - -fn f() { - let I = 0; - let J = 1; - let K = 2; - let l = load_a_p0_p1_p2(u32(I), u32(J), u32(K)); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - } // namespace } // namespace tint::transform diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc index dcad1b5d1c..1e786da0f3 100644 --- a/src/tint/writer/hlsl/generator_impl.cc +++ b/src/tint/writer/hlsl/generator_impl.cc @@ -1097,31 +1097,62 @@ bool GeneratorImpl::EmitUniformBufferAccess( const auto& args = expr->args; auto* offset_arg = builder_.Sem().Get(args[1]); - uint32_t scalar_offset_value = 0; - std::string scalar_offset_expr; + // offset in bytes + uint32_t scalar_offset_bytes = 0; + // offset in uint (4 bytes) + uint32_t scalar_offset_index = 0; + // expression to calculate offset in bytes + std::string scalar_offset_bytes_expr; + // expression to calculate offset in uint, by dividing scalar_offset_bytes_expr by 4 + std::string scalar_offset_index_expr; + // expression to calculate offset in uint, independently + std::string scalar_offset_index_unified_expr; - // If true, use scalar_offset_value, otherwise use scalar_offset_expr + // If true, use scalar_offset_index, otherwise use scalar_offset_index_expr bool scalar_offset_constant = false; if (auto* val = offset_arg->ConstantValue()) { TINT_ASSERT(Writer, val->Type()->Is()); - scalar_offset_value = static_cast(std::get(val->Value())); - scalar_offset_value /= 4; // bytes -> scalar index + scalar_offset_bytes = static_cast(std::get(val->Value())); + scalar_offset_index = scalar_offset_bytes / 4; // bytes -> scalar index scalar_offset_constant = true; } + // If true, scalar_offset_bytes or scalar_offset_bytes_expr should be used, otherwise only use + // scalar_offset_index or scalar_offset_index_unified_expr. Currently only loading f16 scalar + // require using offset in bytes. + const bool need_offset_in_bytes = + intrinsic->type == transform::DecomposeMemoryAccess::Intrinsic::DataType::kF16; + if (!scalar_offset_constant) { // UBO offset not compile-time known. // Calculate the scalar offset into a temporary. - scalar_offset_expr = UniqueIdentifier("scalar_offset"); - auto pre = line(); - pre << "const uint " << scalar_offset_expr << " = ("; - if (!EmitExpression(pre, args[1])) { // offset - return false; + if (need_offset_in_bytes) { + scalar_offset_bytes_expr = UniqueIdentifier("scalar_offset_bytes"); + scalar_offset_index_expr = UniqueIdentifier("scalar_offset_index"); + { + auto pre = line(); + pre << "const uint " << scalar_offset_bytes_expr << " = ("; + if (!EmitExpression(pre, args[1])) { // offset + return false; + } + pre << ");"; + } + line() << "const uint " << scalar_offset_index_expr << " = " << scalar_offset_bytes_expr + << " / 4;"; + } else { + scalar_offset_index_unified_expr = UniqueIdentifier("scalar_offset"); + auto pre = line(); + pre << "const uint " << scalar_offset_index_unified_expr << " = ("; + if (!EmitExpression(pre, args[1])) { // offset + return false; + } + pre << ") / 4;"; } - pre << ") / 4;"; } + constexpr const char swizzle[] = {'x', 'y', 'z', 'w'}; + using Op = transform::DecomposeMemoryAccess::Intrinsic::Op; using DataType = transform::DecomposeMemoryAccess::Intrinsic::DataType; switch (intrinsic->op) { @@ -1132,27 +1163,28 @@ bool GeneratorImpl::EmitUniformBufferAccess( out << ")"; return result; }; - auto load_scalar = [&]() { - if (!EmitExpression(out, args[0])) { // buffer + auto load_u32_to = [&](std::ostream& target) { + if (!EmitExpression(target, args[0])) { // buffer return false; } if (scalar_offset_constant) { - char swizzle[] = {'x', 'y', 'z', 'w'}; - out << "[" << (scalar_offset_value / 4) << "]." - << swizzle[scalar_offset_value & 3]; + target << "[" << (scalar_offset_index / 4) << "]." + << swizzle[scalar_offset_index & 3]; } else { - out << "[" << scalar_offset_expr << " / 4][" << scalar_offset_expr << " % 4]"; + target << "[" << scalar_offset_index_unified_expr << " / 4][" + << scalar_offset_index_unified_expr << " % 4]"; } return true; }; + auto load_u32 = [&] { return load_u32_to(out); }; // Has a minimum alignment of 8 bytes, so is either .xy or .zw - auto load_vec2 = [&] { + auto load_vec2_u32_to = [&](std::ostream& target) { if (scalar_offset_constant) { - if (!EmitExpression(out, args[0])) { // buffer + if (!EmitExpression(target, args[0])) { // buffer return false; } - out << "[" << (scalar_offset_value / 4) << "]"; - out << ((scalar_offset_value & 2) == 0 ? ".xy" : ".zw"); + target << "[" << (scalar_offset_index / 4) << "]"; + target << ((scalar_offset_index & 2) == 0 ? ".xy" : ".zw"); } else { std::string ubo_load = UniqueIdentifier("ubo_load"); { @@ -1161,58 +1193,190 @@ bool GeneratorImpl::EmitUniformBufferAccess( if (!EmitExpression(pre, args[0])) { // buffer return false; } - pre << "[" << scalar_offset_expr << " / 4];"; + pre << "[" << scalar_offset_index_unified_expr << " / 4];"; } - out << "((" << scalar_offset_expr << " & 2) ? " << ubo_load - << ".zw : " << ubo_load << ".xy)"; + target << "((" << scalar_offset_index_unified_expr << " & 2) ? " << ubo_load + << ".zw : " << ubo_load << ".xy)"; } return true; }; + auto load_vec2_u32 = [&] { return load_vec2_u32_to(out); }; // vec4 has a minimum alignment of 16 bytes, easiest case - auto load_vec4 = [&] { + auto load_vec4_u32 = [&] { if (!EmitExpression(out, args[0])) { // buffer return false; } if (scalar_offset_constant) { - out << "[" << (scalar_offset_value / 4) << "]"; + out << "[" << (scalar_offset_index / 4) << "]"; } else { - out << "[" << scalar_offset_expr << " / 4]"; + out << "[" << scalar_offset_index_unified_expr << " / 4]"; } return true; }; // vec3 has a minimum alignment of 16 bytes, so is just a .xyz swizzle - auto load_vec3 = [&] { - if (!load_vec4()) { + auto load_vec3_u32 = [&] { + if (!load_vec4_u32()) { return false; } out << ".xyz"; return true; }; + auto load_scalar_f16 = [&] { + // offset bytes = 4k, ((buffer[index].x) & 0xFFFF) + // offset bytes = 4k+2, ((buffer[index].x >> 16) & 0xFFFF) + out << "float16_t(f16tof32((("; + if (!EmitExpression(out, args[0])) { // buffer + return false; + } + if (scalar_offset_constant) { + out << "[" << (scalar_offset_index / 4) << "]." + << swizzle[scalar_offset_index & 3]; + // WGSL spec ensure little endian memory layout. + if (scalar_offset_bytes % 4 == 0) { + out << ") & 0xFFFF)"; + } else { + out << " >> 16) & 0xFFFF)"; + } + } else { + out << "[" << scalar_offset_index_expr << " / 4][" << scalar_offset_index_expr + << " % 4] >> (" << scalar_offset_bytes_expr + << " % 4 == 0 ? 0 : 16)) & 0xFFFF)"; + } + out << "))"; + return true; + }; + auto load_vec2_f16 = [&] { + // vec2 is aligned to 4 bytes + // Preclude code load the vec2 data as a uint: + // uint ubo_load = buffer[id0][id1]; + // Loading code convert it to vec2: + // vector(float16_t(f16tof32(ubo_load & 0xFFFF)), + // float16_t(f16tof32(ubo_load >> 16))) + std::string ubo_load = UniqueIdentifier("ubo_load"); + { + auto pre = line(); + // Load the 4 bytes f16 vector as an uint + pre << "uint " << ubo_load << " = "; + if (!load_u32_to(pre)) { + return false; + } + pre << ";"; + } + out << "vector(float16_t(f16tof32(" << ubo_load + << " & 0xFFFF)), float16_t(f16tof32(" << ubo_load << " >> 16)))"; + return true; + }; + auto load_vec3_f16 = [&] { + // vec3 is aligned to 8 bytes + // Preclude code load the vec3 data as uint2 and convert its elements to + // float16_t: + // uint2 ubo_load = buffer[id0].xy; + // /* The low 8 bits of two uint are the x and z elements of vec3 */ + // vector ubo_load_xz = vector(f16tof32(ubo_load & + // 0xFFFF)); + // /* The high 8 bits of first uint is the y element of vec3 */ + // float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + // Loading code convert it to vec3: + // vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]) + std::string ubo_load = UniqueIdentifier("ubo_load"); + std::string ubo_load_xz = UniqueIdentifier(ubo_load + "_xz"); + std::string ubo_load_y = UniqueIdentifier(ubo_load + "_y"); + { + auto pre = line(); + // Load the 8 bytes uint2 with the f16 vector at lower 6 bytes + pre << "uint2 " << ubo_load << " = "; + if (!load_vec2_u32_to(pre)) { + return false; + } + pre << ";"; + } + { + auto pre = line(); + pre << "vector " << ubo_load_xz + << " = vector(f16tof32(" << ubo_load << " & 0xFFFF));"; + } + { + auto pre = line(); + pre << "float16_t " << ubo_load_y << " = f16tof32(" << ubo_load + << "[0] >> 16);"; + } + out << "vector(" << ubo_load_xz << "[0], " << ubo_load_y << ", " + << ubo_load_xz << "[1])"; + return true; + }; + auto load_vec4_f16 = [&] { + // vec4 is aligned to 8 bytes + // Preclude code load the vec4 data as uint2 and convert its elements to + // float16_t: + // uint2 ubo_load = buffer[id0].xy; + // /* The low 8 bits of two uint are the x and z elements of vec4 */ + // vector ubo_load_xz = vector(f16tof32(ubo_load & + // 0xFFFF)); + // /* The high 8 bits of two uint are the y and w elements of vec4 */ + // vector ubo_load_yw = vector(f16tof32(ubo_load >> + // 16)); + // Loading code convert it to vec4: + // vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], + // ubo_load_yw[1]) + std::string ubo_load = UniqueIdentifier("ubo_load"); + std::string ubo_load_xz = UniqueIdentifier(ubo_load + "_xz"); + std::string ubo_load_yw = UniqueIdentifier(ubo_load + "_yw"); + { + auto pre = line(); + // Load the 8 bytes f16 vector as an uint2 + pre << "uint2 " << ubo_load << " = "; + if (!load_vec2_u32_to(pre)) { + return false; + } + pre << ";"; + } + { + auto pre = line(); + pre << "vector " << ubo_load_xz + << " = vector(f16tof32(" << ubo_load << " & 0xFFFF));"; + } + { + auto pre = line(); + pre << "vector " << ubo_load_yw + << " = vector(f16tof32(" << ubo_load << " >> 16));"; + } + out << "vector(" << ubo_load_xz << "[0], " << ubo_load_yw << "[0], " + << ubo_load_xz << "[1], " << ubo_load_yw << "[1])"; + return true; + }; switch (intrinsic->type) { case DataType::kU32: - return load_scalar(); + return load_u32(); case DataType::kF32: - return cast("asfloat", load_scalar); + return cast("asfloat", load_u32); case DataType::kI32: - return cast("asint", load_scalar); + return cast("asint", load_u32); + case DataType::kF16: + return load_scalar_f16(); case DataType::kVec2U32: - return load_vec2(); + return load_vec2_u32(); case DataType::kVec2F32: - return cast("asfloat", load_vec2); + return cast("asfloat", load_vec2_u32); case DataType::kVec2I32: - return cast("asint", load_vec2); + return cast("asint", load_vec2_u32); + case DataType::kVec2F16: + return load_vec2_f16(); case DataType::kVec3U32: - return load_vec3(); + return load_vec3_u32(); case DataType::kVec3F32: - return cast("asfloat", load_vec3); + return cast("asfloat", load_vec3_u32); case DataType::kVec3I32: - return cast("asint", load_vec3); + return cast("asint", load_vec3_u32); + case DataType::kVec3F16: + return load_vec3_f16(); case DataType::kVec4U32: - return load_vec4(); + return load_vec4_u32(); case DataType::kVec4F32: - return cast("asfloat", load_vec4); + return cast("asfloat", load_vec4_u32); case DataType::kVec4I32: - return cast("asint", load_vec4); + return cast("asint", load_vec4_u32); + case DataType::kVec4F16: + return load_vec4_f16(); } TINT_UNREACHABLE(Writer, diagnostics_) << "unsupported DecomposeMemoryAccess::Intrinsic::DataType: " @@ -1257,6 +1421,20 @@ bool GeneratorImpl::EmitStorageBufferAccess( } return true; }; + // Templated load used for f16 types, requires SM6.2 or higher and DXC + // Used by loading f16 types, e.g. for f16 type, set type parameter to "float16_t" + // to emit `buffer.Load(offset)`. + auto templated_load = [&](const char* type) { + if (!EmitExpression(out, args[0])) { // buffer + return false; + } + out << ".Load<" << type << ">"; // templated load + ScopedParen sp(out); + if (!EmitExpression(out, args[1])) { // offset + return false; + } + return true; + }; switch (intrinsic->type) { case DataType::kU32: return load(nullptr, 1); @@ -1264,24 +1442,32 @@ bool GeneratorImpl::EmitStorageBufferAccess( return load("asfloat", 1); case DataType::kI32: return load("asint", 1); + case DataType::kF16: + return templated_load("float16_t"); case DataType::kVec2U32: return load(nullptr, 2); case DataType::kVec2F32: return load("asfloat", 2); case DataType::kVec2I32: return load("asint", 2); + case DataType::kVec2F16: + return templated_load("vector "); case DataType::kVec3U32: return load(nullptr, 3); case DataType::kVec3F32: return load("asfloat", 3); case DataType::kVec3I32: return load("asint", 3); + case DataType::kVec3F16: + return templated_load("vector "); case DataType::kVec4U32: return load(nullptr, 4); case DataType::kVec4F32: return load("asfloat", 4); case DataType::kVec4I32: return load("asint", 4); + case DataType::kVec4F16: + return templated_load("vector "); } TINT_UNREACHABLE(Writer, diagnostics_) << "unsupported DecomposeMemoryAccess::Intrinsic::DataType: " @@ -1309,6 +1495,24 @@ bool GeneratorImpl::EmitStorageBufferAccess( } return true; }; + // Templated stored used for f16 types, requires SM6.2 or higher and DXC + // Used by storing f16 types, e.g. for f16 type, set type parameter to "float16_t" + // to emit `buffer.Store(offset)`. + auto templated_store = [&](const char* type) { + if (!EmitExpression(out, args[0])) { // buffer + return false; + } + out << ".Store<" << type << ">"; // templated store + ScopedParen sp1(out); + if (!EmitExpression(out, args[1])) { // offset + return false; + } + out << ", "; + if (!EmitExpression(out, args[2])) { // value + return false; + } + return true; + }; switch (intrinsic->type) { case DataType::kU32: return store(1); @@ -1316,24 +1520,32 @@ bool GeneratorImpl::EmitStorageBufferAccess( return store(1); case DataType::kI32: return store(1); + case DataType::kF16: + return templated_store("float16_t"); case DataType::kVec2U32: return store(2); case DataType::kVec2F32: return store(2); case DataType::kVec2I32: return store(2); + case DataType::kVec2F16: + return templated_store("vector "); case DataType::kVec3U32: return store(3); case DataType::kVec3F32: return store(3); case DataType::kVec3I32: return store(3); + case DataType::kVec3F16: + return templated_store("vector "); case DataType::kVec4U32: return store(4); case DataType::kVec4F32: return store(4); case DataType::kVec4I32: return store(4); + case DataType::kVec4F16: + return templated_store("vector "); } TINT_UNREACHABLE(Writer, diagnostics_) << "unsupported DecomposeMemoryAccess::Intrinsic::DataType: " diff --git a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc index 1fbef9b056..b3440b8efb 100644 --- a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc +++ b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc @@ -34,6 +34,9 @@ inline const ast::Type* ty_u32(const ProgramBuilder::TypesBuilder& ty) { inline const ast::Type* ty_f32(const ProgramBuilder::TypesBuilder& ty) { return ty.f32(); } +inline const ast::Type* ty_f16(const ProgramBuilder::TypesBuilder& ty) { + return ty.f16(); +} template inline const ast::Type* ty_vec2(const ProgramBuilder::TypesBuilder& ty) { return ty.vec2(); @@ -94,6 +97,14 @@ class HlslGeneratorImplTest_MemberAccessorBase : public BASE { b.Group(1_a), b.Binding(0_a)); } + void SetupUniformBuffer(utils::VectorRef members) { + ProgramBuilder& b = *this; + auto* s = b.Structure("Data", members); + + b.GlobalVar("data", b.ty.Of(s), ast::AddressSpace::kUniform, ast::Access::kUndefined, + b.Group(1_a), b.Binding(1_a)); + } + void SetupFunction(utils::VectorRef statements) { ProgramBuilder& b = *this; utils::Vector attrs{ @@ -144,18 +155,21 @@ inline std::ostream& operator<<(std::ostream& out, TypeCase c) { return out; } -using HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad = +using HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad_ConstantOffset = HlslGeneratorImplTest_MemberAccessorWithParam; -TEST_P(HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad, Test) { + +TEST_P(HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad_ConstantOffset, Test) { // struct Data { - // a : i32; - // b : ; + // a : i32, + // b : , // }; // var data : Data; // data.b; auto p = GetParam(); + Enable(ast::Extension::kF16); + SetupStorageBuffer(utils::Vector{ Member("a", ty.i32()), Member("b", p.member_type(ty)), @@ -173,60 +187,813 @@ TEST_P(HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad, Test) { INSTANTIATE_TEST_SUITE_P( HlslGeneratorImplTest_MemberAccessor, - HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad, + HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad_ConstantOffset, + testing::Values(TypeCase{ty_u32, "data.Load(4u)"}, + TypeCase{ty_f32, "asfloat(data.Load(4u))"}, + TypeCase{ty_i32, "asint(data.Load(4u))"}, + TypeCase{ty_f16, "data.Load(4u)"}, + TypeCase{ty_vec2, "data.Load2(8u)"}, + TypeCase{ty_vec2, "asfloat(data.Load2(8u))"}, + TypeCase{ty_vec2, "asint(data.Load2(8u))"}, + TypeCase{ty_vec2, "data.Load >(4u)"}, + TypeCase{ty_vec3, "data.Load3(16u)"}, + TypeCase{ty_vec3, "asfloat(data.Load3(16u))"}, + TypeCase{ty_vec3, "asint(data.Load3(16u))"}, + TypeCase{ty_vec3, "data.Load >(8u)"}, + TypeCase{ty_vec4, "data.Load4(16u)"}, + TypeCase{ty_vec4, "asfloat(data.Load4(16u))"}, + TypeCase{ty_vec4, "asint(data.Load4(16u))"}, + TypeCase{ty_vec4, "data.Load >(8u)"}, + TypeCase{ty_mat2x2, + "return float2x2(asfloat(buffer.Load2((offset + 0u))), " + "asfloat(buffer.Load2((offset + 8u))));"}, + TypeCase{ty_mat2x3, + "return float2x3(asfloat(buffer.Load3((offset + 0u))), " + "asfloat(buffer.Load3((offset + 16u))));"}, + TypeCase{ty_mat2x4, + "return float2x4(asfloat(buffer.Load4((offset + 0u))), " + "asfloat(buffer.Load4((offset + 16u))));"}, + TypeCase{ty_mat3x2, + "return float3x2(asfloat(buffer.Load2((offset + 0u))), " + "asfloat(buffer.Load2((offset + 8u))), " + "asfloat(buffer.Load2((offset + 16u))));"}, + TypeCase{ty_mat3x3, + "return float3x3(asfloat(buffer.Load3((offset + 0u))), " + "asfloat(buffer.Load3((offset + 16u))), " + "asfloat(buffer.Load3((offset + 32u))));"}, + TypeCase{ty_mat3x4, + "return float3x4(asfloat(buffer.Load4((offset + 0u))), " + "asfloat(buffer.Load4((offset + 16u))), " + "asfloat(buffer.Load4((offset + 32u))));"}, + TypeCase{ty_mat4x2, + "return float4x2(asfloat(buffer.Load2((offset + 0u))), " + "asfloat(buffer.Load2((offset + 8u))), " + "asfloat(buffer.Load2((offset + 16u))), " + "asfloat(buffer.Load2((offset + 24u))));"}, + TypeCase{ty_mat4x3, + "return float4x3(asfloat(buffer.Load3((offset + 0u))), " + "asfloat(buffer.Load3((offset + 16u))), " + "asfloat(buffer.Load3((offset + 32u))), " + "asfloat(buffer.Load3((offset + 48u))));"}, + TypeCase{ty_mat4x4, + "return float4x4(asfloat(buffer.Load4((offset + 0u))), " + "asfloat(buffer.Load4((offset + 16u))), " + "asfloat(buffer.Load4((offset + 32u))), " + "asfloat(buffer.Load4((offset + 48u))));"}, + TypeCase{ty_mat2x2, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 4u)));"}, + TypeCase{ty_mat2x3, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)));"}, + TypeCase{ty_mat2x4, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)));"}, + TypeCase{ty_mat3x2, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 4u)), " + "buffer.Load >((offset + 8u)));"}, + TypeCase{ty_mat3x3, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 16u)));"}, + TypeCase{ty_mat3x4, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 16u)));"}, + TypeCase{ty_mat4x2, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 4u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 12u)));"}, + TypeCase{ty_mat4x3, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 16u)), " + "buffer.Load >((offset + 24u)));"}, + TypeCase{ty_mat4x4, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 16u)), " + "buffer.Load >((offset + 24u)));"})); + +using HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad_DynamicOffset = + HlslGeneratorImplTest_MemberAccessorWithParam; + +TEST_P(HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad_DynamicOffset, Test) { + // struct Inner { + // a : i32, + // b : , + // c : vec4, + // }; + // struct Data { + // arr : array, + // } + // var data : Data; + // data.arr[i].b; + + auto p = GetParam(); + + Enable(ast::Extension::kF16); + + auto* inner = Structure("Inner", utils::Vector{ + Member("a", ty.i32()), + Member("b", p.member_type(ty)), + Member("c", ty.vec4(ty.i32())), + }); + + SetupStorageBuffer(utils::Vector{ + Member("arr", ty.array(ty.Of(inner), 4_i)), + }); + + auto* i = Var("i", Expr(2_i)); + + SetupFunction(utils::Vector{ + Decl(i), + Decl(Var("x", MemberAccessor(IndexAccessor(MemberAccessor("data", "arr"), i), "b"))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT(gen.result(), HasSubstr(p.expected)); +} + +INSTANTIATE_TEST_SUITE_P( + HlslGeneratorImplTest_MemberAccessor, + HlslGeneratorImplTest_MemberAccessor_StorageBufferLoad_DynamicOffset, testing::Values( - TypeCase{ty_u32, "data.Load(4u)"}, - TypeCase{ty_f32, "asfloat(data.Load(4u))"}, - TypeCase{ty_i32, "asint(data.Load(4u))"}, - TypeCase{ty_vec2, "data.Load2(8u)"}, - TypeCase{ty_vec2, "asfloat(data.Load2(8u))"}, - TypeCase{ty_vec2, "asint(data.Load2(8u))"}, - TypeCase{ty_vec3, "data.Load3(16u)"}, - TypeCase{ty_vec3, "asfloat(data.Load3(16u))"}, - TypeCase{ty_vec3, "asint(data.Load3(16u))"}, - TypeCase{ty_vec4, "data.Load4(16u)"}, - TypeCase{ty_vec4, "asfloat(data.Load4(16u))"}, - TypeCase{ty_vec4, "asint(data.Load4(16u))"}, - TypeCase{ - ty_mat2x2, - R"(return float2x2(asfloat(buffer.Load2((offset + 0u))), asfloat(buffer.Load2((offset + 8u))));)"}, - TypeCase{ - ty_mat2x3, - R"(return float2x3(asfloat(buffer.Load3((offset + 0u))), asfloat(buffer.Load3((offset + 16u))));)"}, - TypeCase{ - ty_mat2x4, - R"(return float2x4(asfloat(buffer.Load4((offset + 0u))), asfloat(buffer.Load4((offset + 16u))));)"}, - TypeCase{ - ty_mat3x2, - R"(return float3x2(asfloat(buffer.Load2((offset + 0u))), asfloat(buffer.Load2((offset + 8u))), asfloat(buffer.Load2((offset + 16u))));)"}, - TypeCase{ - ty_mat3x3, - R"(return float3x3(asfloat(buffer.Load3((offset + 0u))), asfloat(buffer.Load3((offset + 16u))), asfloat(buffer.Load3((offset + 32u))));)"}, - TypeCase{ - ty_mat3x4, - R"(return float3x4(asfloat(buffer.Load4((offset + 0u))), asfloat(buffer.Load4((offset + 16u))), asfloat(buffer.Load4((offset + 32u))));)"}, - TypeCase{ - ty_mat4x2, - R"(return float4x2(asfloat(buffer.Load2((offset + 0u))), asfloat(buffer.Load2((offset + 8u))), asfloat(buffer.Load2((offset + 16u))), asfloat(buffer.Load2((offset + 24u))));)"}, - TypeCase{ - ty_mat4x3, - R"(return float4x3(asfloat(buffer.Load3((offset + 0u))), asfloat(buffer.Load3((offset + 16u))), asfloat(buffer.Load3((offset + 32u))), asfloat(buffer.Load3((offset + 48u))));)"}, - TypeCase{ - ty_mat4x4, - R"(return float4x4(asfloat(buffer.Load4((offset + 0u))), asfloat(buffer.Load4((offset + 16u))), asfloat(buffer.Load4((offset + 32u))), asfloat(buffer.Load4((offset + 48u))));)"})); + TypeCase{ty_u32, "data.Load(((32u * uint(i)) + 4u))"}, + TypeCase{ty_f32, "asfloat(data.Load(((32u * uint(i)) + 4u)))"}, + TypeCase{ty_i32, "asint(data.Load(((32u * uint(i)) + 4u)))"}, + TypeCase{ty_f16, "data.Load(((32u * uint(i)) + 4u))"}, + TypeCase{ty_vec2, "data.Load2(((32u * uint(i)) + 8u))"}, + TypeCase{ty_vec2, "asfloat(data.Load2(((32u * uint(i)) + 8u)))"}, + TypeCase{ty_vec2, "asint(data.Load2(((32u * uint(i)) + 8u)))"}, + TypeCase{ty_vec2, "data.Load >(((32u * uint(i)) + 4u))"}, + TypeCase{ty_vec3, "data.Load3(((48u * uint(i)) + 16u))"}, + TypeCase{ty_vec3, "asfloat(data.Load3(((48u * uint(i)) + 16u)))"}, + TypeCase{ty_vec3, "asint(data.Load3(((48u * uint(i)) + 16u)))"}, + TypeCase{ty_vec3, "data.Load >(((32u * uint(i)) + 8u))"}, + TypeCase{ty_vec4, "data.Load4(((48u * uint(i)) + 16u))"}, + TypeCase{ty_vec4, "asfloat(data.Load4(((48u * uint(i)) + 16u)))"}, + TypeCase{ty_vec4, "asint(data.Load4(((48u * uint(i)) + 16u)))"}, + TypeCase{ty_vec4, "data.Load >(((32u * uint(i)) + 8u))"}, + TypeCase{ty_mat2x2, + "return float2x2(asfloat(buffer.Load2((offset + 0u))), " + "asfloat(buffer.Load2((offset + 8u))));"}, + TypeCase{ty_mat2x3, + "return float2x3(asfloat(buffer.Load3((offset + 0u))), " + "asfloat(buffer.Load3((offset + 16u))));"}, + TypeCase{ty_mat2x4, + "return float2x4(asfloat(buffer.Load4((offset + 0u))), " + "asfloat(buffer.Load4((offset + 16u))));"}, + TypeCase{ty_mat3x2, + "return float3x2(asfloat(buffer.Load2((offset + 0u))), " + "asfloat(buffer.Load2((offset + 8u))), " + "asfloat(buffer.Load2((offset + 16u))));"}, + TypeCase{ty_mat3x3, + "return float3x3(asfloat(buffer.Load3((offset + 0u))), " + "asfloat(buffer.Load3((offset + 16u))), " + "asfloat(buffer.Load3((offset + 32u))));"}, + TypeCase{ty_mat3x4, + "return float3x4(asfloat(buffer.Load4((offset + 0u))), " + "asfloat(buffer.Load4((offset + 16u))), " + "asfloat(buffer.Load4((offset + 32u))));"}, + TypeCase{ty_mat4x2, + "return float4x2(asfloat(buffer.Load2((offset + 0u))), " + "asfloat(buffer.Load2((offset + 8u))), " + "asfloat(buffer.Load2((offset + 16u))), " + "asfloat(buffer.Load2((offset + 24u))));"}, + TypeCase{ty_mat4x3, + "return float4x3(asfloat(buffer.Load3((offset + 0u))), " + "asfloat(buffer.Load3((offset + 16u))), " + "asfloat(buffer.Load3((offset + 32u))), " + "asfloat(buffer.Load3((offset + 48u))));"}, + TypeCase{ty_mat4x4, + "return float4x4(asfloat(buffer.Load4((offset + 0u))), " + "asfloat(buffer.Load4((offset + 16u))), " + "asfloat(buffer.Load4((offset + 32u))), " + "asfloat(buffer.Load4((offset + 48u))));"}, + TypeCase{ty_mat2x2, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 4u)));"}, + TypeCase{ty_mat2x3, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)));"}, + TypeCase{ty_mat2x4, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)));"}, + TypeCase{ty_mat3x2, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 4u)), " + "buffer.Load >((offset + 8u)));"}, + TypeCase{ty_mat3x3, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 16u)));"}, + TypeCase{ty_mat3x4, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 16u)));"}, + TypeCase{ty_mat4x2, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 4u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 12u)));"}, + TypeCase{ty_mat4x3, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 16u)), " + "buffer.Load >((offset + 24u)));"}, + TypeCase{ty_mat4x4, + "return matrix(" + "buffer.Load >((offset + 0u)), " + "buffer.Load >((offset + 8u)), " + "buffer.Load >((offset + 16u)), " + "buffer.Load >((offset + 24u)));"})); + +using HlslGeneratorImplTest_MemberAccessor_UniformBufferLoad_ConstantOffset = + HlslGeneratorImplTest_MemberAccessorWithParam; +TEST_P(HlslGeneratorImplTest_MemberAccessor_UniformBufferLoad_ConstantOffset, Test) { + // struct Data { + // a : i32, + // b : , + // }; + // var data : Data; + // data.b; + + auto p = GetParam(); + + Enable(ast::Extension::kF16); + + SetupUniformBuffer(utils::Vector{ + Member("a", ty.i32()), + Member("b", p.member_type(ty)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", MemberAccessor("data", "b"))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT(gen.result(), HasSubstr(p.expected)); +} + +INSTANTIATE_TEST_SUITE_P( + HlslGeneratorImplTest_MemberAccessor, + HlslGeneratorImplTest_MemberAccessor_UniformBufferLoad_ConstantOffset, + testing::Values(TypeCase{ty_u32, "uint x = data[0].y;"}, + TypeCase{ty_f32, "float x = asfloat(data[0].y);"}, + TypeCase{ty_i32, "int x = asint(data[0].y);"}, + TypeCase{ty_f16, "float16_t x = float16_t(f16tof32(((data[0].y) & 0xFFFF)));"}, + TypeCase{ty_vec2, "uint2 x = data[0].zw;"}, + TypeCase{ty_vec2, "float2 x = asfloat(data[0].zw);"}, + TypeCase{ty_vec2, "int2 x = asint(data[0].zw);"}, + TypeCase{ty_vec2, R"(uint ubo_load = data[0].y; + vector x = vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16)));)"}, + TypeCase{ty_vec3, "uint3 x = data[1].xyz;"}, + TypeCase{ty_vec3, "float3 x = asfloat(data[1].xyz);"}, + TypeCase{ty_vec3, "int3 x = asint(data[1].xyz);"}, + TypeCase{ty_vec3, R"(uint2 ubo_load = data[0].zw; + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + vector x = vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]);)"}, + TypeCase{ty_vec4, "uint4 x = data[1];"}, + TypeCase{ty_vec4, "float4 x = asfloat(data[1]);"}, + TypeCase{ty_vec4, "int4 x = asint(data[1]);"}, + TypeCase{ty_vec4, + R"(uint2 ubo_load = data[0].zw; + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + vector ubo_load_yw = vector(f16tof32(ubo_load >> 16)); + vector x = vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], ubo_load_yw[1]);)"}, + TypeCase{ty_mat2x2, R"(float2x2 tint_symbol(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load = buffer[scalar_offset / 4]; + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset_1 / 4]; + return float2x2(asfloat(((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy)), asfloat(((scalar_offset_1 & 2) ? ubo_load_1.zw : ubo_load_1.xy))); +})"}, + TypeCase{ty_mat2x3, R"(float2x3 tint_symbol(uint4 buffer[3], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + return float2x3(asfloat(buffer[scalar_offset / 4].xyz), asfloat(buffer[scalar_offset_1 / 4].xyz)); +})"}, + TypeCase{ty_mat2x4, R"(float2x4 tint_symbol(uint4 buffer[3], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + return float2x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4])); +})"}, + TypeCase{ty_mat3x2, R"(float3x2 tint_symbol(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load = buffer[scalar_offset / 4]; + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset_1 / 4]; + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_2 = buffer[scalar_offset_2 / 4]; + return float3x2(asfloat(((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy)), asfloat(((scalar_offset_1 & 2) ? ubo_load_1.zw : ubo_load_1.xy)), asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy))); +})"}, + TypeCase{ty_mat3x3, R"(float3x3 tint_symbol(uint4 buffer[4], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + return float3x3(asfloat(buffer[scalar_offset / 4].xyz), asfloat(buffer[scalar_offset_1 / 4].xyz), asfloat(buffer[scalar_offset_2 / 4].xyz)); +})"}, + TypeCase{ty_mat3x4, R"(float3x4 tint_symbol(uint4 buffer[4], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + return float3x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4])); +})"}, + TypeCase{ty_mat4x2, R"(float4x2 tint_symbol(uint4 buffer[3], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load = buffer[scalar_offset / 4]; + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset_1 / 4]; + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_2 = buffer[scalar_offset_2 / 4]; + const uint scalar_offset_3 = ((offset + 24u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_3 / 4]; + return float4x2(asfloat(((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy)), asfloat(((scalar_offset_1 & 2) ? ubo_load_1.zw : ubo_load_1.xy)), asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy)), asfloat(((scalar_offset_3 & 2) ? ubo_load_3.zw : ubo_load_3.xy))); +})"}, + TypeCase{ty_mat4x3, R"(float4x3 tint_symbol(uint4 buffer[5], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + const uint scalar_offset_3 = ((offset + 48u)) / 4; + return float4x3(asfloat(buffer[scalar_offset / 4].xyz), asfloat(buffer[scalar_offset_1 / 4].xyz), asfloat(buffer[scalar_offset_2 / 4].xyz), asfloat(buffer[scalar_offset_3 / 4].xyz)); +})"}, + TypeCase{ty_mat4x4, R"(float4x4 tint_symbol(uint4 buffer[5], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + const uint scalar_offset_3 = ((offset + 48u)) / 4; + return float4x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4]), asfloat(buffer[scalar_offset_3 / 4])); +})"}, + TypeCase{ty_mat2x2, + R"(matrix tint_symbol(uint4 buffer[1], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint ubo_load = buffer[scalar_offset / 4][scalar_offset % 4]; + const uint scalar_offset_1 = ((offset + 4u)) / 4; + uint ubo_load_1 = buffer[scalar_offset_1 / 4][scalar_offset_1 % 4]; + return matrix(vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16))), vector(float16_t(f16tof32(ubo_load_1 & 0xFFFF)), float16_t(f16tof32(ubo_load_1 >> 16)))); +})"}, + TypeCase{ty_mat2x3, + R"(matrix tint_symbol(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1])); +})"}, + TypeCase{ty_mat2x4, + R"(matrix tint_symbol(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + vector ubo_load_yw = vector(f16tof32(ubo_load >> 16)); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + vector ubo_load_2_yw = vector(f16tof32(ubo_load_2 >> 16)); + return matrix(vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], ubo_load_yw[1]), vector(ubo_load_2_xz[0], ubo_load_2_yw[0], ubo_load_2_xz[1], ubo_load_2_yw[1])); +})"}, + TypeCase{ty_mat3x2, + R"(matrix tint_symbol(uint4 buffer[1], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint ubo_load = buffer[scalar_offset / 4][scalar_offset % 4]; + const uint scalar_offset_1 = ((offset + 4u)) / 4; + uint ubo_load_1 = buffer[scalar_offset_1 / 4][scalar_offset_1 % 4]; + const uint scalar_offset_2 = ((offset + 8u)) / 4; + uint ubo_load_2 = buffer[scalar_offset_2 / 4][scalar_offset_2 % 4]; + return matrix(vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16))), vector(float16_t(f16tof32(ubo_load_1 & 0xFFFF)), float16_t(f16tof32(ubo_load_1 >> 16))), vector(float16_t(f16tof32(ubo_load_2 & 0xFFFF)), float16_t(f16tof32(ubo_load_2 >> 16)))); +})"}, + TypeCase{ty_mat3x3, + R"(matrix tint_symbol(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1]), vector(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1])); +})"}, + TypeCase{ty_mat3x4, + R"(matrix tint_symbol(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + vector ubo_load_yw = vector(f16tof32(ubo_load >> 16)); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + vector ubo_load_2_yw = vector(f16tof32(ubo_load_2 >> 16)); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + vector ubo_load_4_yw = vector(f16tof32(ubo_load_4 >> 16)); + return matrix(vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], ubo_load_yw[1]), vector(ubo_load_2_xz[0], ubo_load_2_yw[0], ubo_load_2_xz[1], ubo_load_2_yw[1]), vector(ubo_load_4_xz[0], ubo_load_4_yw[0], ubo_load_4_xz[1], ubo_load_4_yw[1]));)"}, + TypeCase{ty_mat4x2, + R"(matrix tint_symbol(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint ubo_load = buffer[scalar_offset / 4][scalar_offset % 4]; + const uint scalar_offset_1 = ((offset + 4u)) / 4; + uint ubo_load_1 = buffer[scalar_offset_1 / 4][scalar_offset_1 % 4]; + const uint scalar_offset_2 = ((offset + 8u)) / 4; + uint ubo_load_2 = buffer[scalar_offset_2 / 4][scalar_offset_2 % 4]; + const uint scalar_offset_3 = ((offset + 12u)) / 4; + uint ubo_load_3 = buffer[scalar_offset_3 / 4][scalar_offset_3 % 4]; + return matrix(vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16))), vector(float16_t(f16tof32(ubo_load_1 & 0xFFFF)), float16_t(f16tof32(ubo_load_1 >> 16))), vector(float16_t(f16tof32(ubo_load_2 & 0xFFFF)), float16_t(f16tof32(ubo_load_2 >> 16))), vector(float16_t(f16tof32(ubo_load_3 & 0xFFFF)), float16_t(f16tof32(ubo_load_3 >> 16)))); +})"}, + TypeCase{ty_mat4x3, + R"(matrix tint_symbol(uint4 buffer[3], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16); + const uint scalar_offset_3 = ((offset + 24u)) / 4; + uint4 ubo_load_7 = buffer[scalar_offset_3 / 4]; + uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy); + vector ubo_load_6_xz = vector(f16tof32(ubo_load_6 & 0xFFFF)); + float16_t ubo_load_6_y = f16tof32(ubo_load_6[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1]), vector(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1]), vector(ubo_load_6_xz[0], ubo_load_6_y, ubo_load_6_xz[1])); +})"}, + TypeCase{ty_mat4x4, + R"(matrix tint_symbol(uint4 buffer[3], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + vector ubo_load_yw = vector(f16tof32(ubo_load >> 16)); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + vector ubo_load_2_yw = vector(f16tof32(ubo_load_2 >> 16)); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + vector ubo_load_4_yw = vector(f16tof32(ubo_load_4 >> 16)); + const uint scalar_offset_3 = ((offset + 24u)) / 4; + uint4 ubo_load_7 = buffer[scalar_offset_3 / 4]; + uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy); + vector ubo_load_6_xz = vector(f16tof32(ubo_load_6 & 0xFFFF)); + vector ubo_load_6_yw = vector(f16tof32(ubo_load_6 >> 16)); + return matrix(vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], ubo_load_yw[1]), vector(ubo_load_2_xz[0], ubo_load_2_yw[0], ubo_load_2_xz[1], ubo_load_2_yw[1]), vector(ubo_load_4_xz[0], ubo_load_4_yw[0], ubo_load_4_xz[1], ubo_load_4_yw[1]), vector(ubo_load_6_xz[0], ubo_load_6_yw[0], ubo_load_6_xz[1], ubo_load_6_yw[1])); +})"})); + +using HlslGeneratorImplTest_MemberAccessor_UniformBufferLoad_DynamicOffset = + HlslGeneratorImplTest_MemberAccessorWithParam; + +TEST_P(HlslGeneratorImplTest_MemberAccessor_UniformBufferLoad_DynamicOffset, Test) { + // struct Inner { + // a : i32, + // b : , + // c : vec4, + // }; + // struct Data { + // arr : array, + // } + // var data : Data; + // data.arr[i].b; + + auto p = GetParam(); + + Enable(ast::Extension::kF16); + + auto* inner = Structure("Inner", utils::Vector{ + Member("a", ty.i32()), + Member("b", p.member_type(ty)), + Member("c", ty.vec4(ty.i32())), + }); + + SetupUniformBuffer(utils::Vector{ + Member("arr", ty.array(ty.Of(inner), 4_i)), + }); + + auto* i = Var("i", Expr(2_i)); + + SetupFunction(utils::Vector{ + Decl(i), + Decl(Var("x", MemberAccessor(IndexAccessor(MemberAccessor("data", "arr"), i), "b"))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT(gen.result(), HasSubstr(p.expected)); +} + +INSTANTIATE_TEST_SUITE_P( + HlslGeneratorImplTest_MemberAccessor, + HlslGeneratorImplTest_MemberAccessor_UniformBufferLoad_DynamicOffset, + testing::Values( + TypeCase{ty_u32, "x = data[scalar_offset / 4][scalar_offset % 4]"}, + TypeCase{ty_f32, "x = asfloat(data[scalar_offset / 4][scalar_offset % 4])"}, + TypeCase{ty_i32, "x = asint(data[scalar_offset / 4][scalar_offset % 4])"}, + TypeCase{ty_f16, R"(const uint scalar_offset_bytes = (((32u * uint(i)) + 4u)); + const uint scalar_offset_index = scalar_offset_bytes / 4; + float16_t x = float16_t(f16tof32(((data[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));)"}, + TypeCase{ty_vec2, R"(uint4 ubo_load = data[scalar_offset / 4]; + uint2 x = ((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy);)"}, + TypeCase{ty_vec2, R"(uint4 ubo_load = data[scalar_offset / 4]; + float2 x = asfloat(((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy));)"}, + TypeCase{ty_vec2, R"(uint4 ubo_load = data[scalar_offset / 4]; + int2 x = asint(((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy));)"}, + TypeCase{ty_vec2, R"(const uint scalar_offset = (((32u * uint(i)) + 4u)) / 4; + uint ubo_load = data[scalar_offset / 4][scalar_offset % 4]; + vector x = vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16)));)"}, + TypeCase{ty_vec3, "x = data[scalar_offset / 4].xyz"}, + TypeCase{ty_vec3, "x = asfloat(data[scalar_offset / 4].xyz)"}, + TypeCase{ty_vec3, "x = asint(data[scalar_offset / 4].xyz)"}, + TypeCase{ty_vec3, R"(const uint scalar_offset = (((32u * uint(i)) + 8u)) / 4; + uint4 ubo_load_1 = data[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + vector x = vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]);)"}, + TypeCase{ty_vec4, "x = data[scalar_offset / 4]"}, + TypeCase{ty_vec4, "x = asfloat(data[scalar_offset / 4])"}, + TypeCase{ty_vec4, "x = asint(data[scalar_offset / 4])"}, + TypeCase{ty_vec4, R"(const uint scalar_offset = (((32u * uint(i)) + 8u)) / 4; + uint4 ubo_load_1 = data[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + vector ubo_load_yw = vector(f16tof32(ubo_load >> 16)); + vector x = vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], ubo_load_yw[1]);)"}, + TypeCase{ty_mat2x2, R"(float2x2 tint_symbol(uint4 buffer[12], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load = buffer[scalar_offset / 4]; + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset_1 / 4]; + return float2x2(asfloat(((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy)), asfloat(((scalar_offset_1 & 2) ? ubo_load_1.zw : ubo_load_1.xy))); +})"}, + TypeCase{ty_mat2x3, R"(float2x3 tint_symbol(uint4 buffer[16], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + return float2x3(asfloat(buffer[scalar_offset / 4].xyz), asfloat(buffer[scalar_offset_1 / 4].xyz)); +})"}, + TypeCase{ty_mat2x4, R"(float2x4 tint_symbol(uint4 buffer[16], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + return float2x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4])); +})"}, + TypeCase{ty_mat3x2, R"(float3x2 tint_symbol(uint4 buffer[12], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load = buffer[scalar_offset / 4]; + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset_1 / 4]; + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_2 = buffer[scalar_offset_2 / 4]; + return float3x2(asfloat(((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy)), asfloat(((scalar_offset_1 & 2) ? ubo_load_1.zw : ubo_load_1.xy)), asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy))); +})"}, + TypeCase{ty_mat3x3, R"(float3x3 tint_symbol(uint4 buffer[20], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + return float3x3(asfloat(buffer[scalar_offset / 4].xyz), asfloat(buffer[scalar_offset_1 / 4].xyz), asfloat(buffer[scalar_offset_2 / 4].xyz)); +})"}, + TypeCase{ty_mat3x4, R"(float3x4 tint_symbol(uint4 buffer[20], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + return float3x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4])); +})"}, + TypeCase{ty_mat4x2, R"(float4x2 tint_symbol(uint4 buffer[16], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load = buffer[scalar_offset / 4]; + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset_1 / 4]; + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_2 = buffer[scalar_offset_2 / 4]; + const uint scalar_offset_3 = ((offset + 24u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_3 / 4]; + return float4x2(asfloat(((scalar_offset & 2) ? ubo_load.zw : ubo_load.xy)), asfloat(((scalar_offset_1 & 2) ? ubo_load_1.zw : ubo_load_1.xy)), asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy)), asfloat(((scalar_offset_3 & 2) ? ubo_load_3.zw : ubo_load_3.xy))); +})"}, + TypeCase{ty_mat4x3, R"(float4x3 tint_symbol(uint4 buffer[24], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + const uint scalar_offset_3 = ((offset + 48u)) / 4; + return float4x3(asfloat(buffer[scalar_offset / 4].xyz), asfloat(buffer[scalar_offset_1 / 4].xyz), asfloat(buffer[scalar_offset_2 / 4].xyz), asfloat(buffer[scalar_offset_3 / 4].xyz)); +})"}, + TypeCase{ty_mat4x4, R"(float4x4 tint_symbol(uint4 buffer[24], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + const uint scalar_offset_3 = ((offset + 48u)) / 4; + return float4x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4]), asfloat(buffer[scalar_offset_3 / 4])); +})"}, + TypeCase{ty_mat2x2, + R"(matrix tint_symbol(uint4 buffer[8], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint ubo_load = buffer[scalar_offset / 4][scalar_offset % 4]; + const uint scalar_offset_1 = ((offset + 4u)) / 4; + uint ubo_load_1 = buffer[scalar_offset_1 / 4][scalar_offset_1 % 4]; + return matrix(vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16))), vector(float16_t(f16tof32(ubo_load_1 & 0xFFFF)), float16_t(f16tof32(ubo_load_1 >> 16)))); +})"}, + TypeCase{ty_mat2x3, + R"(matrix tint_symbol(uint4 buffer[12], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1])); +})"}, + TypeCase{ty_mat2x4, + R"(matrix tint_symbol(uint4 buffer[12], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + vector ubo_load_yw = vector(f16tof32(ubo_load >> 16)); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + vector ubo_load_2_yw = vector(f16tof32(ubo_load_2 >> 16)); + return matrix(vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], ubo_load_yw[1]), vector(ubo_load_2_xz[0], ubo_load_2_yw[0], ubo_load_2_xz[1], ubo_load_2_yw[1])); +})"}, + TypeCase{ty_mat3x2, + R"(matrix tint_symbol(uint4 buffer[8], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint ubo_load = buffer[scalar_offset / 4][scalar_offset % 4]; + const uint scalar_offset_1 = ((offset + 4u)) / 4; + uint ubo_load_1 = buffer[scalar_offset_1 / 4][scalar_offset_1 % 4]; + const uint scalar_offset_2 = ((offset + 8u)) / 4; + uint ubo_load_2 = buffer[scalar_offset_2 / 4][scalar_offset_2 % 4]; + return matrix(vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16))), vector(float16_t(f16tof32(ubo_load_1 & 0xFFFF)), float16_t(f16tof32(ubo_load_1 >> 16))), vector(float16_t(f16tof32(ubo_load_2 & 0xFFFF)), float16_t(f16tof32(ubo_load_2 >> 16)))); +})"}, + TypeCase{ty_mat3x3, + R"(matrix tint_symbol(uint4 buffer[12], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1]), vector(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1])); +})"}, + TypeCase{ty_mat3x4, + R"(matrix tint_symbol(uint4 buffer[12], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + vector ubo_load_yw = vector(f16tof32(ubo_load >> 16)); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + vector ubo_load_2_yw = vector(f16tof32(ubo_load_2 >> 16)); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + vector ubo_load_4_yw = vector(f16tof32(ubo_load_4 >> 16)); + return matrix(vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], ubo_load_yw[1]), vector(ubo_load_2_xz[0], ubo_load_2_yw[0], ubo_load_2_xz[1], ubo_load_2_yw[1]), vector(ubo_load_4_xz[0], ubo_load_4_yw[0], ubo_load_4_xz[1], ubo_load_4_yw[1])); +})"}, + TypeCase{ty_mat4x2, + R"(matrix tint_symbol(uint4 buffer[12], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint ubo_load = buffer[scalar_offset / 4][scalar_offset % 4]; + const uint scalar_offset_1 = ((offset + 4u)) / 4; + uint ubo_load_1 = buffer[scalar_offset_1 / 4][scalar_offset_1 % 4]; + const uint scalar_offset_2 = ((offset + 8u)) / 4; + uint ubo_load_2 = buffer[scalar_offset_2 / 4][scalar_offset_2 % 4]; + const uint scalar_offset_3 = ((offset + 12u)) / 4; + uint ubo_load_3 = buffer[scalar_offset_3 / 4][scalar_offset_3 % 4]; + return matrix(vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16))), vector(float16_t(f16tof32(ubo_load_1 & 0xFFFF)), float16_t(f16tof32(ubo_load_1 >> 16))), vector(float16_t(f16tof32(ubo_load_2 & 0xFFFF)), float16_t(f16tof32(ubo_load_2 >> 16))), vector(float16_t(f16tof32(ubo_load_3 & 0xFFFF)), float16_t(f16tof32(ubo_load_3 >> 16)))); +})"}, + TypeCase{ty_mat4x3, + R"(matrix tint_symbol(uint4 buffer[16], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16); + const uint scalar_offset_3 = ((offset + 24u)) / 4; + uint4 ubo_load_7 = buffer[scalar_offset_3 / 4]; + uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy); + vector ubo_load_6_xz = vector(f16tof32(ubo_load_6 & 0xFFFF)); + float16_t ubo_load_6_y = f16tof32(ubo_load_6[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1]), vector(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1]), vector(ubo_load_6_xz[0], ubo_load_6_y, ubo_load_6_xz[1])); +})"}, + TypeCase{ty_mat4x4, + R"(matrix tint_symbol(uint4 buffer[16], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + vector ubo_load_yw = vector(f16tof32(ubo_load >> 16)); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + vector ubo_load_2_yw = vector(f16tof32(ubo_load_2 >> 16)); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + vector ubo_load_4_yw = vector(f16tof32(ubo_load_4 >> 16)); + const uint scalar_offset_3 = ((offset + 24u)) / 4; + uint4 ubo_load_7 = buffer[scalar_offset_3 / 4]; + uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy); + vector ubo_load_6_xz = vector(f16tof32(ubo_load_6 & 0xFFFF)); + vector ubo_load_6_yw = vector(f16tof32(ubo_load_6 >> 16)); + return matrix(vector(ubo_load_xz[0], ubo_load_yw[0], ubo_load_xz[1], ubo_load_yw[1]), vector(ubo_load_2_xz[0], ubo_load_2_yw[0], ubo_load_2_xz[1], ubo_load_2_yw[1]), vector(ubo_load_4_xz[0], ubo_load_4_yw[0], ubo_load_4_xz[1], ubo_load_4_yw[1]), vector(ubo_load_6_xz[0], ubo_load_6_yw[0], ubo_load_6_xz[1], ubo_load_6_yw[1])); +})"})); using HlslGeneratorImplTest_MemberAccessor_StorageBufferStore = HlslGeneratorImplTest_MemberAccessorWithParam; TEST_P(HlslGeneratorImplTest_MemberAccessor_StorageBufferStore, Test) { // struct Data { - // a : i32; - // b : ; + // a : i32, + // b : , // }; // var data : Data; // data.b = (); auto p = GetParam(); + Enable(ast::Extension::kF16); + SetupStorageBuffer(utils::Vector{ Member("a", ty.i32()), Member("b", p.member_type(ty)), @@ -243,73 +1010,123 @@ TEST_P(HlslGeneratorImplTest_MemberAccessor_StorageBufferStore, Test) { EXPECT_THAT(gen.result(), HasSubstr(p.expected)); } -INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest_MemberAccessor, - HlslGeneratorImplTest_MemberAccessor_StorageBufferStore, - testing::Values(TypeCase{ty_u32, "data.Store(4u, asuint(value))"}, - TypeCase{ty_f32, "data.Store(4u, asuint(value))"}, - TypeCase{ty_i32, "data.Store(4u, asuint(value))"}, - TypeCase{ty_vec2, "data.Store2(8u, asuint(value))"}, - TypeCase{ty_vec2, "data.Store2(8u, asuint(value))"}, - TypeCase{ty_vec2, "data.Store2(8u, asuint(value))"}, - TypeCase{ty_vec3, "data.Store3(16u, asuint(value))"}, - TypeCase{ty_vec3, "data.Store3(16u, asuint(value))"}, - TypeCase{ty_vec3, "data.Store3(16u, asuint(value))"}, - TypeCase{ty_vec4, "data.Store4(16u, asuint(value))"}, - TypeCase{ty_vec4, "data.Store4(16u, asuint(value))"}, - TypeCase{ty_vec4, "data.Store4(16u, asuint(value))"}, - TypeCase{ty_mat2x2, R"({ +INSTANTIATE_TEST_SUITE_P( + HlslGeneratorImplTest_MemberAccessor, + HlslGeneratorImplTest_MemberAccessor_StorageBufferStore, + testing::Values(TypeCase{ty_u32, "data.Store(4u, asuint(value))"}, + TypeCase{ty_f32, "data.Store(4u, asuint(value))"}, + TypeCase{ty_i32, "data.Store(4u, asuint(value))"}, + TypeCase{ty_f16, "data.Store(4u, value)"}, + TypeCase{ty_vec2, "data.Store2(8u, asuint(value))"}, + TypeCase{ty_vec2, "data.Store2(8u, asuint(value))"}, + TypeCase{ty_vec2, "data.Store2(8u, asuint(value))"}, + TypeCase{ty_vec2, "data.Store >(4u, value)"}, + TypeCase{ty_vec3, "data.Store3(16u, asuint(value))"}, + TypeCase{ty_vec3, "data.Store3(16u, asuint(value))"}, + TypeCase{ty_vec3, "data.Store3(16u, asuint(value))"}, + TypeCase{ty_vec3, "data.Store >(8u, value)"}, + TypeCase{ty_vec4, "data.Store4(16u, asuint(value))"}, + TypeCase{ty_vec4, "data.Store4(16u, asuint(value))"}, + TypeCase{ty_vec4, "data.Store4(16u, asuint(value))"}, + TypeCase{ty_vec4, "data.Store >(8u, value)"}, + TypeCase{ty_mat2x2, R"({ buffer.Store2((offset + 0u), asuint(value[0u])); buffer.Store2((offset + 8u), asuint(value[1u])); })"}, - TypeCase{ty_mat2x3, R"({ + TypeCase{ty_mat2x3, R"({ buffer.Store3((offset + 0u), asuint(value[0u])); buffer.Store3((offset + 16u), asuint(value[1u])); })"}, - TypeCase{ty_mat2x4, R"({ + TypeCase{ty_mat2x4, R"({ buffer.Store4((offset + 0u), asuint(value[0u])); buffer.Store4((offset + 16u), asuint(value[1u])); })"}, - TypeCase{ty_mat3x2, R"({ + TypeCase{ty_mat3x2, R"({ buffer.Store2((offset + 0u), asuint(value[0u])); buffer.Store2((offset + 8u), asuint(value[1u])); buffer.Store2((offset + 16u), asuint(value[2u])); })"}, - TypeCase{ty_mat3x3, R"({ + TypeCase{ty_mat3x3, R"({ buffer.Store3((offset + 0u), asuint(value[0u])); buffer.Store3((offset + 16u), asuint(value[1u])); buffer.Store3((offset + 32u), asuint(value[2u])); })"}, - TypeCase{ty_mat3x4, R"({ + TypeCase{ty_mat3x4, R"({ buffer.Store4((offset + 0u), asuint(value[0u])); buffer.Store4((offset + 16u), asuint(value[1u])); buffer.Store4((offset + 32u), asuint(value[2u])); })"}, - TypeCase{ty_mat4x2, R"({ + TypeCase{ty_mat4x2, R"({ buffer.Store2((offset + 0u), asuint(value[0u])); buffer.Store2((offset + 8u), asuint(value[1u])); buffer.Store2((offset + 16u), asuint(value[2u])); buffer.Store2((offset + 24u), asuint(value[3u])); })"}, - TypeCase{ty_mat4x3, R"({ + TypeCase{ty_mat4x3, R"({ buffer.Store3((offset + 0u), asuint(value[0u])); buffer.Store3((offset + 16u), asuint(value[1u])); buffer.Store3((offset + 32u), asuint(value[2u])); buffer.Store3((offset + 48u), asuint(value[3u])); })"}, - TypeCase{ty_mat4x4, R"({ + TypeCase{ty_mat4x4, R"({ buffer.Store4((offset + 0u), asuint(value[0u])); buffer.Store4((offset + 16u), asuint(value[1u])); buffer.Store4((offset + 32u), asuint(value[2u])); buffer.Store4((offset + 48u), asuint(value[3u])); +})"}, + TypeCase{ty_mat2x2, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 4u), value[1u]); +})"}, + TypeCase{ty_mat2x3, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 8u), value[1u]); +})"}, + TypeCase{ty_mat2x4, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 8u), value[1u]); +})"}, + TypeCase{ty_mat3x2, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 4u), value[1u]); + buffer.Store >((offset + 8u), value[2u]); +})"}, + TypeCase{ty_mat3x3, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 8u), value[1u]); + buffer.Store >((offset + 16u), value[2u]); +})"}, + TypeCase{ty_mat3x4, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 8u), value[1u]); + buffer.Store >((offset + 16u), value[2u]); +})"}, + TypeCase{ty_mat4x2, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 4u), value[1u]); + buffer.Store >((offset + 8u), value[2u]); + buffer.Store >((offset + 12u), value[3u]); +})"}, + TypeCase{ty_mat4x3, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 8u), value[1u]); + buffer.Store >((offset + 16u), value[2u]); + buffer.Store >((offset + 24u), value[3u]); +})"}, + TypeCase{ty_mat4x4, R"({ + buffer.Store >((offset + 0u), value[0u]); + buffer.Store >((offset + 8u), value[1u]); + buffer.Store >((offset + 16u), value[2u]); + buffer.Store >((offset + 24u), value[3u]); })"})); TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_Matrix_Empty) { // struct Data { - // z : f32; - // a : mat2x3; + // a : f32, + // b : mat2x3, // }; // var data : Data; - // data.a = mat2x3(); + // data.b = mat2x3(); SetupStorageBuffer(utils::Vector{ Member("a", ty.i32()), @@ -339,10 +1156,10 @@ void main() { EXPECT_EQ(gen.result(), expected); } -TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_Matrix_Single_Element) { +TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_Matrix_F32_Single_Element) { // struct Data { - // z : f32; - // a : mat4x3; + // z : f32, + // a : mat4x3, // }; // var data : Data; // data.a[2i][1i]; @@ -370,17 +1187,119 @@ void main() { EXPECT_EQ(gen.result(), expected); } -TEST_F(HlslGeneratorImplTest_MemberAccessor, - EmitExpression_IndexAccessor_StorageBuffer_Load_Int_FromArray) { +TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_Matrix_F16_Single_Element) { // struct Data { - // a : array; + // z : f16, + // a : mat4x3, + // }; + // var data : Data; + // data.a[2i][1i]; + + Enable(ast::Extension::kF16); + + SetupStorageBuffer(utils::Vector{ + Member("z", ty.f16()), + Member("a", ty.mat4x3()), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2_i), 1_i))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(RWByteAddressBuffer data : register(u0, space1); + +void main() { + float16_t x = data.Load(26u); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, UniformBuffer_Load_Matrix_F32_Single_Element) { + // struct Data { + // z : f32, + // a : mat4x3, + // }; + // var data : Data; + // data.a[2i][1i]; + + SetupUniformBuffer(utils::Vector{ + Member("z", ty.f32()), + Member("a", ty.mat4x3()), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2_i), 1_i))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(cbuffer cbuffer_data : register(b1, space1) { + uint4 data[5]; +}; + +void main() { + float x = asfloat(data[3].y); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, UniformBuffer_Load_Matrix_F16_Single_Element) { + // struct Data { + // z : f16, + // a : mat4x3, + // }; + // var data : Data; + // data.a[2i][1i]; + + Enable(ast::Extension::kF16); + + SetupUniformBuffer(utils::Vector{ + Member("z", ty.f16()), + Member("a", ty.mat4x3()), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2_i), 1_i))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(cbuffer cbuffer_data : register(b1, space1) { + uint4 data[3]; +}; + +void main() { + float16_t x = float16_t(f16tof32(((data[1].z >> 16) & 0xFFFF))); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, + EmitExpression_IndexAccessor_StorageBuffer_Load_I32_FromArray) { + // struct Data { + // z : f32, + // a : array, // }; // var data : Data; // data.a[2]; SetupStorageBuffer(utils::Vector{ Member("z", ty.f32()), - Member("a", ty.array(4)), + Member("a", ty.array(ty.i32(), 5_i)), }); SetupFunction(utils::Vector{ @@ -402,16 +1321,154 @@ void main() { } TEST_F(HlslGeneratorImplTest_MemberAccessor, - EmitExpression_IndexAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) { + EmitExpression_IndexAccessor_UniformBuffer_Load_Vec4_I32_FromArray) { // struct Data { - // a : array; + // z : f32, + // a : array, 5i>, + // }; + // var data : Data; + // data.a[2]; + + SetupUniformBuffer(utils::Vector{ + Member("z", ty.f32()), + Member("a", ty.array(ty.vec4(ty.i32()), 5_i)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", IndexAccessor(MemberAccessor("data", "a"), 2_i))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(cbuffer cbuffer_data : register(b1, space1) { + uint4 data[6]; +}; + +void main() { + int4 x = asint(data[3]); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, + EmitExpression_IndexAccessor_StorageBuffer_Load_Struct_FromArray) { + // struct Inner { + // @size(16i) @align(16i) + // v : i32, + // }; + // struct Data { + // z : f32, + // a : array, + // }; + // var data : Data; + // data.a[2i]; + + auto* elem_type = Structure( + "Inner", utils::Vector{ + Member("v", ty.i32(), utils::Vector{MemberSize(16_i), MemberAlign(16_i)}), + }); + + SetupStorageBuffer(utils::Vector{ + Member("z", ty.f32()), + Member("a", ty.array(ty.Of(elem_type), 5_i)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", IndexAccessor(MemberAccessor("data", "a"), 2_i))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(struct Inner { + int v; +}; + +RWByteAddressBuffer data : register(u0, space1); + +Inner tint_symbol(RWByteAddressBuffer buffer, uint offset) { + const Inner tint_symbol_2 = {asint(buffer.Load((offset + 0u)))}; + return tint_symbol_2; +} + +void main() { + Inner x = tint_symbol(data, 48u); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, + EmitExpression_IndexAccessor_UniformBuffer_Load_Struct_FromArray) { + // struct Inner { + // @size(16i) @align(16i) + // v : i32, + // }; + // struct Data { + // z : f32, + // a : array, + // }; + // var data : Data; + // data.a[2i]; + + auto* elem_type = Structure( + "Inner", utils::Vector{ + Member("v", ty.i32(), utils::Vector{MemberSize(16_i), MemberAlign(16_i)}), + }); + + SetupUniformBuffer(utils::Vector{ + Member("z", ty.f32()), + Member("a", ty.array(ty.Of(elem_type), 5_i)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", IndexAccessor(MemberAccessor("data", "a"), 2_i))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(struct Inner { + int v; +}; + +cbuffer cbuffer_data : register(b1, space1) { + uint4 data[6]; +}; + +Inner tint_symbol(uint4 buffer[6], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const Inner tint_symbol_2 = {asint(buffer[scalar_offset / 4][scalar_offset % 4])}; + return tint_symbol_2; +} + +void main() { + Inner x = tint_symbol(data, 48u); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, + EmitExpression_IndexAccessor_StorageBuffer_Load_I32_FromArray_ExprIdx) { + // struct Data { + // z : f32, + // a : array, // }; // var data : Data; // data.a[(2i + 4i) - 3i]; SetupStorageBuffer(utils::Vector{ Member("z", ty.f32()), - Member("a", ty.array(4)), + Member("a", ty.array(ty.i32(), 5_i)), }); SetupFunction(utils::Vector{ @@ -438,16 +1495,57 @@ void main() { EXPECT_EQ(gen.result(), expected); } +TEST_F(HlslGeneratorImplTest_MemberAccessor, + EmitExpression_IndexAccessor_UniformBuffer_Load_Vec4_I32_FromArray_ExprIdx) { + // struct Data { + // z : f32, + // a : array, 5i>, + // }; + // var data : Data; + // data.a[(2i + 4i) - 3i]; + + SetupUniformBuffer(utils::Vector{ + Member("z", ty.f32()), + Member("a", ty.array(ty.vec4(ty.i32()), 5_i)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("a", Expr(2_i))), + Decl(Var("b", Expr(4_i))), + Decl(Var("c", Expr(3_i))), + Decl(Var("x", IndexAccessor(MemberAccessor("data", "a"), Sub(Add("a", "b"), "c")))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(cbuffer cbuffer_data : register(b1, space1) { + uint4 data[6]; +}; + +void main() { + int a = 2; + int b = 4; + int c = 3; + const uint scalar_offset = ((16u + (16u * uint(((a + b) - c))))) / 4; + int4 x = asint(data[scalar_offset / 4]); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_ToArray) { // struct Data { - // a : array; + // a : array, // }; // var data : Data; - // data.a[2] = 2; + // data.a[2i] = 2i; SetupStorageBuffer(utils::Vector{ Member("z", ty.f32()), - Member("a", ty.array(4)), + Member("a", ty.array(ty.i32(), 5_i)), }); SetupFunction(utils::Vector{ @@ -470,23 +1568,23 @@ void main() { TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel) { // struct Inner { - // a : vec3; - // b : vec3; + // a : vec3, + // b : vec3, // }; // struct Data { - // var c : array; + // c : array, // }; // - // var data : Pre; - // data.c[2].b + // var data : Data; + // data.c[2i].b auto* inner = Structure("Inner", utils::Vector{ - Member("a", ty.vec3()), + Member("a", ty.vec3()), Member("b", ty.vec3()), }); SetupStorageBuffer(utils::Vector{ - Member("c", ty.array(ty.Of(inner), 4_u, 32)), + Member("c", ty.array(ty.Of(inner), 4_u)), }); SetupFunction(utils::Vector{ @@ -507,31 +1605,72 @@ void main() { EXPECT_EQ(gen.result(), expected); } -TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel_Swizzle) { +TEST_F(HlslGeneratorImplTest_MemberAccessor, UniformBuffer_Load_MultiLevel) { // struct Inner { - // a : vec3; - // b : vec3; + // a : vec3, + // b : vec3, // }; // struct Data { - // var c : array; + // var c : array, // }; // - // var data : Pre; - // data.c[2].b.xy + // var data : Data; + // data.c[2i].b auto* inner = Structure("Inner", utils::Vector{ - Member("a", ty.vec3()), + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); + + SetupUniformBuffer(utils::Vector{ + Member("c", ty.array(ty.Of(inner), 4_u)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(cbuffer cbuffer_data : register(b1, space1) { + uint4 data[8]; +}; + +void main() { + float3 x = asfloat(data[5].xyz); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel_Swizzle) { + // struct Inner { + // a : vec3, + // b : vec3, + // }; + // struct Data { + // var c : array, + // }; + // + // var data : Data; + // data.c[2i].b.yx + + auto* inner = Structure("Inner", utils::Vector{ + Member("a", ty.vec3()), Member("b", ty.vec3()), }); SetupStorageBuffer(utils::Vector{ - Member("c", ty.array(ty.Of(inner), 4_u, 32)), + Member("c", ty.array(ty.Of(inner), 4_u)), }); SetupFunction(utils::Vector{ Decl(Var("x", MemberAccessor( - MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "xy"))), + MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "yx"))), }); GeneratorImpl& gen = SanitizeAndBuild(); @@ -541,7 +1680,50 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel_Swizz R"(RWByteAddressBuffer data : register(u0, space1); void main() { - float2 x = asfloat(data.Load3(80u)).xy; + float2 x = asfloat(data.Load3(80u)).yx; + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, UniformBuffer_Load_MultiLevel_Swizzle) { + // struct Inner { + // a : vec3, + // b : vec3, + // }; + // struct Data { + // var c : array, + // }; + // + // var data : Data; + // data.c[2i].b.yx + + auto* inner = Structure("Inner", utils::Vector{ + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); + + SetupUniformBuffer(utils::Vector{ + Member("c", ty.array(ty.Of(inner), 4_u)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", + MemberAccessor( + MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "yx"))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(cbuffer cbuffer_data : register(b1, space1) { + uint4 data[8]; +}; + +void main() { + float2 x = asfloat(data[5].xyz).yx; return; } )"; @@ -551,23 +1733,23 @@ void main() { TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel_Swizzle_SingleLetter) { // NOLINT // struct Inner { - // a : vec3; - // b : vec3; + // a : vec3, + // b : vec3, // }; // struct Data { - // var c : array; + // var c : array, // }; // - // var data : Pre; - // data.c[2].b.g + // var data : Data; + // data.c[2i].b.g auto* inner = Structure("Inner", utils::Vector{ - Member("a", ty.vec3()), + Member("a", ty.vec3()), Member("b", ty.vec3()), }); SetupStorageBuffer(utils::Vector{ - Member("c", ty.array(ty.Of(inner), 4_u, 32)), + Member("c", ty.array(ty.Of(inner), 4_u)), }); SetupFunction(utils::Vector{ @@ -590,25 +1772,69 @@ void main() { EXPECT_EQ(gen.result(), expected); } -TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel_Index) { +TEST_F(HlslGeneratorImplTest_MemberAccessor, + UniformBuffer_Load_MultiLevel_Swizzle_SingleLetter) { // NOLINT // struct Inner { - // a : vec3; - // b : vec3; + // a : vec3, + // b : vec3, // }; // struct Data { - // var c : array; + // var c : array, // }; // - // var data : Pre; - // data.c[2].b[1] + // var data : Data; + // data.c[2i].b.g auto* inner = Structure("Inner", utils::Vector{ - Member("a", ty.vec3()), + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); + + SetupUniformBuffer(utils::Vector{ + Member("c", ty.array(ty.Of(inner), 4_u)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", + MemberAccessor( + MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "g"))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(cbuffer cbuffer_data : register(b1, space1) { + uint4 data[8]; +}; + +void main() { + float x = asfloat(data[5].y); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel_Index) { + // struct Inner { + // a : vec3, + // b : vec3, + // }; + // struct Data { + // var c : array, + // }; + // + // var data : Data; + // data.c[2i].b[1i] + + auto* inner = Structure("Inner", utils::Vector{ + Member("a", ty.vec3()), Member("b", ty.vec3()), }); SetupStorageBuffer(utils::Vector{ - Member("c", ty.array(ty.Of(inner), 4_u, 32)), + Member("c", ty.array(ty.Of(inner), 4_u)), }); SetupFunction(utils::Vector{ @@ -631,25 +1857,68 @@ void main() { EXPECT_EQ(gen.result(), expected); } -TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_MultiLevel) { +TEST_F(HlslGeneratorImplTest_MemberAccessor, UniformBuffer_Load_MultiLevel_Index) { // struct Inner { - // a : vec3; - // b : vec3; + // a : vec3, + // b : vec3, // }; // struct Data { - // var c : array; + // var c : array, + // }; + // + // var data : Data; + // data.c[2i].b[1i] + + auto* inner = Structure("Inner", utils::Vector{ + Member("a", ty.vec3()), + Member("b", ty.vec3()), + }); + + SetupUniformBuffer(utils::Vector{ + Member("c", ty.array(ty.Of(inner), 4_u)), + }); + + SetupFunction(utils::Vector{ + Decl(Var("x", + IndexAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), + 1_i))), + }); + + GeneratorImpl& gen = SanitizeAndBuild(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + auto* expected = + R"(cbuffer cbuffer_data : register(b1, space1) { + uint4 data[8]; +}; + +void main() { + float x = asfloat(data[5].y); + return; +} +)"; + EXPECT_EQ(gen.result(), expected); +} + +TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_MultiLevel) { + // struct Inner { + // a : vec3, + // b : vec3, + // }; + // struct Data { + // var c : array, // }; // // var data : Pre; - // data.c[2].b = vec3(1_f, 2_f, 3_f); + // data.c[2i].b = vec3(1_f, 2_f, 3_f); auto* inner = Structure("Inner", utils::Vector{ - Member("a", ty.vec3()), + Member("a", ty.vec3()), Member("b", ty.vec3()), }); SetupStorageBuffer(utils::Vector{ - Member("c", ty.array(ty.Of(inner), 4_u, 32)), + Member("c", ty.array(ty.Of(inner), 4_u)), }); SetupFunction(utils::Vector{ @@ -673,15 +1942,15 @@ void main() { TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_Swizzle_SingleLetter) { // struct Inner { - // a : vec3; - // b : vec3; + // a : vec3, + // b : vec3, // }; // struct Data { - // var c : array; + // var c : array, // }; // // var data : Pre; - // data.c[2].b.y = 1.f; + // data.c[2i].b.y = 1.f; auto* inner = Structure("Inner", utils::Vector{ Member("a", ty.vec3()), @@ -689,7 +1958,7 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_Swizzle_SingleL }); SetupStorageBuffer(utils::Vector{ - Member("c", ty.array(ty.Of(inner), 4_u, 32)), + Member("c", ty.array(ty.Of(inner), 4_u)), }); SetupFunction(utils::Vector{ diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc index 9b1e0775f8..c5e4a381af 100644 --- a/src/tint/writer/spirv/builder.cc +++ b/src/tint/writer/spirv/builder.cc @@ -3955,11 +3955,7 @@ uint32_t Builder::GenerateStructMember(uint32_t struct_id, if (matrix_type) { push_annot(spv::Op::OpMemberDecorate, {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationColMajor)}); - if (!matrix_type->type()->Is()) { - error_ = "matrix scalar element type must be f32"; - return 0; - } - const uint32_t scalar_elem_size = 4; + const uint32_t scalar_elem_size = matrix_type->type()->Size(); const uint32_t effective_row_count = (matrix_type->rows() == 2) ? 2 : 4; push_annot(spv::Op::OpMemberDecorate, {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationMatrixStride), diff --git a/src/tint/writer/spirv/builder_type_test.cc b/src/tint/writer/spirv/builder_type_test.cc index a17dcb5e3b..4377c424df 100644 --- a/src/tint/writer/spirv/builder_type_test.cc +++ b/src/tint/writer/spirv/builder_type_test.cc @@ -317,7 +317,9 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) { } TEST_F(BuilderTest_Type, GenerateStruct) { - auto* s = Structure("my_struct", utils::Vector{Member("a", ty.f32())}); + Enable(ast::Extension::kF16); + + auto* s = Structure("my_struct", utils::Vector{Member("a", ty.f32()), Member("b", ty.f16())}); spirv::Builder& b = Build(); @@ -326,17 +328,23 @@ TEST_F(BuilderTest_Type, GenerateStruct) { EXPECT_EQ(id, 1u); EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32 -%1 = OpTypeStruct %2 +%3 = OpTypeFloat 16 +%1 = OpTypeStruct %2 %3 )"); EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_struct" OpMemberName %1 0 "a" +OpMemberName %1 1 "b" )"); } TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers) { + Enable(ast::Extension::kF16); + auto* s = Structure("S", utils::Vector{ Member("a", ty.f32()), Member("b", ty.f32(), utils::Vector{MemberAlign(8_i)}), + Member("c", ty.f16(), utils::Vector{MemberAlign(8_u)}), + Member("d", ty.f16()), }); spirv::Builder& b = Build(); @@ -346,23 +354,34 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers) { EXPECT_EQ(id, 1u); EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32 -%1 = OpTypeStruct %2 %2 +%3 = OpTypeFloat 16 +%1 = OpTypeStruct %2 %2 %3 %3 )"); EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S" OpMemberName %1 0 "a" OpMemberName %1 1 "b" +OpMemberName %1 2 "c" +OpMemberName %1 3 "d" )"); EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0 OpMemberDecorate %1 1 Offset 8 +OpMemberDecorate %1 2 Offset 16 +OpMemberDecorate %1 3 Offset 18 )"); } -TEST_F(BuilderTest_Type, GenerateStruct_NonLayout_Matrix) { - auto* s = Structure("S", utils::Vector{ - Member("a", ty.mat2x2()), - Member("b", ty.mat2x3()), - Member("c", ty.mat4x4()), - }); +TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_Matrix) { + Enable(ast::Extension::kF16); + + auto* s = + Structure("S", utils::Vector{ + Member("mat2x2_f32", ty.mat2x2()), + Member("mat2x3_f32", ty.mat2x3(), utils::Vector{MemberAlign(64_i)}), + Member("mat4x4_f32", ty.mat4x4()), + Member("mat2x2_f16", ty.mat2x2(), utils::Vector{MemberAlign(32_i)}), + Member("mat2x3_f16", ty.mat2x3()), + Member("mat4x4_f16", ty.mat4x4(), utils::Vector{MemberAlign(64_i)}), + }); spirv::Builder& b = Build(); @@ -377,78 +396,63 @@ TEST_F(BuilderTest_Type, GenerateStruct_NonLayout_Matrix) { %5 = OpTypeMatrix %6 2 %8 = OpTypeVector %4 4 %7 = OpTypeMatrix %8 4 -%1 = OpTypeStruct %2 %5 %7 +%11 = OpTypeFloat 16 +%10 = OpTypeVector %11 2 +%9 = OpTypeMatrix %10 2 +%13 = OpTypeVector %11 3 +%12 = OpTypeMatrix %13 2 +%15 = OpTypeVector %11 4 +%14 = OpTypeMatrix %15 4 +%1 = OpTypeStruct %2 %5 %7 %9 %12 %14 )"); EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S" -OpMemberName %1 0 "a" -OpMemberName %1 1 "b" -OpMemberName %1 2 "c" +OpMemberName %1 0 "mat2x2_f32" +OpMemberName %1 1 "mat2x3_f32" +OpMemberName %1 2 "mat4x4_f32" +OpMemberName %1 3 "mat2x2_f16" +OpMemberName %1 4 "mat2x3_f16" +OpMemberName %1 5 "mat4x4_f16" )"); EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0 OpMemberDecorate %1 0 ColMajor OpMemberDecorate %1 0 MatrixStride 8 -OpMemberDecorate %1 1 Offset 16 +OpMemberDecorate %1 1 Offset 64 OpMemberDecorate %1 1 ColMajor OpMemberDecorate %1 1 MatrixStride 16 -OpMemberDecorate %1 2 Offset 48 +OpMemberDecorate %1 2 Offset 96 OpMemberDecorate %1 2 ColMajor OpMemberDecorate %1 2 MatrixStride 16 +OpMemberDecorate %1 3 Offset 160 +OpMemberDecorate %1 3 ColMajor +OpMemberDecorate %1 3 MatrixStride 4 +OpMemberDecorate %1 4 Offset 168 +OpMemberDecorate %1 4 ColMajor +OpMemberDecorate %1 4 MatrixStride 8 +OpMemberDecorate %1 5 Offset 192 +OpMemberDecorate %1 5 ColMajor +OpMemberDecorate %1 5 MatrixStride 8 )"); } -TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutMatrix) { - // We have to infer layout for matrix when it also has an offset. - auto* s = Structure("S", utils::Vector{ - Member("a", ty.mat2x2()), - Member("b", ty.mat2x3()), - Member("c", ty.mat4x4()), - }); +TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_ArraysOfMatrix) { + Enable(ast::Extension::kF16); - spirv::Builder& b = Build(); - - auto id = b.GenerateTypeIfNeeded(program->TypeOf(s)); - ASSERT_FALSE(b.has_error()) << b.error(); - EXPECT_EQ(id, 1u); - - EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 -%3 = OpTypeVector %4 2 -%2 = OpTypeMatrix %3 2 -%6 = OpTypeVector %4 3 -%5 = OpTypeMatrix %6 2 -%8 = OpTypeVector %4 4 -%7 = OpTypeMatrix %8 4 -%1 = OpTypeStruct %2 %5 %7 -)"); - EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S" -OpMemberName %1 0 "a" -OpMemberName %1 1 "b" -OpMemberName %1 2 "c" -)"); - EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0 -OpMemberDecorate %1 0 ColMajor -OpMemberDecorate %1 0 MatrixStride 8 -OpMemberDecorate %1 1 Offset 16 -OpMemberDecorate %1 1 ColMajor -OpMemberDecorate %1 1 MatrixStride 16 -OpMemberDecorate %1 2 Offset 48 -OpMemberDecorate %1 2 ColMajor -OpMemberDecorate %1 2 MatrixStride 16 -)"); -} - -TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutArraysOfMatrix) { - // We have to infer layout for matrix when it also has an offset. - // The decoration goes on the struct member, even if the matrix is buried - // in levels of arrays. - auto* arr_mat2x2 = ty.array(ty.mat2x2(), 1_u); // Singly nested array - auto* arr_arr_mat2x3 = ty.array(ty.mat2x3(), 1_u); // Doubly nested array + auto* arr_mat2x2_f32 = ty.array(ty.mat2x2(), 1_u); // Singly nested array + auto* arr_mat2x2_f16 = ty.array(ty.mat2x2(), 1_u); // Singly nested array + auto* arr_arr_mat2x3_f32 = + ty.array(ty.array(ty.mat2x3(), 1_u), 2_u); // Doubly nested array + auto* arr_arr_mat2x3_f16 = + ty.array(ty.array(ty.mat2x3(), 1_u), 2_u); // Doubly nested array auto* rtarr_mat4x4 = ty.array(ty.mat4x4()); // Runtime array - auto* s = Structure("S", utils::Vector{ - Member("a", arr_mat2x2), - Member("b", arr_arr_mat2x3), - Member("c", rtarr_mat4x4), - }); + auto* s = Structure( + "S", utils::Vector{ + Member("arr_mat2x2_f32", arr_mat2x2_f32), + Member("arr_mat2x2_f16", arr_mat2x2_f16, utils::Vector{MemberAlign(64_i)}), + Member("arr_arr_mat2x3_f32", arr_arr_mat2x3_f32, utils::Vector{MemberAlign(64_i)}), + Member("arr_arr_mat2x3_f16", arr_arr_mat2x3_f16), + Member("rtarr_mat4x4", rtarr_mat4x4), + }); spirv::Builder& b = Build(); @@ -462,31 +466,53 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutArraysOfMatrix) { %6 = OpTypeInt 32 0 %7 = OpConstant %6 1 %2 = OpTypeArray %3 %7 -%10 = OpTypeVector %5 3 +%11 = OpTypeFloat 16 +%10 = OpTypeVector %11 2 %9 = OpTypeMatrix %10 2 %8 = OpTypeArray %9 %7 -%13 = OpTypeVector %5 4 -%12 = OpTypeMatrix %13 4 -%11 = OpTypeRuntimeArray %12 -%1 = OpTypeStruct %2 %8 %11 +%15 = OpTypeVector %5 3 +%14 = OpTypeMatrix %15 2 +%13 = OpTypeArray %14 %7 +%16 = OpConstant %6 2 +%12 = OpTypeArray %13 %16 +%20 = OpTypeVector %11 3 +%19 = OpTypeMatrix %20 2 +%18 = OpTypeArray %19 %7 +%17 = OpTypeArray %18 %16 +%23 = OpTypeVector %5 4 +%22 = OpTypeMatrix %23 4 +%21 = OpTypeRuntimeArray %22 +%1 = OpTypeStruct %2 %8 %12 %17 %21 )"); EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S" -OpMemberName %1 0 "a" -OpMemberName %1 1 "b" -OpMemberName %1 2 "c" +OpMemberName %1 0 "arr_mat2x2_f32" +OpMemberName %1 1 "arr_mat2x2_f16" +OpMemberName %1 2 "arr_arr_mat2x3_f32" +OpMemberName %1 3 "arr_arr_mat2x3_f16" +OpMemberName %1 4 "rtarr_mat4x4" )"); EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0 OpMemberDecorate %1 0 ColMajor OpMemberDecorate %1 0 MatrixStride 8 OpDecorate %2 ArrayStride 16 -OpMemberDecorate %1 1 Offset 16 +OpMemberDecorate %1 1 Offset 64 OpMemberDecorate %1 1 ColMajor -OpMemberDecorate %1 1 MatrixStride 16 -OpDecorate %8 ArrayStride 32 -OpMemberDecorate %1 2 Offset 48 +OpMemberDecorate %1 1 MatrixStride 4 +OpDecorate %8 ArrayStride 8 +OpMemberDecorate %1 2 Offset 128 OpMemberDecorate %1 2 ColMajor OpMemberDecorate %1 2 MatrixStride 16 -OpDecorate %11 ArrayStride 64 +OpDecorate %13 ArrayStride 32 +OpDecorate %12 ArrayStride 32 +OpMemberDecorate %1 3 Offset 192 +OpMemberDecorate %1 3 ColMajor +OpMemberDecorate %1 3 MatrixStride 8 +OpDecorate %18 ArrayStride 16 +OpDecorate %17 ArrayStride 16 +OpMemberDecorate %1 4 Offset 224 +OpMemberDecorate %1 4 ColMajor +OpMemberDecorate %1 4 MatrixStride 16 +OpDecorate %21 ArrayStride 64 )"); } diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.dxc.hlsl index 87e09025ee..269428379d 100644 --- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.dxc.hlsl +++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.dxc.hlsl @@ -1,17 +1,35 @@ -SKIP: FAILED +ByteAddressBuffer sb_ro : register(t1, space0); -builtins/gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +void arrayLength_8421b9() { + uint tint_symbol_2 = 0u; + sb_ro.GetDimensions(tint_symbol_2); + const uint tint_symbol_3 = ((tint_symbol_2 - 0u) / 2u); + uint res = tint_symbol_3; +} -builtins/gen/literal/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RO { -^^^^^^ +struct tint_symbol { + float4 value : SV_Position; +}; -builtins/gen/literal/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +float4 vertex_main_inner() { + arrayLength_8421b9(); + return (0.0f).xxxx; +} +tint_symbol vertex_main() { + const float4 inner_result = vertex_main_inner(); + tint_symbol wrapper_result = (tint_symbol)0; + wrapper_result.value = inner_result; + return wrapper_result; +} + +void fragment_main() { + arrayLength_8421b9(); + return; +} + +[numthreads(1, 1, 1)] +void compute_main() { + arrayLength_8421b9(); + return; +} diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.fxc.hlsl index 87e09025ee..269428379d 100644 --- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.fxc.hlsl +++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.fxc.hlsl @@ -1,17 +1,35 @@ -SKIP: FAILED +ByteAddressBuffer sb_ro : register(t1, space0); -builtins/gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +void arrayLength_8421b9() { + uint tint_symbol_2 = 0u; + sb_ro.GetDimensions(tint_symbol_2); + const uint tint_symbol_3 = ((tint_symbol_2 - 0u) / 2u); + uint res = tint_symbol_3; +} -builtins/gen/literal/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RO { -^^^^^^ +struct tint_symbol { + float4 value : SV_Position; +}; -builtins/gen/literal/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +float4 vertex_main_inner() { + arrayLength_8421b9(); + return (0.0f).xxxx; +} +tint_symbol vertex_main() { + const float4 inner_result = vertex_main_inner(); + tint_symbol wrapper_result = (tint_symbol)0; + wrapper_result.value = inner_result; + return wrapper_result; +} + +void fragment_main() { + arrayLength_8421b9(); + return; +} + +[numthreads(1, 1, 1)] +void compute_main() { + arrayLength_8421b9(); + return; +} diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.glsl index 87e09025ee..9375052837 100644 --- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.glsl +++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.glsl @@ -1,17 +1,64 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require -builtins/gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +layout(binding = 1, std430) buffer SB_RO_ssbo { + float16_t arg_0[]; +} sb_ro; -builtins/gen/literal/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RO { -^^^^^^ +void arrayLength_8421b9() { + uint res = uint(sb_ro.arg_0.length()); +} -builtins/gen/literal/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +vec4 vertex_main() { + arrayLength_8421b9(); + return vec4(0.0f); +} +void main() { + gl_PointSize = 1.0; + vec4 inner_result = vertex_main(); + gl_Position = inner_result; + gl_Position.y = -(gl_Position.y); + gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w); + return; +} +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require +precision mediump float; + +layout(binding = 1, std430) buffer SB_RO_ssbo { + float16_t arg_0[]; +} sb_ro; + +void arrayLength_8421b9() { + uint res = uint(sb_ro.arg_0.length()); +} + +void fragment_main() { + arrayLength_8421b9(); +} + +void main() { + fragment_main(); + return; +} +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require + +layout(binding = 1, std430) buffer SB_RO_ssbo { + float16_t arg_0[]; +} sb_ro; + +void arrayLength_8421b9() { + uint res = uint(sb_ro.arg_0.length()); +} + +void compute_main() { + arrayLength_8421b9(); +} + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void main() { + compute_main(); + return; +} diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.msl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.msl index 87e09025ee..3661b2237a 100644 --- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.msl +++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.msl @@ -1,17 +1,54 @@ -SKIP: FAILED +#include -builtins/gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; + +struct tint_symbol_1 { + /* 0x0000 */ tint_array buffer_size; +}; -builtins/gen/literal/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; struct SB_RO { -^^^^^^ + tint_array arg_0; +}; -builtins/gen/literal/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +void arrayLength_8421b9(const constant tint_symbol_1* const tint_symbol_3) { + uint res = (((*(tint_symbol_3)).buffer_size[0u][0u] - 0u) / 2u); +} + +struct tint_symbol { + float4 value [[position]]; +}; + +float4 vertex_main_inner(const constant tint_symbol_1* const tint_symbol_4) { + arrayLength_8421b9(tint_symbol_4); + return float4(0.0f); +} + +vertex tint_symbol vertex_main(const constant tint_symbol_1* tint_symbol_5 [[buffer(30)]]) { + float4 const inner_result = vertex_main_inner(tint_symbol_5); + tint_symbol wrapper_result = {}; + wrapper_result.value = inner_result; + return wrapper_result; +} + +fragment void fragment_main(const constant tint_symbol_1* tint_symbol_6 [[buffer(30)]]) { + arrayLength_8421b9(tint_symbol_6); + return; +} + +kernel void compute_main(const constant tint_symbol_1* tint_symbol_7 [[buffer(30)]]) { + arrayLength_8421b9(tint_symbol_7); + return; +} diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.spvasm index 87e09025ee..485ba209d5 100644 --- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.spvasm +++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.spvasm @@ -1,17 +1,84 @@ -SKIP: FAILED - -builtins/gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ - -builtins/gen/literal/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RO { -^^^^^^ - -builtins/gen/literal/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 37 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size + OpEntryPoint Fragment %fragment_main "fragment_main" + OpEntryPoint GLCompute %compute_main "compute_main" + OpExecutionMode %fragment_main OriginUpperLeft + OpExecutionMode %compute_main LocalSize 1 1 1 + OpName %value "value" + OpName %vertex_point_size "vertex_point_size" + OpName %SB_RO "SB_RO" + OpMemberName %SB_RO 0 "arg_0" + OpName %sb_ro "sb_ro" + OpName %arrayLength_8421b9 "arrayLength_8421b9" + OpName %res "res" + OpName %vertex_main_inner "vertex_main_inner" + OpName %vertex_main "vertex_main" + OpName %fragment_main "fragment_main" + OpName %compute_main "compute_main" + OpDecorate %value BuiltIn Position + OpDecorate %vertex_point_size BuiltIn PointSize + OpDecorate %SB_RO Block + OpMemberDecorate %SB_RO 0 Offset 0 + OpDecorate %_runtimearr_half ArrayStride 2 + OpDecorate %sb_ro NonWritable + OpDecorate %sb_ro DescriptorSet 0 + OpDecorate %sb_ro Binding 1 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5 = OpConstantNull %v4float + %value = OpVariable %_ptr_Output_v4float Output %5 +%_ptr_Output_float = OpTypePointer Output %float + %8 = OpConstantNull %float +%vertex_point_size = OpVariable %_ptr_Output_float Output %8 + %half = OpTypeFloat 16 +%_runtimearr_half = OpTypeRuntimeArray %half + %SB_RO = OpTypeStruct %_runtimearr_half +%_ptr_StorageBuffer_SB_RO = OpTypePointer StorageBuffer %SB_RO + %sb_ro = OpVariable %_ptr_StorageBuffer_SB_RO StorageBuffer + %void = OpTypeVoid + %14 = OpTypeFunction %void + %uint = OpTypeInt 32 0 +%_ptr_Function_uint = OpTypePointer Function %uint + %22 = OpConstantNull %uint + %23 = OpTypeFunction %v4float + %float_1 = OpConstant %float 1 +%arrayLength_8421b9 = OpFunction %void None %14 + %17 = OpLabel + %res = OpVariable %_ptr_Function_uint Function %22 + %18 = OpArrayLength %uint %sb_ro 0 + OpStore %res %18 + OpReturn + OpFunctionEnd +%vertex_main_inner = OpFunction %v4float None %23 + %25 = OpLabel + %26 = OpFunctionCall %void %arrayLength_8421b9 + OpReturnValue %5 + OpFunctionEnd +%vertex_main = OpFunction %void None %14 + %28 = OpLabel + %29 = OpFunctionCall %v4float %vertex_main_inner + OpStore %value %29 + OpStore %vertex_point_size %float_1 + OpReturn + OpFunctionEnd +%fragment_main = OpFunction %void None %14 + %32 = OpLabel + %33 = OpFunctionCall %void %arrayLength_8421b9 + OpReturn + OpFunctionEnd +%compute_main = OpFunction %void None %14 + %35 = OpLabel + %36 = OpFunctionCall %void %arrayLength_8421b9 + OpReturn + OpFunctionEnd diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.wgsl index 87e09025ee..2d6dca3ef7 100644 --- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.wgsl +++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.wgsl @@ -1,17 +1,27 @@ -SKIP: FAILED +enable f16; -builtins/gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ - -builtins/gen/literal/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; struct SB_RO { -^^^^^^ + arg_0 : array, +} -builtins/gen/literal/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable @group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +fn arrayLength_8421b9() { + var res : u32 = arrayLength(&(sb_ro.arg_0)); +} + +@vertex +fn vertex_main() -> @builtin(position) vec4 { + arrayLength_8421b9(); + return vec4(); +} + +@fragment +fn fragment_main() { + arrayLength_8421b9(); +} + +@compute @workgroup_size(1) +fn compute_main() { + arrayLength_8421b9(); +} diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl index 7849c68390..c62bc2334d 100644 --- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl +++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl @@ -1,17 +1,35 @@ -SKIP: FAILED +RWByteAddressBuffer sb_rw : register(u0, space0); -builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +void arrayLength_cbd6b5() { + uint tint_symbol_2 = 0u; + sb_rw.GetDimensions(tint_symbol_2); + const uint tint_symbol_3 = ((tint_symbol_2 - 0u) / 2u); + uint res = tint_symbol_3; +} -builtins/gen/literal/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RW { -^^^^^^ +struct tint_symbol { + float4 value : SV_Position; +}; -builtins/gen/literal/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +float4 vertex_main_inner() { + arrayLength_cbd6b5(); + return (0.0f).xxxx; +} +tint_symbol vertex_main() { + const float4 inner_result = vertex_main_inner(); + tint_symbol wrapper_result = (tint_symbol)0; + wrapper_result.value = inner_result; + return wrapper_result; +} + +void fragment_main() { + arrayLength_cbd6b5(); + return; +} + +[numthreads(1, 1, 1)] +void compute_main() { + arrayLength_cbd6b5(); + return; +} diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl index 7849c68390..c62bc2334d 100644 --- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl +++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl @@ -1,17 +1,35 @@ -SKIP: FAILED +RWByteAddressBuffer sb_rw : register(u0, space0); -builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +void arrayLength_cbd6b5() { + uint tint_symbol_2 = 0u; + sb_rw.GetDimensions(tint_symbol_2); + const uint tint_symbol_3 = ((tint_symbol_2 - 0u) / 2u); + uint res = tint_symbol_3; +} -builtins/gen/literal/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RW { -^^^^^^ +struct tint_symbol { + float4 value : SV_Position; +}; -builtins/gen/literal/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +float4 vertex_main_inner() { + arrayLength_cbd6b5(); + return (0.0f).xxxx; +} +tint_symbol vertex_main() { + const float4 inner_result = vertex_main_inner(); + tint_symbol wrapper_result = (tint_symbol)0; + wrapper_result.value = inner_result; + return wrapper_result; +} + +void fragment_main() { + arrayLength_cbd6b5(); + return; +} + +[numthreads(1, 1, 1)] +void compute_main() { + arrayLength_cbd6b5(); + return; +} diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.glsl index 7849c68390..aeaf5a38b8 100644 --- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.glsl +++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.glsl @@ -1,17 +1,64 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require -builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +layout(binding = 0, std430) buffer SB_RW_ssbo { + float16_t arg_0[]; +} sb_rw; -builtins/gen/literal/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RW { -^^^^^^ +void arrayLength_cbd6b5() { + uint res = uint(sb_rw.arg_0.length()); +} -builtins/gen/literal/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +vec4 vertex_main() { + arrayLength_cbd6b5(); + return vec4(0.0f); +} +void main() { + gl_PointSize = 1.0; + vec4 inner_result = vertex_main(); + gl_Position = inner_result; + gl_Position.y = -(gl_Position.y); + gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w); + return; +} +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require +precision mediump float; + +layout(binding = 0, std430) buffer SB_RW_ssbo { + float16_t arg_0[]; +} sb_rw; + +void arrayLength_cbd6b5() { + uint res = uint(sb_rw.arg_0.length()); +} + +void fragment_main() { + arrayLength_cbd6b5(); +} + +void main() { + fragment_main(); + return; +} +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require + +layout(binding = 0, std430) buffer SB_RW_ssbo { + float16_t arg_0[]; +} sb_rw; + +void arrayLength_cbd6b5() { + uint res = uint(sb_rw.arg_0.length()); +} + +void compute_main() { + arrayLength_cbd6b5(); +} + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void main() { + compute_main(); + return; +} diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.msl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.msl index 7849c68390..86034e437c 100644 --- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.msl +++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.msl @@ -1,17 +1,54 @@ -SKIP: FAILED +#include -builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; + +struct tint_symbol_1 { + /* 0x0000 */ tint_array buffer_size; +}; -builtins/gen/literal/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; struct SB_RW { -^^^^^^ + tint_array arg_0; +}; -builtins/gen/literal/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +void arrayLength_cbd6b5(const constant tint_symbol_1* const tint_symbol_3) { + uint res = (((*(tint_symbol_3)).buffer_size[0u][0u] - 0u) / 2u); +} + +struct tint_symbol { + float4 value [[position]]; +}; + +float4 vertex_main_inner(const constant tint_symbol_1* const tint_symbol_4) { + arrayLength_cbd6b5(tint_symbol_4); + return float4(0.0f); +} + +vertex tint_symbol vertex_main(const constant tint_symbol_1* tint_symbol_5 [[buffer(30)]]) { + float4 const inner_result = vertex_main_inner(tint_symbol_5); + tint_symbol wrapper_result = {}; + wrapper_result.value = inner_result; + return wrapper_result; +} + +fragment void fragment_main(const constant tint_symbol_1* tint_symbol_6 [[buffer(30)]]) { + arrayLength_cbd6b5(tint_symbol_6); + return; +} + +kernel void compute_main(const constant tint_symbol_1* tint_symbol_7 [[buffer(30)]]) { + arrayLength_cbd6b5(tint_symbol_7); + return; +} diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.spvasm index 7849c68390..15031dee64 100644 --- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.spvasm +++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.spvasm @@ -1,17 +1,83 @@ -SKIP: FAILED - -builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ - -builtins/gen/literal/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RW { -^^^^^^ - -builtins/gen/literal/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 37 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size + OpEntryPoint Fragment %fragment_main "fragment_main" + OpEntryPoint GLCompute %compute_main "compute_main" + OpExecutionMode %fragment_main OriginUpperLeft + OpExecutionMode %compute_main LocalSize 1 1 1 + OpName %value "value" + OpName %vertex_point_size "vertex_point_size" + OpName %SB_RW "SB_RW" + OpMemberName %SB_RW 0 "arg_0" + OpName %sb_rw "sb_rw" + OpName %arrayLength_cbd6b5 "arrayLength_cbd6b5" + OpName %res "res" + OpName %vertex_main_inner "vertex_main_inner" + OpName %vertex_main "vertex_main" + OpName %fragment_main "fragment_main" + OpName %compute_main "compute_main" + OpDecorate %value BuiltIn Position + OpDecorate %vertex_point_size BuiltIn PointSize + OpDecorate %SB_RW Block + OpMemberDecorate %SB_RW 0 Offset 0 + OpDecorate %_runtimearr_half ArrayStride 2 + OpDecorate %sb_rw DescriptorSet 0 + OpDecorate %sb_rw Binding 0 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5 = OpConstantNull %v4float + %value = OpVariable %_ptr_Output_v4float Output %5 +%_ptr_Output_float = OpTypePointer Output %float + %8 = OpConstantNull %float +%vertex_point_size = OpVariable %_ptr_Output_float Output %8 + %half = OpTypeFloat 16 +%_runtimearr_half = OpTypeRuntimeArray %half + %SB_RW = OpTypeStruct %_runtimearr_half +%_ptr_StorageBuffer_SB_RW = OpTypePointer StorageBuffer %SB_RW + %sb_rw = OpVariable %_ptr_StorageBuffer_SB_RW StorageBuffer + %void = OpTypeVoid + %14 = OpTypeFunction %void + %uint = OpTypeInt 32 0 +%_ptr_Function_uint = OpTypePointer Function %uint + %22 = OpConstantNull %uint + %23 = OpTypeFunction %v4float + %float_1 = OpConstant %float 1 +%arrayLength_cbd6b5 = OpFunction %void None %14 + %17 = OpLabel + %res = OpVariable %_ptr_Function_uint Function %22 + %18 = OpArrayLength %uint %sb_rw 0 + OpStore %res %18 + OpReturn + OpFunctionEnd +%vertex_main_inner = OpFunction %v4float None %23 + %25 = OpLabel + %26 = OpFunctionCall %void %arrayLength_cbd6b5 + OpReturnValue %5 + OpFunctionEnd +%vertex_main = OpFunction %void None %14 + %28 = OpLabel + %29 = OpFunctionCall %v4float %vertex_main_inner + OpStore %value %29 + OpStore %vertex_point_size %float_1 + OpReturn + OpFunctionEnd +%fragment_main = OpFunction %void None %14 + %32 = OpLabel + %33 = OpFunctionCall %void %arrayLength_cbd6b5 + OpReturn + OpFunctionEnd +%compute_main = OpFunction %void None %14 + %35 = OpLabel + %36 = OpFunctionCall %void %arrayLength_cbd6b5 + OpReturn + OpFunctionEnd diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.wgsl index 7849c68390..c0255910b3 100644 --- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.wgsl +++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.wgsl @@ -1,17 +1,27 @@ -SKIP: FAILED +enable f16; -builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ - -builtins/gen/literal/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; struct SB_RW { -^^^^^^ + arg_0 : array, +} -builtins/gen/literal/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable @group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +fn arrayLength_cbd6b5() { + var res : u32 = arrayLength(&(sb_rw.arg_0)); +} + +@vertex +fn vertex_main() -> @builtin(position) vec4 { + arrayLength_cbd6b5(); + return vec4(); +} + +@fragment +fn fragment_main() { + arrayLength_cbd6b5(); +} + +@compute @workgroup_size(1) +fn compute_main() { + arrayLength_cbd6b5(); +} diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.dxc.hlsl index fc94710a29..269428379d 100644 --- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.dxc.hlsl +++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.dxc.hlsl @@ -1,17 +1,35 @@ -SKIP: FAILED +ByteAddressBuffer sb_ro : register(t1, space0); -builtins/gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +void arrayLength_8421b9() { + uint tint_symbol_2 = 0u; + sb_ro.GetDimensions(tint_symbol_2); + const uint tint_symbol_3 = ((tint_symbol_2 - 0u) / 2u); + uint res = tint_symbol_3; +} -builtins/gen/var/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RO { -^^^^^^ +struct tint_symbol { + float4 value : SV_Position; +}; -builtins/gen/var/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +float4 vertex_main_inner() { + arrayLength_8421b9(); + return (0.0f).xxxx; +} +tint_symbol vertex_main() { + const float4 inner_result = vertex_main_inner(); + tint_symbol wrapper_result = (tint_symbol)0; + wrapper_result.value = inner_result; + return wrapper_result; +} + +void fragment_main() { + arrayLength_8421b9(); + return; +} + +[numthreads(1, 1, 1)] +void compute_main() { + arrayLength_8421b9(); + return; +} diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.fxc.hlsl index fc94710a29..269428379d 100644 --- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.fxc.hlsl +++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.fxc.hlsl @@ -1,17 +1,35 @@ -SKIP: FAILED +ByteAddressBuffer sb_ro : register(t1, space0); -builtins/gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +void arrayLength_8421b9() { + uint tint_symbol_2 = 0u; + sb_ro.GetDimensions(tint_symbol_2); + const uint tint_symbol_3 = ((tint_symbol_2 - 0u) / 2u); + uint res = tint_symbol_3; +} -builtins/gen/var/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RO { -^^^^^^ +struct tint_symbol { + float4 value : SV_Position; +}; -builtins/gen/var/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +float4 vertex_main_inner() { + arrayLength_8421b9(); + return (0.0f).xxxx; +} +tint_symbol vertex_main() { + const float4 inner_result = vertex_main_inner(); + tint_symbol wrapper_result = (tint_symbol)0; + wrapper_result.value = inner_result; + return wrapper_result; +} + +void fragment_main() { + arrayLength_8421b9(); + return; +} + +[numthreads(1, 1, 1)] +void compute_main() { + arrayLength_8421b9(); + return; +} diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.glsl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.glsl index fc94710a29..9375052837 100644 --- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.glsl +++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.glsl @@ -1,17 +1,64 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require -builtins/gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +layout(binding = 1, std430) buffer SB_RO_ssbo { + float16_t arg_0[]; +} sb_ro; -builtins/gen/var/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RO { -^^^^^^ +void arrayLength_8421b9() { + uint res = uint(sb_ro.arg_0.length()); +} -builtins/gen/var/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +vec4 vertex_main() { + arrayLength_8421b9(); + return vec4(0.0f); +} +void main() { + gl_PointSize = 1.0; + vec4 inner_result = vertex_main(); + gl_Position = inner_result; + gl_Position.y = -(gl_Position.y); + gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w); + return; +} +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require +precision mediump float; + +layout(binding = 1, std430) buffer SB_RO_ssbo { + float16_t arg_0[]; +} sb_ro; + +void arrayLength_8421b9() { + uint res = uint(sb_ro.arg_0.length()); +} + +void fragment_main() { + arrayLength_8421b9(); +} + +void main() { + fragment_main(); + return; +} +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require + +layout(binding = 1, std430) buffer SB_RO_ssbo { + float16_t arg_0[]; +} sb_ro; + +void arrayLength_8421b9() { + uint res = uint(sb_ro.arg_0.length()); +} + +void compute_main() { + arrayLength_8421b9(); +} + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void main() { + compute_main(); + return; +} diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.msl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.msl index fc94710a29..3661b2237a 100644 --- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.msl +++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.msl @@ -1,17 +1,54 @@ -SKIP: FAILED +#include -builtins/gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; + +struct tint_symbol_1 { + /* 0x0000 */ tint_array buffer_size; +}; -builtins/gen/var/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; struct SB_RO { -^^^^^^ + tint_array arg_0; +}; -builtins/gen/var/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +void arrayLength_8421b9(const constant tint_symbol_1* const tint_symbol_3) { + uint res = (((*(tint_symbol_3)).buffer_size[0u][0u] - 0u) / 2u); +} + +struct tint_symbol { + float4 value [[position]]; +}; + +float4 vertex_main_inner(const constant tint_symbol_1* const tint_symbol_4) { + arrayLength_8421b9(tint_symbol_4); + return float4(0.0f); +} + +vertex tint_symbol vertex_main(const constant tint_symbol_1* tint_symbol_5 [[buffer(30)]]) { + float4 const inner_result = vertex_main_inner(tint_symbol_5); + tint_symbol wrapper_result = {}; + wrapper_result.value = inner_result; + return wrapper_result; +} + +fragment void fragment_main(const constant tint_symbol_1* tint_symbol_6 [[buffer(30)]]) { + arrayLength_8421b9(tint_symbol_6); + return; +} + +kernel void compute_main(const constant tint_symbol_1* tint_symbol_7 [[buffer(30)]]) { + arrayLength_8421b9(tint_symbol_7); + return; +} diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.spvasm index fc94710a29..485ba209d5 100644 --- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.spvasm +++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.spvasm @@ -1,17 +1,84 @@ -SKIP: FAILED - -builtins/gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ - -builtins/gen/var/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RO { -^^^^^^ - -builtins/gen/var/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable -@group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 37 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size + OpEntryPoint Fragment %fragment_main "fragment_main" + OpEntryPoint GLCompute %compute_main "compute_main" + OpExecutionMode %fragment_main OriginUpperLeft + OpExecutionMode %compute_main LocalSize 1 1 1 + OpName %value "value" + OpName %vertex_point_size "vertex_point_size" + OpName %SB_RO "SB_RO" + OpMemberName %SB_RO 0 "arg_0" + OpName %sb_ro "sb_ro" + OpName %arrayLength_8421b9 "arrayLength_8421b9" + OpName %res "res" + OpName %vertex_main_inner "vertex_main_inner" + OpName %vertex_main "vertex_main" + OpName %fragment_main "fragment_main" + OpName %compute_main "compute_main" + OpDecorate %value BuiltIn Position + OpDecorate %vertex_point_size BuiltIn PointSize + OpDecorate %SB_RO Block + OpMemberDecorate %SB_RO 0 Offset 0 + OpDecorate %_runtimearr_half ArrayStride 2 + OpDecorate %sb_ro NonWritable + OpDecorate %sb_ro DescriptorSet 0 + OpDecorate %sb_ro Binding 1 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5 = OpConstantNull %v4float + %value = OpVariable %_ptr_Output_v4float Output %5 +%_ptr_Output_float = OpTypePointer Output %float + %8 = OpConstantNull %float +%vertex_point_size = OpVariable %_ptr_Output_float Output %8 + %half = OpTypeFloat 16 +%_runtimearr_half = OpTypeRuntimeArray %half + %SB_RO = OpTypeStruct %_runtimearr_half +%_ptr_StorageBuffer_SB_RO = OpTypePointer StorageBuffer %SB_RO + %sb_ro = OpVariable %_ptr_StorageBuffer_SB_RO StorageBuffer + %void = OpTypeVoid + %14 = OpTypeFunction %void + %uint = OpTypeInt 32 0 +%_ptr_Function_uint = OpTypePointer Function %uint + %22 = OpConstantNull %uint + %23 = OpTypeFunction %v4float + %float_1 = OpConstant %float 1 +%arrayLength_8421b9 = OpFunction %void None %14 + %17 = OpLabel + %res = OpVariable %_ptr_Function_uint Function %22 + %18 = OpArrayLength %uint %sb_ro 0 + OpStore %res %18 + OpReturn + OpFunctionEnd +%vertex_main_inner = OpFunction %v4float None %23 + %25 = OpLabel + %26 = OpFunctionCall %void %arrayLength_8421b9 + OpReturnValue %5 + OpFunctionEnd +%vertex_main = OpFunction %void None %14 + %28 = OpLabel + %29 = OpFunctionCall %v4float %vertex_main_inner + OpStore %value %29 + OpStore %vertex_point_size %float_1 + OpReturn + OpFunctionEnd +%fragment_main = OpFunction %void None %14 + %32 = OpLabel + %33 = OpFunctionCall %void %arrayLength_8421b9 + OpReturn + OpFunctionEnd +%compute_main = OpFunction %void None %14 + %35 = OpLabel + %36 = OpFunctionCall %void %arrayLength_8421b9 + OpReturn + OpFunctionEnd diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.wgsl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.wgsl index fc94710a29..2d6dca3ef7 100644 --- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.wgsl +++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.wgsl @@ -1,17 +1,27 @@ -SKIP: FAILED +enable f16; -builtins/gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ - -builtins/gen/var/arrayLength/8421b9.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RO { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; struct SB_RO { -^^^^^^ + arg_0 : array, +} -builtins/gen/var/arrayLength/8421b9.wgsl:28:42 note: see declaration of variable @group(0) @binding(1) var sb_ro : SB_RO; - ^^^^^ +fn arrayLength_8421b9() { + var res : u32 = arrayLength(&(sb_ro.arg_0)); +} + +@vertex +fn vertex_main() -> @builtin(position) vec4 { + arrayLength_8421b9(); + return vec4(); +} + +@fragment +fn fragment_main() { + arrayLength_8421b9(); +} + +@compute @workgroup_size(1) +fn compute_main() { + arrayLength_8421b9(); +} diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl index f19d93a9c8..c62bc2334d 100644 --- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl +++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl @@ -1,17 +1,35 @@ -SKIP: FAILED +RWByteAddressBuffer sb_rw : register(u0, space0); -builtins/gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +void arrayLength_cbd6b5() { + uint tint_symbol_2 = 0u; + sb_rw.GetDimensions(tint_symbol_2); + const uint tint_symbol_3 = ((tint_symbol_2 - 0u) / 2u); + uint res = tint_symbol_3; +} -builtins/gen/var/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RW { -^^^^^^ +struct tint_symbol { + float4 value : SV_Position; +}; -builtins/gen/var/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +float4 vertex_main_inner() { + arrayLength_cbd6b5(); + return (0.0f).xxxx; +} +tint_symbol vertex_main() { + const float4 inner_result = vertex_main_inner(); + tint_symbol wrapper_result = (tint_symbol)0; + wrapper_result.value = inner_result; + return wrapper_result; +} + +void fragment_main() { + arrayLength_cbd6b5(); + return; +} + +[numthreads(1, 1, 1)] +void compute_main() { + arrayLength_cbd6b5(); + return; +} diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl index f19d93a9c8..c62bc2334d 100644 --- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl +++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl @@ -1,17 +1,35 @@ -SKIP: FAILED +RWByteAddressBuffer sb_rw : register(u0, space0); -builtins/gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +void arrayLength_cbd6b5() { + uint tint_symbol_2 = 0u; + sb_rw.GetDimensions(tint_symbol_2); + const uint tint_symbol_3 = ((tint_symbol_2 - 0u) / 2u); + uint res = tint_symbol_3; +} -builtins/gen/var/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RW { -^^^^^^ +struct tint_symbol { + float4 value : SV_Position; +}; -builtins/gen/var/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +float4 vertex_main_inner() { + arrayLength_cbd6b5(); + return (0.0f).xxxx; +} +tint_symbol vertex_main() { + const float4 inner_result = vertex_main_inner(); + tint_symbol wrapper_result = (tint_symbol)0; + wrapper_result.value = inner_result; + return wrapper_result; +} + +void fragment_main() { + arrayLength_cbd6b5(); + return; +} + +[numthreads(1, 1, 1)] +void compute_main() { + arrayLength_cbd6b5(); + return; +} diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.glsl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.glsl index f19d93a9c8..aeaf5a38b8 100644 --- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.glsl +++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.glsl @@ -1,17 +1,64 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require -builtins/gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +layout(binding = 0, std430) buffer SB_RW_ssbo { + float16_t arg_0[]; +} sb_rw; -builtins/gen/var/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RW { -^^^^^^ +void arrayLength_cbd6b5() { + uint res = uint(sb_rw.arg_0.length()); +} -builtins/gen/var/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +vec4 vertex_main() { + arrayLength_cbd6b5(); + return vec4(0.0f); +} +void main() { + gl_PointSize = 1.0; + vec4 inner_result = vertex_main(); + gl_Position = inner_result; + gl_Position.y = -(gl_Position.y); + gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w); + return; +} +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require +precision mediump float; + +layout(binding = 0, std430) buffer SB_RW_ssbo { + float16_t arg_0[]; +} sb_rw; + +void arrayLength_cbd6b5() { + uint res = uint(sb_rw.arg_0.length()); +} + +void fragment_main() { + arrayLength_cbd6b5(); +} + +void main() { + fragment_main(); + return; +} +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require + +layout(binding = 0, std430) buffer SB_RW_ssbo { + float16_t arg_0[]; +} sb_rw; + +void arrayLength_cbd6b5() { + uint res = uint(sb_rw.arg_0.length()); +} + +void compute_main() { + arrayLength_cbd6b5(); +} + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void main() { + compute_main(); + return; +} diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.msl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.msl index f19d93a9c8..86034e437c 100644 --- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.msl +++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.msl @@ -1,17 +1,54 @@ -SKIP: FAILED +#include -builtins/gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; + +struct tint_symbol_1 { + /* 0x0000 */ tint_array buffer_size; +}; -builtins/gen/var/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; struct SB_RW { -^^^^^^ + tint_array arg_0; +}; -builtins/gen/var/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +void arrayLength_cbd6b5(const constant tint_symbol_1* const tint_symbol_3) { + uint res = (((*(tint_symbol_3)).buffer_size[0u][0u] - 0u) / 2u); +} + +struct tint_symbol { + float4 value [[position]]; +}; + +float4 vertex_main_inner(const constant tint_symbol_1* const tint_symbol_4) { + arrayLength_cbd6b5(tint_symbol_4); + return float4(0.0f); +} + +vertex tint_symbol vertex_main(const constant tint_symbol_1* tint_symbol_5 [[buffer(30)]]) { + float4 const inner_result = vertex_main_inner(tint_symbol_5); + tint_symbol wrapper_result = {}; + wrapper_result.value = inner_result; + return wrapper_result; +} + +fragment void fragment_main(const constant tint_symbol_1* tint_symbol_6 [[buffer(30)]]) { + arrayLength_cbd6b5(tint_symbol_6); + return; +} + +kernel void compute_main(const constant tint_symbol_1* tint_symbol_7 [[buffer(30)]]) { + arrayLength_cbd6b5(tint_symbol_7); + return; +} diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.spvasm index f19d93a9c8..15031dee64 100644 --- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.spvasm +++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.spvasm @@ -1,17 +1,83 @@ -SKIP: FAILED - -builtins/gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ - -builtins/gen/var/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; -struct SB_RW { -^^^^^^ - -builtins/gen/var/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable -@group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 37 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size + OpEntryPoint Fragment %fragment_main "fragment_main" + OpEntryPoint GLCompute %compute_main "compute_main" + OpExecutionMode %fragment_main OriginUpperLeft + OpExecutionMode %compute_main LocalSize 1 1 1 + OpName %value "value" + OpName %vertex_point_size "vertex_point_size" + OpName %SB_RW "SB_RW" + OpMemberName %SB_RW 0 "arg_0" + OpName %sb_rw "sb_rw" + OpName %arrayLength_cbd6b5 "arrayLength_cbd6b5" + OpName %res "res" + OpName %vertex_main_inner "vertex_main_inner" + OpName %vertex_main "vertex_main" + OpName %fragment_main "fragment_main" + OpName %compute_main "compute_main" + OpDecorate %value BuiltIn Position + OpDecorate %vertex_point_size BuiltIn PointSize + OpDecorate %SB_RW Block + OpMemberDecorate %SB_RW 0 Offset 0 + OpDecorate %_runtimearr_half ArrayStride 2 + OpDecorate %sb_rw DescriptorSet 0 + OpDecorate %sb_rw Binding 0 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %5 = OpConstantNull %v4float + %value = OpVariable %_ptr_Output_v4float Output %5 +%_ptr_Output_float = OpTypePointer Output %float + %8 = OpConstantNull %float +%vertex_point_size = OpVariable %_ptr_Output_float Output %8 + %half = OpTypeFloat 16 +%_runtimearr_half = OpTypeRuntimeArray %half + %SB_RW = OpTypeStruct %_runtimearr_half +%_ptr_StorageBuffer_SB_RW = OpTypePointer StorageBuffer %SB_RW + %sb_rw = OpVariable %_ptr_StorageBuffer_SB_RW StorageBuffer + %void = OpTypeVoid + %14 = OpTypeFunction %void + %uint = OpTypeInt 32 0 +%_ptr_Function_uint = OpTypePointer Function %uint + %22 = OpConstantNull %uint + %23 = OpTypeFunction %v4float + %float_1 = OpConstant %float 1 +%arrayLength_cbd6b5 = OpFunction %void None %14 + %17 = OpLabel + %res = OpVariable %_ptr_Function_uint Function %22 + %18 = OpArrayLength %uint %sb_rw 0 + OpStore %res %18 + OpReturn + OpFunctionEnd +%vertex_main_inner = OpFunction %v4float None %23 + %25 = OpLabel + %26 = OpFunctionCall %void %arrayLength_cbd6b5 + OpReturnValue %5 + OpFunctionEnd +%vertex_main = OpFunction %void None %14 + %28 = OpLabel + %29 = OpFunctionCall %v4float %vertex_main_inner + OpStore %value %29 + OpStore %vertex_point_size %float_1 + OpReturn + OpFunctionEnd +%fragment_main = OpFunction %void None %14 + %32 = OpLabel + %33 = OpFunctionCall %void %arrayLength_cbd6b5 + OpReturn + OpFunctionEnd +%compute_main = OpFunction %void None %14 + %35 = OpLabel + %36 = OpFunctionCall %void %arrayLength_cbd6b5 + OpReturn + OpFunctionEnd diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.wgsl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.wgsl index f19d93a9c8..c0255910b3 100644 --- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.wgsl +++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.wgsl @@ -1,17 +1,27 @@ -SKIP: FAILED +enable f16; -builtins/gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet - arg_0: array, - ^^^^^^^^^^ - -builtins/gen/var/arrayLength/cbd6b5.wgsl:25:1 note: see layout of struct: -/* align(2) size(2) */ struct SB_RW { -/* offset(0) align(2) size(2) */ arg_0 : array; -/* */ }; struct SB_RW { -^^^^^^ + arg_0 : array, +} -builtins/gen/var/arrayLength/cbd6b5.wgsl:28:48 note: see declaration of variable @group(0) @binding(0) var sb_rw : SB_RW; - ^^^^^ +fn arrayLength_cbd6b5() { + var res : u32 = arrayLength(&(sb_rw.arg_0)); +} + +@vertex +fn vertex_main() -> @builtin(position) vec4 { + arrayLength_cbd6b5(); + return vec4(); +} + +@fragment +fn fragment_main() { + arrayLength_cbd6b5(); +} + +@compute @workgroup_size(1) +fn compute_main() { + arrayLength_cbd6b5(); +} diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.dxc.hlsl index ae79b76d77..523d7b4349 100644 --- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.dxc.hlsl @@ -1,20 +1,21 @@ -SKIP: FAILED +cbuffer cbuffer_data : register(b0, space0) { + uint4 data[2]; +}; -binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x2, - ^^^^^^^^^^^ - -binary/mul/mat3x2-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(24) */ struct S { -/* offset( 0) align(4) size(12) */ matrix : mat3x2; -/* offset(12) align(1) size( 4) */ // -- implicit field alignment padding --; -/* offset(16) align(8) size( 6) */ vector : vec3; -/* offset(22) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -binary/mul/mat3x2-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +matrix tint_symbol_2(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint ubo_load = buffer[scalar_offset / 4][scalar_offset % 4]; + const uint scalar_offset_1 = ((offset + 4u)) / 4; + uint ubo_load_1 = buffer[scalar_offset_1 / 4][scalar_offset_1 % 4]; + const uint scalar_offset_2 = ((offset + 8u)) / 4; + uint ubo_load_2 = buffer[scalar_offset_2 / 4][scalar_offset_2 % 4]; + return matrix(vector(float16_t(f16tof32(ubo_load & 0xFFFF)), float16_t(f16tof32(ubo_load >> 16))), vector(float16_t(f16tof32(ubo_load_1 & 0xFFFF)), float16_t(f16tof32(ubo_load_1 >> 16))), vector(float16_t(f16tof32(ubo_load_2 & 0xFFFF)), float16_t(f16tof32(ubo_load_2 >> 16)))); +} +void main() { + uint2 ubo_load_3 = data[1].xy; + vector ubo_load_3_xz = vector(f16tof32(ubo_load_3 & 0xFFFF)); + float16_t ubo_load_3_y = f16tof32(ubo_load_3[0] >> 16); + const vector x = mul(vector(ubo_load_3_xz[0], ubo_load_3_y, ubo_load_3_xz[1]), tint_symbol_2(data, 0u)); + return; +} diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.glsl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.glsl index b949b92072..35e00f45eb 100644 --- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.glsl @@ -1,20 +1,38 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require +precision mediump float; -expressions/binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x2, - ^^^^^^^^^^^ - -expressions/binary/mul/mat3x2-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(24) */ struct S { -/* offset( 0) align(4) size(12) */ matrix : mat3x2; -/* offset(12) align(1) size( 4) */ // -- implicit field alignment padding --; -/* offset(16) align(8) size( 6) */ vector : vec3; -/* offset(22) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + f16mat3x2 matrix; + uint pad; + f16vec3 vector; + uint pad_1; + uint pad_2; +}; -expressions/binary/mul/mat3x2-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +struct S_std140 { + f16vec2 matrix_0; + f16vec2 matrix_1; + f16vec2 matrix_2; + uint pad; + f16vec3 vector; + uint pad_1; + uint pad_2; +}; +layout(binding = 0, std140) uniform data_block_std140_ubo { + S_std140 inner; +} data; + +f16mat3x2 load_data_inner_matrix() { + return f16mat3x2(data.inner.matrix_0, data.inner.matrix_1, data.inner.matrix_2); +} + +void tint_symbol() { + f16vec2 x = (load_data_inner_matrix() * data.inner.vector); +} + +void main() { + tint_symbol(); + return; +} diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.msl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.msl index ae79b76d77..779a708edf 100644 --- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.msl +++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.msl @@ -1,20 +1,28 @@ -SKIP: FAILED +#include -binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x2, - ^^^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; -binary/mul/mat3x2-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(24) */ struct S { -/* offset( 0) align(4) size(12) */ matrix : mat3x2; -/* offset(12) align(1) size( 4) */ // -- implicit field alignment padding --; -/* offset(16) align(8) size( 6) */ vector : vec3; -/* offset(22) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + /* 0x0000 */ half3x2 tint_symbol; + /* 0x000c */ tint_array tint_pad; + /* 0x0010 */ packed_half3 vector; + /* 0x0016 */ tint_array tint_pad_1; +}; -binary/mul/mat3x2-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +fragment void tint_symbol_1(const constant S* tint_symbol_2 [[buffer(0)]]) { + half2 const x = ((*(tint_symbol_2)).tint_symbol * half3((*(tint_symbol_2)).vector)); + return; +} diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.spvasm b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.spvasm index ae79b76d77..1ff70b3643 100644 --- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.spvasm @@ -1,20 +1,71 @@ -SKIP: FAILED - -binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x2, - ^^^^^^^^^^^ - -binary/mul/mat3x2-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(24) */ struct S { -/* offset( 0) align(4) size(12) */ matrix : mat3x2; -/* offset(12) align(1) size( 4) */ // -- implicit field alignment padding --; -/* offset(16) align(8) size( 6) */ vector : vec3; -/* offset(22) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -binary/mul/mat3x2-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 40 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpName %data_block_std140 "data_block_std140" + OpMemberName %data_block_std140 0 "inner" + OpName %S_std140 "S_std140" + OpMemberName %S_std140 0 "matrix_0" + OpMemberName %S_std140 1 "matrix_1" + OpMemberName %S_std140 2 "matrix_2" + OpMemberName %S_std140 3 "vector" + OpName %data "data" + OpName %load_data_inner_matrix "load_data_inner_matrix" + OpName %main "main" + OpDecorate %data_block_std140 Block + OpMemberDecorate %data_block_std140 0 Offset 0 + OpMemberDecorate %S_std140 0 Offset 0 + OpMemberDecorate %S_std140 1 Offset 4 + OpMemberDecorate %S_std140 2 Offset 8 + OpMemberDecorate %S_std140 3 Offset 16 + OpDecorate %data NonWritable + OpDecorate %data DescriptorSet 0 + OpDecorate %data Binding 0 + %half = OpTypeFloat 16 + %v2half = OpTypeVector %half 2 + %v3half = OpTypeVector %half 3 + %S_std140 = OpTypeStruct %v2half %v2half %v2half %v3half +%data_block_std140 = OpTypeStruct %S_std140 +%_ptr_Uniform_data_block_std140 = OpTypePointer Uniform %data_block_std140 + %data = OpVariable %_ptr_Uniform_data_block_std140 Uniform + %mat3v2half = OpTypeMatrix %v2half 3 + %8 = OpTypeFunction %mat3v2half + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 +%_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140 +%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %void = OpTypeVoid + %30 = OpTypeFunction %void + %uint_3 = OpConstant %uint 3 +%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half +%load_data_inner_matrix = OpFunction %mat3v2half None %8 + %11 = OpLabel + %16 = OpAccessChain %_ptr_Uniform_S_std140 %data %uint_0 + %19 = OpAccessChain %_ptr_Uniform_v2half %16 %uint_0 + %20 = OpLoad %v2half %19 + %23 = OpAccessChain %_ptr_Uniform_v2half %16 %uint_1 + %24 = OpLoad %v2half %23 + %27 = OpAccessChain %_ptr_Uniform_v2half %16 %uint_2 + %28 = OpLoad %v2half %27 + %29 = OpCompositeConstruct %mat3v2half %20 %24 %28 + OpReturnValue %29 + OpFunctionEnd + %main = OpFunction %void None %30 + %33 = OpLabel + %34 = OpFunctionCall %mat3v2half %load_data_inner_matrix + %37 = OpAccessChain %_ptr_Uniform_v3half %data %uint_0 %uint_3 + %38 = OpLoad %v3half %37 + %39 = OpMatrixTimesVector %v2half %34 %38 + OpReturn + OpFunctionEnd diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.wgsl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.wgsl index ae79b76d77..dfa05d4be5 100644 --- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.wgsl +++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.wgsl @@ -1,20 +1,13 @@ -SKIP: FAILED +enable f16; -binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x2, - ^^^^^^^^^^^ - -binary/mul/mat3x2-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(24) */ struct S { -/* offset( 0) align(4) size(12) */ matrix : mat3x2; -/* offset(12) align(1) size( 4) */ // -- implicit field alignment padding --; -/* offset(16) align(8) size( 6) */ vector : vec3; -/* offset(22) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + matrix : mat3x2, + vector : vec3, +} -binary/mul/mat3x2-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +@group(0) @binding(0) var data : S; +@fragment +fn main() { + let x = (data.matrix * data.vector); +} diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.dxc.hlsl index 57a21b59f2..a60cb20fe5 100644 --- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.dxc.hlsl @@ -1,19 +1,30 @@ -SKIP: FAILED +cbuffer cbuffer_data : register(b0, space0) { + uint4 data[2]; +}; -binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ - -binary/mul/mat3x3-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -binary/mul/mat3x3-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +matrix tint_symbol_2(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1]), vector(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1])); +} +void main() { + uint2 ubo_load_6 = data[1].zw; + vector ubo_load_6_xz = vector(f16tof32(ubo_load_6 & 0xFFFF)); + float16_t ubo_load_6_y = f16tof32(ubo_load_6[0] >> 16); + const vector x = mul(vector(ubo_load_6_xz[0], ubo_load_6_y, ubo_load_6_xz[1]), tint_symbol_2(data, 0u)); + return; +} diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.glsl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.glsl index 07caac0143..24726cc2c1 100644 --- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.glsl @@ -1,19 +1,32 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require +precision mediump float; -expressions/binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ - -expressions/binary/mul/mat3x3-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + f16mat3 matrix; + f16vec3 vector; +}; -expressions/binary/mul/mat3x3-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +struct S_std140 { + f16vec3 matrix_0; + f16vec3 matrix_1; + f16vec3 matrix_2; + f16vec3 vector; +}; +layout(binding = 0, std140) uniform data_block_std140_ubo { + S_std140 inner; +} data; + +f16mat3 load_data_inner_matrix() { + return f16mat3(data.inner.matrix_0, data.inner.matrix_1, data.inner.matrix_2); +} + +void tint_symbol() { + f16vec3 x = (load_data_inner_matrix() * data.inner.vector); +} + +void main() { + tint_symbol(); + return; +} diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.msl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.msl index 57a21b59f2..9c67a7c408 100644 --- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.msl +++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.msl @@ -1,19 +1,27 @@ -SKIP: FAILED +#include -binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; -binary/mul/mat3x3-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + /* 0x0000 */ half3x3 tint_symbol; + /* 0x0018 */ packed_half3 vector; + /* 0x001e */ tint_array tint_pad; +}; -binary/mul/mat3x3-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +fragment void tint_symbol_1(const constant S* tint_symbol_2 [[buffer(0)]]) { + half3 const x = ((*(tint_symbol_2)).tint_symbol * half3((*(tint_symbol_2)).vector)); + return; +} diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.spvasm b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.spvasm index 57a21b59f2..09734ffeaf 100644 --- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.spvasm @@ -1,19 +1,69 @@ -SKIP: FAILED - -binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ - -binary/mul/mat3x3-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -binary/mul/mat3x3-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 38 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpName %data_block_std140 "data_block_std140" + OpMemberName %data_block_std140 0 "inner" + OpName %S_std140 "S_std140" + OpMemberName %S_std140 0 "matrix_0" + OpMemberName %S_std140 1 "matrix_1" + OpMemberName %S_std140 2 "matrix_2" + OpMemberName %S_std140 3 "vector" + OpName %data "data" + OpName %load_data_inner_matrix "load_data_inner_matrix" + OpName %main "main" + OpDecorate %data_block_std140 Block + OpMemberDecorate %data_block_std140 0 Offset 0 + OpMemberDecorate %S_std140 0 Offset 0 + OpMemberDecorate %S_std140 1 Offset 8 + OpMemberDecorate %S_std140 2 Offset 16 + OpMemberDecorate %S_std140 3 Offset 24 + OpDecorate %data NonWritable + OpDecorate %data DescriptorSet 0 + OpDecorate %data Binding 0 + %half = OpTypeFloat 16 + %v3half = OpTypeVector %half 3 + %S_std140 = OpTypeStruct %v3half %v3half %v3half %v3half +%data_block_std140 = OpTypeStruct %S_std140 +%_ptr_Uniform_data_block_std140 = OpTypePointer Uniform %data_block_std140 + %data = OpVariable %_ptr_Uniform_data_block_std140 Uniform + %mat3v3half = OpTypeMatrix %v3half 3 + %7 = OpTypeFunction %mat3v3half + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 +%_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140 +%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %void = OpTypeVoid + %29 = OpTypeFunction %void + %uint_3 = OpConstant %uint 3 +%load_data_inner_matrix = OpFunction %mat3v3half None %7 + %10 = OpLabel + %15 = OpAccessChain %_ptr_Uniform_S_std140 %data %uint_0 + %18 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_0 + %19 = OpLoad %v3half %18 + %22 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_1 + %23 = OpLoad %v3half %22 + %26 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_2 + %27 = OpLoad %v3half %26 + %28 = OpCompositeConstruct %mat3v3half %19 %23 %27 + OpReturnValue %28 + OpFunctionEnd + %main = OpFunction %void None %29 + %32 = OpLabel + %33 = OpFunctionCall %mat3v3half %load_data_inner_matrix + %35 = OpAccessChain %_ptr_Uniform_v3half %data %uint_0 %uint_3 + %36 = OpLoad %v3half %35 + %37 = OpMatrixTimesVector %v3half %33 %36 + OpReturn + OpFunctionEnd diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.wgsl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.wgsl index 57a21b59f2..9b6f18cda6 100644 --- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.wgsl +++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.wgsl @@ -1,19 +1,13 @@ -SKIP: FAILED +enable f16; -binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ - -binary/mul/mat3x3-vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + matrix : mat3x3, + vector : vec3, +} -binary/mul/mat3x3-vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +@group(0) @binding(0) var data : S; +@fragment +fn main() { + let x = (data.matrix * data.vector); +} diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.dxc.hlsl index df85ef65d9..4f3858766a 100644 --- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.dxc.hlsl @@ -1,19 +1,30 @@ -SKIP: FAILED +cbuffer cbuffer_data : register(b0, space0) { + uint4 data[2]; +}; -binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ - -binary/mul/vec3-mat3x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -binary/mul/vec3-mat3x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +matrix tint_symbol_3(uint4 buffer[2], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1]), vector(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1])); +} +void main() { + uint2 ubo_load_6 = data[1].zw; + vector ubo_load_6_xz = vector(f16tof32(ubo_load_6 & 0xFFFF)); + float16_t ubo_load_6_y = f16tof32(ubo_load_6[0] >> 16); + const vector x = mul(tint_symbol_3(data, 0u), vector(ubo_load_6_xz[0], ubo_load_6_y, ubo_load_6_xz[1])); + return; +} diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.glsl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.glsl index 33e1cf031e..3382518b90 100644 --- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.glsl @@ -1,19 +1,32 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require +precision mediump float; -expressions/binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ - -expressions/binary/mul/vec3-mat3x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + f16mat3 matrix; + f16vec3 vector; +}; -expressions/binary/mul/vec3-mat3x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +struct S_std140 { + f16vec3 matrix_0; + f16vec3 matrix_1; + f16vec3 matrix_2; + f16vec3 vector; +}; +layout(binding = 0, std140) uniform data_block_std140_ubo { + S_std140 inner; +} data; + +f16mat3 load_data_inner_matrix() { + return f16mat3(data.inner.matrix_0, data.inner.matrix_1, data.inner.matrix_2); +} + +void tint_symbol() { + f16vec3 x = (data.inner.vector * load_data_inner_matrix()); +} + +void main() { + tint_symbol(); + return; +} diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.msl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.msl index df85ef65d9..1d92d8d555 100644 --- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.msl +++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.msl @@ -1,19 +1,27 @@ -SKIP: FAILED +#include -binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; -binary/mul/vec3-mat3x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + /* 0x0000 */ half3x3 tint_symbol; + /* 0x0018 */ packed_half3 vector; + /* 0x001e */ tint_array tint_pad; +}; -binary/mul/vec3-mat3x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +fragment void tint_symbol_1(const constant S* tint_symbol_2 [[buffer(0)]]) { + half3 const x = (half3((*(tint_symbol_2)).vector) * (*(tint_symbol_2)).tint_symbol); + return; +} diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.spvasm b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.spvasm index df85ef65d9..debae7d13c 100644 --- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.spvasm @@ -1,19 +1,69 @@ -SKIP: FAILED - -binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ - -binary/mul/vec3-mat3x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -binary/mul/vec3-mat3x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 38 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpName %data_block_std140 "data_block_std140" + OpMemberName %data_block_std140 0 "inner" + OpName %S_std140 "S_std140" + OpMemberName %S_std140 0 "matrix_0" + OpMemberName %S_std140 1 "matrix_1" + OpMemberName %S_std140 2 "matrix_2" + OpMemberName %S_std140 3 "vector" + OpName %data "data" + OpName %load_data_inner_matrix "load_data_inner_matrix" + OpName %main "main" + OpDecorate %data_block_std140 Block + OpMemberDecorate %data_block_std140 0 Offset 0 + OpMemberDecorate %S_std140 0 Offset 0 + OpMemberDecorate %S_std140 1 Offset 8 + OpMemberDecorate %S_std140 2 Offset 16 + OpMemberDecorate %S_std140 3 Offset 24 + OpDecorate %data NonWritable + OpDecorate %data DescriptorSet 0 + OpDecorate %data Binding 0 + %half = OpTypeFloat 16 + %v3half = OpTypeVector %half 3 + %S_std140 = OpTypeStruct %v3half %v3half %v3half %v3half +%data_block_std140 = OpTypeStruct %S_std140 +%_ptr_Uniform_data_block_std140 = OpTypePointer Uniform %data_block_std140 + %data = OpVariable %_ptr_Uniform_data_block_std140 Uniform + %mat3v3half = OpTypeMatrix %v3half 3 + %7 = OpTypeFunction %mat3v3half + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 +%_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140 +%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %void = OpTypeVoid + %29 = OpTypeFunction %void + %uint_3 = OpConstant %uint 3 +%load_data_inner_matrix = OpFunction %mat3v3half None %7 + %10 = OpLabel + %15 = OpAccessChain %_ptr_Uniform_S_std140 %data %uint_0 + %18 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_0 + %19 = OpLoad %v3half %18 + %22 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_1 + %23 = OpLoad %v3half %22 + %26 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_2 + %27 = OpLoad %v3half %26 + %28 = OpCompositeConstruct %mat3v3half %19 %23 %27 + OpReturnValue %28 + OpFunctionEnd + %main = OpFunction %void None %29 + %32 = OpLabel + %34 = OpAccessChain %_ptr_Uniform_v3half %data %uint_0 %uint_3 + %35 = OpLoad %v3half %34 + %36 = OpFunctionCall %mat3v3half %load_data_inner_matrix + %37 = OpVectorTimesMatrix %v3half %35 %36 + OpReturn + OpFunctionEnd diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.wgsl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.wgsl index df85ef65d9..9c71b03b76 100644 --- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.wgsl +++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.wgsl @@ -1,19 +1,13 @@ -SKIP: FAILED +enable f16; -binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat3x3, - ^^^^^^^^^^^ - -binary/mul/vec3-mat3x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(32) */ struct S { -/* offset( 0) align(8) size(24) */ matrix : mat3x3; -/* offset(24) align(8) size( 6) */ vector : vec3; -/* offset(30) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + matrix : mat3x3, + vector : vec3, +} -binary/mul/vec3-mat3x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +@group(0) @binding(0) var data : S; +@fragment +fn main() { + let x = (data.vector * data.matrix); +} diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.dxc.hlsl index 6f70109ab0..818c96e51d 100644 --- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.dxc.hlsl @@ -1,19 +1,35 @@ -SKIP: FAILED +cbuffer cbuffer_data : register(b0, space0) { + uint4 data[3]; +}; -binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat4x3, - ^^^^^^^^^^^ - -binary/mul/vec3-mat4x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(40) */ struct S { -/* offset( 0) align(8) size(32) */ matrix : mat4x3; -/* offset(32) align(8) size( 6) */ vector : vec3; -/* offset(38) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -binary/mul/vec3-mat4x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +matrix tint_symbol_3(uint4 buffer[3], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + uint4 ubo_load_1 = buffer[scalar_offset / 4]; + uint2 ubo_load = ((scalar_offset & 2) ? ubo_load_1.zw : ubo_load_1.xy); + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + const uint scalar_offset_1 = ((offset + 8u)) / 4; + uint4 ubo_load_3 = buffer[scalar_offset_1 / 4]; + uint2 ubo_load_2 = ((scalar_offset_1 & 2) ? ubo_load_3.zw : ubo_load_3.xy); + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + const uint scalar_offset_2 = ((offset + 16u)) / 4; + uint4 ubo_load_5 = buffer[scalar_offset_2 / 4]; + uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy); + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16); + const uint scalar_offset_3 = ((offset + 24u)) / 4; + uint4 ubo_load_7 = buffer[scalar_offset_3 / 4]; + uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy); + vector ubo_load_6_xz = vector(f16tof32(ubo_load_6 & 0xFFFF)); + float16_t ubo_load_6_y = f16tof32(ubo_load_6[0] >> 16); + return matrix(vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]), vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1]), vector(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1]), vector(ubo_load_6_xz[0], ubo_load_6_y, ubo_load_6_xz[1])); +} +void main() { + uint2 ubo_load_8 = data[2].xy; + vector ubo_load_8_xz = vector(f16tof32(ubo_load_8 & 0xFFFF)); + float16_t ubo_load_8_y = f16tof32(ubo_load_8[0] >> 16); + const vector x = mul(tint_symbol_3(data, 0u), vector(ubo_load_8_xz[0], ubo_load_8_y, ubo_load_8_xz[1])); + return; +} diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.glsl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.glsl index 9f92e39e36..b684ca939a 100644 --- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.glsl @@ -1,19 +1,37 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require +precision mediump float; -expressions/binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat4x3, - ^^^^^^^^^^^ - -expressions/binary/mul/vec3-mat4x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(40) */ struct S { -/* offset( 0) align(8) size(32) */ matrix : mat4x3; -/* offset(32) align(8) size( 6) */ vector : vec3; -/* offset(38) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + f16mat4x3 matrix; + f16vec3 vector; + uint pad; + uint pad_1; +}; -expressions/binary/mul/vec3-mat4x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +struct S_std140 { + f16vec3 matrix_0; + f16vec3 matrix_1; + f16vec3 matrix_2; + f16vec3 matrix_3; + f16vec3 vector; + uint pad; + uint pad_1; +}; +layout(binding = 0, std140) uniform data_block_std140_ubo { + S_std140 inner; +} data; + +f16mat4x3 load_data_inner_matrix() { + return f16mat4x3(data.inner.matrix_0, data.inner.matrix_1, data.inner.matrix_2, data.inner.matrix_3); +} + +void tint_symbol() { + f16vec4 x = (data.inner.vector * load_data_inner_matrix()); +} + +void main() { + tint_symbol(); + return; +} diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.msl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.msl index 6f70109ab0..d311e887f1 100644 --- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.msl +++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.msl @@ -1,19 +1,27 @@ -SKIP: FAILED +#include -binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat4x3, - ^^^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; -binary/mul/vec3-mat4x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(40) */ struct S { -/* offset( 0) align(8) size(32) */ matrix : mat4x3; -/* offset(32) align(8) size( 6) */ vector : vec3; -/* offset(38) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + /* 0x0000 */ half4x3 tint_symbol; + /* 0x0020 */ packed_half3 vector; + /* 0x0026 */ tint_array tint_pad; +}; -binary/mul/vec3-mat4x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +fragment void tint_symbol_1(const constant S* tint_symbol_2 [[buffer(0)]]) { + half4 const x = (half3((*(tint_symbol_2)).vector) * (*(tint_symbol_2)).tint_symbol); + return; +} diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.spvasm b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.spvasm index 6f70109ab0..6cb5a7030d 100644 --- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.spvasm @@ -1,19 +1,75 @@ -SKIP: FAILED - -binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat4x3, - ^^^^^^^^^^^ - -binary/mul/vec3-mat4x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(40) */ struct S { -/* offset( 0) align(8) size(32) */ matrix : mat4x3; -/* offset(32) align(8) size( 6) */ vector : vec3; -/* offset(38) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -binary/mul/vec3-mat4x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 43 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpName %data_block_std140 "data_block_std140" + OpMemberName %data_block_std140 0 "inner" + OpName %S_std140 "S_std140" + OpMemberName %S_std140 0 "matrix_0" + OpMemberName %S_std140 1 "matrix_1" + OpMemberName %S_std140 2 "matrix_2" + OpMemberName %S_std140 3 "matrix_3" + OpMemberName %S_std140 4 "vector" + OpName %data "data" + OpName %load_data_inner_matrix "load_data_inner_matrix" + OpName %main "main" + OpDecorate %data_block_std140 Block + OpMemberDecorate %data_block_std140 0 Offset 0 + OpMemberDecorate %S_std140 0 Offset 0 + OpMemberDecorate %S_std140 1 Offset 8 + OpMemberDecorate %S_std140 2 Offset 16 + OpMemberDecorate %S_std140 3 Offset 24 + OpMemberDecorate %S_std140 4 Offset 32 + OpDecorate %data NonWritable + OpDecorate %data DescriptorSet 0 + OpDecorate %data Binding 0 + %half = OpTypeFloat 16 + %v3half = OpTypeVector %half 3 + %S_std140 = OpTypeStruct %v3half %v3half %v3half %v3half %v3half +%data_block_std140 = OpTypeStruct %S_std140 +%_ptr_Uniform_data_block_std140 = OpTypePointer Uniform %data_block_std140 + %data = OpVariable %_ptr_Uniform_data_block_std140 Uniform + %mat4v3half = OpTypeMatrix %v3half 4 + %7 = OpTypeFunction %mat4v3half + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 +%_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140 +%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_3 = OpConstant %uint 3 + %void = OpTypeVoid + %33 = OpTypeFunction %void + %uint_4 = OpConstant %uint 4 + %v4half = OpTypeVector %half 4 +%load_data_inner_matrix = OpFunction %mat4v3half None %7 + %10 = OpLabel + %15 = OpAccessChain %_ptr_Uniform_S_std140 %data %uint_0 + %18 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_0 + %19 = OpLoad %v3half %18 + %22 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_1 + %23 = OpLoad %v3half %22 + %26 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_2 + %27 = OpLoad %v3half %26 + %30 = OpAccessChain %_ptr_Uniform_v3half %15 %uint_3 + %31 = OpLoad %v3half %30 + %32 = OpCompositeConstruct %mat4v3half %19 %23 %27 %31 + OpReturnValue %32 + OpFunctionEnd + %main = OpFunction %void None %33 + %36 = OpLabel + %38 = OpAccessChain %_ptr_Uniform_v3half %data %uint_0 %uint_4 + %39 = OpLoad %v3half %38 + %40 = OpFunctionCall %mat4v3half %load_data_inner_matrix + %41 = OpVectorTimesMatrix %v4half %39 %40 + OpReturn + OpFunctionEnd diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.wgsl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.wgsl index 6f70109ab0..93ffb9e672 100644 --- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.wgsl +++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.wgsl @@ -1,19 +1,13 @@ -SKIP: FAILED +enable f16; -binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet - matrix : mat4x3, - ^^^^^^^^^^^ - -binary/mul/vec3-mat4x3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(40) */ struct S { -/* offset( 0) align(8) size(32) */ matrix : mat4x3; -/* offset(32) align(8) size( 6) */ vector : vec3; -/* offset(38) align(1) size( 2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + matrix : mat4x3, + vector : vec3, +} -binary/mul/vec3-mat4x3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var data: S; - ^^^^ +@group(0) @binding(0) var data : S; +@fragment +fn main() { + let x = (data.vector * data.matrix); +} diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.dxc.hlsl index 6c8063b2f1..5be5dfc29b 100644 --- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.dxc.hlsl @@ -1,18 +1,486 @@ -SKIP: FAILED +[numthreads(1, 1, 1)] +void unused_entry_point() { + return; +} -swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet - v: vec3, - ^^^^^^^^^ - -swizzle/read/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -swizzle/read/packed_vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var U : S; - ^ +cbuffer cbuffer_U : register(b0, space0) { + uint4 U[1]; +}; +void f() { + uint2 ubo_load = U[0].xy; + vector ubo_load_xz = vector(f16tof32(ubo_load & 0xFFFF)); + float16_t ubo_load_y = f16tof32(ubo_load[0] >> 16); + vector v = vector(ubo_load_xz[0], ubo_load_y, ubo_load_xz[1]); + float16_t x = float16_t(f16tof32(((U[0].x) & 0xFFFF))); + float16_t y = float16_t(f16tof32(((U[0].x >> 16) & 0xFFFF))); + float16_t z = float16_t(f16tof32(((U[0].y) & 0xFFFF))); + uint2 ubo_load_1 = U[0].xy; + vector ubo_load_1_xz = vector(f16tof32(ubo_load_1 & 0xFFFF)); + float16_t ubo_load_1_y = f16tof32(ubo_load_1[0] >> 16); + vector xx = vector(ubo_load_1_xz[0], ubo_load_1_y, ubo_load_1_xz[1]).xx; + uint2 ubo_load_2 = U[0].xy; + vector ubo_load_2_xz = vector(f16tof32(ubo_load_2 & 0xFFFF)); + float16_t ubo_load_2_y = f16tof32(ubo_load_2[0] >> 16); + vector xy = vector(ubo_load_2_xz[0], ubo_load_2_y, ubo_load_2_xz[1]).xy; + uint2 ubo_load_3 = U[0].xy; + vector ubo_load_3_xz = vector(f16tof32(ubo_load_3 & 0xFFFF)); + float16_t ubo_load_3_y = f16tof32(ubo_load_3[0] >> 16); + vector xz = vector(ubo_load_3_xz[0], ubo_load_3_y, ubo_load_3_xz[1]).xz; + uint2 ubo_load_4 = U[0].xy; + vector ubo_load_4_xz = vector(f16tof32(ubo_load_4 & 0xFFFF)); + float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16); + vector yx = vector(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1]).yx; + uint2 ubo_load_5 = U[0].xy; + vector ubo_load_5_xz = vector(f16tof32(ubo_load_5 & 0xFFFF)); + float16_t ubo_load_5_y = f16tof32(ubo_load_5[0] >> 16); + vector yy = vector(ubo_load_5_xz[0], ubo_load_5_y, ubo_load_5_xz[1]).yy; + uint2 ubo_load_6 = U[0].xy; + vector ubo_load_6_xz = vector(f16tof32(ubo_load_6 & 0xFFFF)); + float16_t ubo_load_6_y = f16tof32(ubo_load_6[0] >> 16); + vector yz = vector(ubo_load_6_xz[0], ubo_load_6_y, ubo_load_6_xz[1]).yz; + uint2 ubo_load_7 = U[0].xy; + vector ubo_load_7_xz = vector(f16tof32(ubo_load_7 & 0xFFFF)); + float16_t ubo_load_7_y = f16tof32(ubo_load_7[0] >> 16); + vector zx = vector(ubo_load_7_xz[0], ubo_load_7_y, ubo_load_7_xz[1]).zx; + uint2 ubo_load_8 = U[0].xy; + vector ubo_load_8_xz = vector(f16tof32(ubo_load_8 & 0xFFFF)); + float16_t ubo_load_8_y = f16tof32(ubo_load_8[0] >> 16); + vector zy = vector(ubo_load_8_xz[0], ubo_load_8_y, ubo_load_8_xz[1]).zy; + uint2 ubo_load_9 = U[0].xy; + vector ubo_load_9_xz = vector(f16tof32(ubo_load_9 & 0xFFFF)); + float16_t ubo_load_9_y = f16tof32(ubo_load_9[0] >> 16); + vector zz = vector(ubo_load_9_xz[0], ubo_load_9_y, ubo_load_9_xz[1]).zz; + uint2 ubo_load_10 = U[0].xy; + vector ubo_load_10_xz = vector(f16tof32(ubo_load_10 & 0xFFFF)); + float16_t ubo_load_10_y = f16tof32(ubo_load_10[0] >> 16); + vector xxx = vector(ubo_load_10_xz[0], ubo_load_10_y, ubo_load_10_xz[1]).xxx; + uint2 ubo_load_11 = U[0].xy; + vector ubo_load_11_xz = vector(f16tof32(ubo_load_11 & 0xFFFF)); + float16_t ubo_load_11_y = f16tof32(ubo_load_11[0] >> 16); + vector xxy = vector(ubo_load_11_xz[0], ubo_load_11_y, ubo_load_11_xz[1]).xxy; + uint2 ubo_load_12 = U[0].xy; + vector ubo_load_12_xz = vector(f16tof32(ubo_load_12 & 0xFFFF)); + float16_t ubo_load_12_y = f16tof32(ubo_load_12[0] >> 16); + vector xxz = vector(ubo_load_12_xz[0], ubo_load_12_y, ubo_load_12_xz[1]).xxz; + uint2 ubo_load_13 = U[0].xy; + vector ubo_load_13_xz = vector(f16tof32(ubo_load_13 & 0xFFFF)); + float16_t ubo_load_13_y = f16tof32(ubo_load_13[0] >> 16); + vector xyx = vector(ubo_load_13_xz[0], ubo_load_13_y, ubo_load_13_xz[1]).xyx; + uint2 ubo_load_14 = U[0].xy; + vector ubo_load_14_xz = vector(f16tof32(ubo_load_14 & 0xFFFF)); + float16_t ubo_load_14_y = f16tof32(ubo_load_14[0] >> 16); + vector xyy = vector(ubo_load_14_xz[0], ubo_load_14_y, ubo_load_14_xz[1]).xyy; + uint2 ubo_load_15 = U[0].xy; + vector ubo_load_15_xz = vector(f16tof32(ubo_load_15 & 0xFFFF)); + float16_t ubo_load_15_y = f16tof32(ubo_load_15[0] >> 16); + vector xyz = vector(ubo_load_15_xz[0], ubo_load_15_y, ubo_load_15_xz[1]).xyz; + uint2 ubo_load_16 = U[0].xy; + vector ubo_load_16_xz = vector(f16tof32(ubo_load_16 & 0xFFFF)); + float16_t ubo_load_16_y = f16tof32(ubo_load_16[0] >> 16); + vector xzx = vector(ubo_load_16_xz[0], ubo_load_16_y, ubo_load_16_xz[1]).xzx; + uint2 ubo_load_17 = U[0].xy; + vector ubo_load_17_xz = vector(f16tof32(ubo_load_17 & 0xFFFF)); + float16_t ubo_load_17_y = f16tof32(ubo_load_17[0] >> 16); + vector xzy = vector(ubo_load_17_xz[0], ubo_load_17_y, ubo_load_17_xz[1]).xzy; + uint2 ubo_load_18 = U[0].xy; + vector ubo_load_18_xz = vector(f16tof32(ubo_load_18 & 0xFFFF)); + float16_t ubo_load_18_y = f16tof32(ubo_load_18[0] >> 16); + vector xzz = vector(ubo_load_18_xz[0], ubo_load_18_y, ubo_load_18_xz[1]).xzz; + uint2 ubo_load_19 = U[0].xy; + vector ubo_load_19_xz = vector(f16tof32(ubo_load_19 & 0xFFFF)); + float16_t ubo_load_19_y = f16tof32(ubo_load_19[0] >> 16); + vector yxx = vector(ubo_load_19_xz[0], ubo_load_19_y, ubo_load_19_xz[1]).yxx; + uint2 ubo_load_20 = U[0].xy; + vector ubo_load_20_xz = vector(f16tof32(ubo_load_20 & 0xFFFF)); + float16_t ubo_load_20_y = f16tof32(ubo_load_20[0] >> 16); + vector yxy = vector(ubo_load_20_xz[0], ubo_load_20_y, ubo_load_20_xz[1]).yxy; + uint2 ubo_load_21 = U[0].xy; + vector ubo_load_21_xz = vector(f16tof32(ubo_load_21 & 0xFFFF)); + float16_t ubo_load_21_y = f16tof32(ubo_load_21[0] >> 16); + vector yxz = vector(ubo_load_21_xz[0], ubo_load_21_y, ubo_load_21_xz[1]).yxz; + uint2 ubo_load_22 = U[0].xy; + vector ubo_load_22_xz = vector(f16tof32(ubo_load_22 & 0xFFFF)); + float16_t ubo_load_22_y = f16tof32(ubo_load_22[0] >> 16); + vector yyx = vector(ubo_load_22_xz[0], ubo_load_22_y, ubo_load_22_xz[1]).yyx; + uint2 ubo_load_23 = U[0].xy; + vector ubo_load_23_xz = vector(f16tof32(ubo_load_23 & 0xFFFF)); + float16_t ubo_load_23_y = f16tof32(ubo_load_23[0] >> 16); + vector yyy = vector(ubo_load_23_xz[0], ubo_load_23_y, ubo_load_23_xz[1]).yyy; + uint2 ubo_load_24 = U[0].xy; + vector ubo_load_24_xz = vector(f16tof32(ubo_load_24 & 0xFFFF)); + float16_t ubo_load_24_y = f16tof32(ubo_load_24[0] >> 16); + vector yyz = vector(ubo_load_24_xz[0], ubo_load_24_y, ubo_load_24_xz[1]).yyz; + uint2 ubo_load_25 = U[0].xy; + vector ubo_load_25_xz = vector(f16tof32(ubo_load_25 & 0xFFFF)); + float16_t ubo_load_25_y = f16tof32(ubo_load_25[0] >> 16); + vector yzx = vector(ubo_load_25_xz[0], ubo_load_25_y, ubo_load_25_xz[1]).yzx; + uint2 ubo_load_26 = U[0].xy; + vector ubo_load_26_xz = vector(f16tof32(ubo_load_26 & 0xFFFF)); + float16_t ubo_load_26_y = f16tof32(ubo_load_26[0] >> 16); + vector yzy = vector(ubo_load_26_xz[0], ubo_load_26_y, ubo_load_26_xz[1]).yzy; + uint2 ubo_load_27 = U[0].xy; + vector ubo_load_27_xz = vector(f16tof32(ubo_load_27 & 0xFFFF)); + float16_t ubo_load_27_y = f16tof32(ubo_load_27[0] >> 16); + vector yzz = vector(ubo_load_27_xz[0], ubo_load_27_y, ubo_load_27_xz[1]).yzz; + uint2 ubo_load_28 = U[0].xy; + vector ubo_load_28_xz = vector(f16tof32(ubo_load_28 & 0xFFFF)); + float16_t ubo_load_28_y = f16tof32(ubo_load_28[0] >> 16); + vector zxx = vector(ubo_load_28_xz[0], ubo_load_28_y, ubo_load_28_xz[1]).zxx; + uint2 ubo_load_29 = U[0].xy; + vector ubo_load_29_xz = vector(f16tof32(ubo_load_29 & 0xFFFF)); + float16_t ubo_load_29_y = f16tof32(ubo_load_29[0] >> 16); + vector zxy = vector(ubo_load_29_xz[0], ubo_load_29_y, ubo_load_29_xz[1]).zxy; + uint2 ubo_load_30 = U[0].xy; + vector ubo_load_30_xz = vector(f16tof32(ubo_load_30 & 0xFFFF)); + float16_t ubo_load_30_y = f16tof32(ubo_load_30[0] >> 16); + vector zxz = vector(ubo_load_30_xz[0], ubo_load_30_y, ubo_load_30_xz[1]).zxz; + uint2 ubo_load_31 = U[0].xy; + vector ubo_load_31_xz = vector(f16tof32(ubo_load_31 & 0xFFFF)); + float16_t ubo_load_31_y = f16tof32(ubo_load_31[0] >> 16); + vector zyx = vector(ubo_load_31_xz[0], ubo_load_31_y, ubo_load_31_xz[1]).zyx; + uint2 ubo_load_32 = U[0].xy; + vector ubo_load_32_xz = vector(f16tof32(ubo_load_32 & 0xFFFF)); + float16_t ubo_load_32_y = f16tof32(ubo_load_32[0] >> 16); + vector zyy = vector(ubo_load_32_xz[0], ubo_load_32_y, ubo_load_32_xz[1]).zyy; + uint2 ubo_load_33 = U[0].xy; + vector ubo_load_33_xz = vector(f16tof32(ubo_load_33 & 0xFFFF)); + float16_t ubo_load_33_y = f16tof32(ubo_load_33[0] >> 16); + vector zyz = vector(ubo_load_33_xz[0], ubo_load_33_y, ubo_load_33_xz[1]).zyz; + uint2 ubo_load_34 = U[0].xy; + vector ubo_load_34_xz = vector(f16tof32(ubo_load_34 & 0xFFFF)); + float16_t ubo_load_34_y = f16tof32(ubo_load_34[0] >> 16); + vector zzx = vector(ubo_load_34_xz[0], ubo_load_34_y, ubo_load_34_xz[1]).zzx; + uint2 ubo_load_35 = U[0].xy; + vector ubo_load_35_xz = vector(f16tof32(ubo_load_35 & 0xFFFF)); + float16_t ubo_load_35_y = f16tof32(ubo_load_35[0] >> 16); + vector zzy = vector(ubo_load_35_xz[0], ubo_load_35_y, ubo_load_35_xz[1]).zzy; + uint2 ubo_load_36 = U[0].xy; + vector ubo_load_36_xz = vector(f16tof32(ubo_load_36 & 0xFFFF)); + float16_t ubo_load_36_y = f16tof32(ubo_load_36[0] >> 16); + vector zzz = vector(ubo_load_36_xz[0], ubo_load_36_y, ubo_load_36_xz[1]).zzz; + uint2 ubo_load_37 = U[0].xy; + vector ubo_load_37_xz = vector(f16tof32(ubo_load_37 & 0xFFFF)); + float16_t ubo_load_37_y = f16tof32(ubo_load_37[0] >> 16); + vector xxxx = vector(ubo_load_37_xz[0], ubo_load_37_y, ubo_load_37_xz[1]).xxxx; + uint2 ubo_load_38 = U[0].xy; + vector ubo_load_38_xz = vector(f16tof32(ubo_load_38 & 0xFFFF)); + float16_t ubo_load_38_y = f16tof32(ubo_load_38[0] >> 16); + vector xxxy = vector(ubo_load_38_xz[0], ubo_load_38_y, ubo_load_38_xz[1]).xxxy; + uint2 ubo_load_39 = U[0].xy; + vector ubo_load_39_xz = vector(f16tof32(ubo_load_39 & 0xFFFF)); + float16_t ubo_load_39_y = f16tof32(ubo_load_39[0] >> 16); + vector xxxz = vector(ubo_load_39_xz[0], ubo_load_39_y, ubo_load_39_xz[1]).xxxz; + uint2 ubo_load_40 = U[0].xy; + vector ubo_load_40_xz = vector(f16tof32(ubo_load_40 & 0xFFFF)); + float16_t ubo_load_40_y = f16tof32(ubo_load_40[0] >> 16); + vector xxyx = vector(ubo_load_40_xz[0], ubo_load_40_y, ubo_load_40_xz[1]).xxyx; + uint2 ubo_load_41 = U[0].xy; + vector ubo_load_41_xz = vector(f16tof32(ubo_load_41 & 0xFFFF)); + float16_t ubo_load_41_y = f16tof32(ubo_load_41[0] >> 16); + vector xxyy = vector(ubo_load_41_xz[0], ubo_load_41_y, ubo_load_41_xz[1]).xxyy; + uint2 ubo_load_42 = U[0].xy; + vector ubo_load_42_xz = vector(f16tof32(ubo_load_42 & 0xFFFF)); + float16_t ubo_load_42_y = f16tof32(ubo_load_42[0] >> 16); + vector xxyz = vector(ubo_load_42_xz[0], ubo_load_42_y, ubo_load_42_xz[1]).xxyz; + uint2 ubo_load_43 = U[0].xy; + vector ubo_load_43_xz = vector(f16tof32(ubo_load_43 & 0xFFFF)); + float16_t ubo_load_43_y = f16tof32(ubo_load_43[0] >> 16); + vector xxzx = vector(ubo_load_43_xz[0], ubo_load_43_y, ubo_load_43_xz[1]).xxzx; + uint2 ubo_load_44 = U[0].xy; + vector ubo_load_44_xz = vector(f16tof32(ubo_load_44 & 0xFFFF)); + float16_t ubo_load_44_y = f16tof32(ubo_load_44[0] >> 16); + vector xxzy = vector(ubo_load_44_xz[0], ubo_load_44_y, ubo_load_44_xz[1]).xxzy; + uint2 ubo_load_45 = U[0].xy; + vector ubo_load_45_xz = vector(f16tof32(ubo_load_45 & 0xFFFF)); + float16_t ubo_load_45_y = f16tof32(ubo_load_45[0] >> 16); + vector xxzz = vector(ubo_load_45_xz[0], ubo_load_45_y, ubo_load_45_xz[1]).xxzz; + uint2 ubo_load_46 = U[0].xy; + vector ubo_load_46_xz = vector(f16tof32(ubo_load_46 & 0xFFFF)); + float16_t ubo_load_46_y = f16tof32(ubo_load_46[0] >> 16); + vector xyxx = vector(ubo_load_46_xz[0], ubo_load_46_y, ubo_load_46_xz[1]).xyxx; + uint2 ubo_load_47 = U[0].xy; + vector ubo_load_47_xz = vector(f16tof32(ubo_load_47 & 0xFFFF)); + float16_t ubo_load_47_y = f16tof32(ubo_load_47[0] >> 16); + vector xyxy = vector(ubo_load_47_xz[0], ubo_load_47_y, ubo_load_47_xz[1]).xyxy; + uint2 ubo_load_48 = U[0].xy; + vector ubo_load_48_xz = vector(f16tof32(ubo_load_48 & 0xFFFF)); + float16_t ubo_load_48_y = f16tof32(ubo_load_48[0] >> 16); + vector xyxz = vector(ubo_load_48_xz[0], ubo_load_48_y, ubo_load_48_xz[1]).xyxz; + uint2 ubo_load_49 = U[0].xy; + vector ubo_load_49_xz = vector(f16tof32(ubo_load_49 & 0xFFFF)); + float16_t ubo_load_49_y = f16tof32(ubo_load_49[0] >> 16); + vector xyyx = vector(ubo_load_49_xz[0], ubo_load_49_y, ubo_load_49_xz[1]).xyyx; + uint2 ubo_load_50 = U[0].xy; + vector ubo_load_50_xz = vector(f16tof32(ubo_load_50 & 0xFFFF)); + float16_t ubo_load_50_y = f16tof32(ubo_load_50[0] >> 16); + vector xyyy = vector(ubo_load_50_xz[0], ubo_load_50_y, ubo_load_50_xz[1]).xyyy; + uint2 ubo_load_51 = U[0].xy; + vector ubo_load_51_xz = vector(f16tof32(ubo_load_51 & 0xFFFF)); + float16_t ubo_load_51_y = f16tof32(ubo_load_51[0] >> 16); + vector xyyz = vector(ubo_load_51_xz[0], ubo_load_51_y, ubo_load_51_xz[1]).xyyz; + uint2 ubo_load_52 = U[0].xy; + vector ubo_load_52_xz = vector(f16tof32(ubo_load_52 & 0xFFFF)); + float16_t ubo_load_52_y = f16tof32(ubo_load_52[0] >> 16); + vector xyzx = vector(ubo_load_52_xz[0], ubo_load_52_y, ubo_load_52_xz[1]).xyzx; + uint2 ubo_load_53 = U[0].xy; + vector ubo_load_53_xz = vector(f16tof32(ubo_load_53 & 0xFFFF)); + float16_t ubo_load_53_y = f16tof32(ubo_load_53[0] >> 16); + vector xyzy = vector(ubo_load_53_xz[0], ubo_load_53_y, ubo_load_53_xz[1]).xyzy; + uint2 ubo_load_54 = U[0].xy; + vector ubo_load_54_xz = vector(f16tof32(ubo_load_54 & 0xFFFF)); + float16_t ubo_load_54_y = f16tof32(ubo_load_54[0] >> 16); + vector xyzz = vector(ubo_load_54_xz[0], ubo_load_54_y, ubo_load_54_xz[1]).xyzz; + uint2 ubo_load_55 = U[0].xy; + vector ubo_load_55_xz = vector(f16tof32(ubo_load_55 & 0xFFFF)); + float16_t ubo_load_55_y = f16tof32(ubo_load_55[0] >> 16); + vector xzxx = vector(ubo_load_55_xz[0], ubo_load_55_y, ubo_load_55_xz[1]).xzxx; + uint2 ubo_load_56 = U[0].xy; + vector ubo_load_56_xz = vector(f16tof32(ubo_load_56 & 0xFFFF)); + float16_t ubo_load_56_y = f16tof32(ubo_load_56[0] >> 16); + vector xzxy = vector(ubo_load_56_xz[0], ubo_load_56_y, ubo_load_56_xz[1]).xzxy; + uint2 ubo_load_57 = U[0].xy; + vector ubo_load_57_xz = vector(f16tof32(ubo_load_57 & 0xFFFF)); + float16_t ubo_load_57_y = f16tof32(ubo_load_57[0] >> 16); + vector xzxz = vector(ubo_load_57_xz[0], ubo_load_57_y, ubo_load_57_xz[1]).xzxz; + uint2 ubo_load_58 = U[0].xy; + vector ubo_load_58_xz = vector(f16tof32(ubo_load_58 & 0xFFFF)); + float16_t ubo_load_58_y = f16tof32(ubo_load_58[0] >> 16); + vector xzyx = vector(ubo_load_58_xz[0], ubo_load_58_y, ubo_load_58_xz[1]).xzyx; + uint2 ubo_load_59 = U[0].xy; + vector ubo_load_59_xz = vector(f16tof32(ubo_load_59 & 0xFFFF)); + float16_t ubo_load_59_y = f16tof32(ubo_load_59[0] >> 16); + vector xzyy = vector(ubo_load_59_xz[0], ubo_load_59_y, ubo_load_59_xz[1]).xzyy; + uint2 ubo_load_60 = U[0].xy; + vector ubo_load_60_xz = vector(f16tof32(ubo_load_60 & 0xFFFF)); + float16_t ubo_load_60_y = f16tof32(ubo_load_60[0] >> 16); + vector xzyz = vector(ubo_load_60_xz[0], ubo_load_60_y, ubo_load_60_xz[1]).xzyz; + uint2 ubo_load_61 = U[0].xy; + vector ubo_load_61_xz = vector(f16tof32(ubo_load_61 & 0xFFFF)); + float16_t ubo_load_61_y = f16tof32(ubo_load_61[0] >> 16); + vector xzzx = vector(ubo_load_61_xz[0], ubo_load_61_y, ubo_load_61_xz[1]).xzzx; + uint2 ubo_load_62 = U[0].xy; + vector ubo_load_62_xz = vector(f16tof32(ubo_load_62 & 0xFFFF)); + float16_t ubo_load_62_y = f16tof32(ubo_load_62[0] >> 16); + vector xzzy = vector(ubo_load_62_xz[0], ubo_load_62_y, ubo_load_62_xz[1]).xzzy; + uint2 ubo_load_63 = U[0].xy; + vector ubo_load_63_xz = vector(f16tof32(ubo_load_63 & 0xFFFF)); + float16_t ubo_load_63_y = f16tof32(ubo_load_63[0] >> 16); + vector xzzz = vector(ubo_load_63_xz[0], ubo_load_63_y, ubo_load_63_xz[1]).xzzz; + uint2 ubo_load_64 = U[0].xy; + vector ubo_load_64_xz = vector(f16tof32(ubo_load_64 & 0xFFFF)); + float16_t ubo_load_64_y = f16tof32(ubo_load_64[0] >> 16); + vector yxxx = vector(ubo_load_64_xz[0], ubo_load_64_y, ubo_load_64_xz[1]).yxxx; + uint2 ubo_load_65 = U[0].xy; + vector ubo_load_65_xz = vector(f16tof32(ubo_load_65 & 0xFFFF)); + float16_t ubo_load_65_y = f16tof32(ubo_load_65[0] >> 16); + vector yxxy = vector(ubo_load_65_xz[0], ubo_load_65_y, ubo_load_65_xz[1]).yxxy; + uint2 ubo_load_66 = U[0].xy; + vector ubo_load_66_xz = vector(f16tof32(ubo_load_66 & 0xFFFF)); + float16_t ubo_load_66_y = f16tof32(ubo_load_66[0] >> 16); + vector yxxz = vector(ubo_load_66_xz[0], ubo_load_66_y, ubo_load_66_xz[1]).yxxz; + uint2 ubo_load_67 = U[0].xy; + vector ubo_load_67_xz = vector(f16tof32(ubo_load_67 & 0xFFFF)); + float16_t ubo_load_67_y = f16tof32(ubo_load_67[0] >> 16); + vector yxyx = vector(ubo_load_67_xz[0], ubo_load_67_y, ubo_load_67_xz[1]).yxyx; + uint2 ubo_load_68 = U[0].xy; + vector ubo_load_68_xz = vector(f16tof32(ubo_load_68 & 0xFFFF)); + float16_t ubo_load_68_y = f16tof32(ubo_load_68[0] >> 16); + vector yxyy = vector(ubo_load_68_xz[0], ubo_load_68_y, ubo_load_68_xz[1]).yxyy; + uint2 ubo_load_69 = U[0].xy; + vector ubo_load_69_xz = vector(f16tof32(ubo_load_69 & 0xFFFF)); + float16_t ubo_load_69_y = f16tof32(ubo_load_69[0] >> 16); + vector yxyz = vector(ubo_load_69_xz[0], ubo_load_69_y, ubo_load_69_xz[1]).yxyz; + uint2 ubo_load_70 = U[0].xy; + vector ubo_load_70_xz = vector(f16tof32(ubo_load_70 & 0xFFFF)); + float16_t ubo_load_70_y = f16tof32(ubo_load_70[0] >> 16); + vector yxzx = vector(ubo_load_70_xz[0], ubo_load_70_y, ubo_load_70_xz[1]).yxzx; + uint2 ubo_load_71 = U[0].xy; + vector ubo_load_71_xz = vector(f16tof32(ubo_load_71 & 0xFFFF)); + float16_t ubo_load_71_y = f16tof32(ubo_load_71[0] >> 16); + vector yxzy = vector(ubo_load_71_xz[0], ubo_load_71_y, ubo_load_71_xz[1]).yxzy; + uint2 ubo_load_72 = U[0].xy; + vector ubo_load_72_xz = vector(f16tof32(ubo_load_72 & 0xFFFF)); + float16_t ubo_load_72_y = f16tof32(ubo_load_72[0] >> 16); + vector yxzz = vector(ubo_load_72_xz[0], ubo_load_72_y, ubo_load_72_xz[1]).yxzz; + uint2 ubo_load_73 = U[0].xy; + vector ubo_load_73_xz = vector(f16tof32(ubo_load_73 & 0xFFFF)); + float16_t ubo_load_73_y = f16tof32(ubo_load_73[0] >> 16); + vector yyxx = vector(ubo_load_73_xz[0], ubo_load_73_y, ubo_load_73_xz[1]).yyxx; + uint2 ubo_load_74 = U[0].xy; + vector ubo_load_74_xz = vector(f16tof32(ubo_load_74 & 0xFFFF)); + float16_t ubo_load_74_y = f16tof32(ubo_load_74[0] >> 16); + vector yyxy = vector(ubo_load_74_xz[0], ubo_load_74_y, ubo_load_74_xz[1]).yyxy; + uint2 ubo_load_75 = U[0].xy; + vector ubo_load_75_xz = vector(f16tof32(ubo_load_75 & 0xFFFF)); + float16_t ubo_load_75_y = f16tof32(ubo_load_75[0] >> 16); + vector yyxz = vector(ubo_load_75_xz[0], ubo_load_75_y, ubo_load_75_xz[1]).yyxz; + uint2 ubo_load_76 = U[0].xy; + vector ubo_load_76_xz = vector(f16tof32(ubo_load_76 & 0xFFFF)); + float16_t ubo_load_76_y = f16tof32(ubo_load_76[0] >> 16); + vector yyyx = vector(ubo_load_76_xz[0], ubo_load_76_y, ubo_load_76_xz[1]).yyyx; + uint2 ubo_load_77 = U[0].xy; + vector ubo_load_77_xz = vector(f16tof32(ubo_load_77 & 0xFFFF)); + float16_t ubo_load_77_y = f16tof32(ubo_load_77[0] >> 16); + vector yyyy = vector(ubo_load_77_xz[0], ubo_load_77_y, ubo_load_77_xz[1]).yyyy; + uint2 ubo_load_78 = U[0].xy; + vector ubo_load_78_xz = vector(f16tof32(ubo_load_78 & 0xFFFF)); + float16_t ubo_load_78_y = f16tof32(ubo_load_78[0] >> 16); + vector yyyz = vector(ubo_load_78_xz[0], ubo_load_78_y, ubo_load_78_xz[1]).yyyz; + uint2 ubo_load_79 = U[0].xy; + vector ubo_load_79_xz = vector(f16tof32(ubo_load_79 & 0xFFFF)); + float16_t ubo_load_79_y = f16tof32(ubo_load_79[0] >> 16); + vector yyzx = vector(ubo_load_79_xz[0], ubo_load_79_y, ubo_load_79_xz[1]).yyzx; + uint2 ubo_load_80 = U[0].xy; + vector ubo_load_80_xz = vector(f16tof32(ubo_load_80 & 0xFFFF)); + float16_t ubo_load_80_y = f16tof32(ubo_load_80[0] >> 16); + vector yyzy = vector(ubo_load_80_xz[0], ubo_load_80_y, ubo_load_80_xz[1]).yyzy; + uint2 ubo_load_81 = U[0].xy; + vector ubo_load_81_xz = vector(f16tof32(ubo_load_81 & 0xFFFF)); + float16_t ubo_load_81_y = f16tof32(ubo_load_81[0] >> 16); + vector yyzz = vector(ubo_load_81_xz[0], ubo_load_81_y, ubo_load_81_xz[1]).yyzz; + uint2 ubo_load_82 = U[0].xy; + vector ubo_load_82_xz = vector(f16tof32(ubo_load_82 & 0xFFFF)); + float16_t ubo_load_82_y = f16tof32(ubo_load_82[0] >> 16); + vector yzxx = vector(ubo_load_82_xz[0], ubo_load_82_y, ubo_load_82_xz[1]).yzxx; + uint2 ubo_load_83 = U[0].xy; + vector ubo_load_83_xz = vector(f16tof32(ubo_load_83 & 0xFFFF)); + float16_t ubo_load_83_y = f16tof32(ubo_load_83[0] >> 16); + vector yzxy = vector(ubo_load_83_xz[0], ubo_load_83_y, ubo_load_83_xz[1]).yzxy; + uint2 ubo_load_84 = U[0].xy; + vector ubo_load_84_xz = vector(f16tof32(ubo_load_84 & 0xFFFF)); + float16_t ubo_load_84_y = f16tof32(ubo_load_84[0] >> 16); + vector yzxz = vector(ubo_load_84_xz[0], ubo_load_84_y, ubo_load_84_xz[1]).yzxz; + uint2 ubo_load_85 = U[0].xy; + vector ubo_load_85_xz = vector(f16tof32(ubo_load_85 & 0xFFFF)); + float16_t ubo_load_85_y = f16tof32(ubo_load_85[0] >> 16); + vector yzyx = vector(ubo_load_85_xz[0], ubo_load_85_y, ubo_load_85_xz[1]).yzyx; + uint2 ubo_load_86 = U[0].xy; + vector ubo_load_86_xz = vector(f16tof32(ubo_load_86 & 0xFFFF)); + float16_t ubo_load_86_y = f16tof32(ubo_load_86[0] >> 16); + vector yzyy = vector(ubo_load_86_xz[0], ubo_load_86_y, ubo_load_86_xz[1]).yzyy; + uint2 ubo_load_87 = U[0].xy; + vector ubo_load_87_xz = vector(f16tof32(ubo_load_87 & 0xFFFF)); + float16_t ubo_load_87_y = f16tof32(ubo_load_87[0] >> 16); + vector yzyz = vector(ubo_load_87_xz[0], ubo_load_87_y, ubo_load_87_xz[1]).yzyz; + uint2 ubo_load_88 = U[0].xy; + vector ubo_load_88_xz = vector(f16tof32(ubo_load_88 & 0xFFFF)); + float16_t ubo_load_88_y = f16tof32(ubo_load_88[0] >> 16); + vector yzzx = vector(ubo_load_88_xz[0], ubo_load_88_y, ubo_load_88_xz[1]).yzzx; + uint2 ubo_load_89 = U[0].xy; + vector ubo_load_89_xz = vector(f16tof32(ubo_load_89 & 0xFFFF)); + float16_t ubo_load_89_y = f16tof32(ubo_load_89[0] >> 16); + vector yzzy = vector(ubo_load_89_xz[0], ubo_load_89_y, ubo_load_89_xz[1]).yzzy; + uint2 ubo_load_90 = U[0].xy; + vector ubo_load_90_xz = vector(f16tof32(ubo_load_90 & 0xFFFF)); + float16_t ubo_load_90_y = f16tof32(ubo_load_90[0] >> 16); + vector yzzz = vector(ubo_load_90_xz[0], ubo_load_90_y, ubo_load_90_xz[1]).yzzz; + uint2 ubo_load_91 = U[0].xy; + vector ubo_load_91_xz = vector(f16tof32(ubo_load_91 & 0xFFFF)); + float16_t ubo_load_91_y = f16tof32(ubo_load_91[0] >> 16); + vector zxxx = vector(ubo_load_91_xz[0], ubo_load_91_y, ubo_load_91_xz[1]).zxxx; + uint2 ubo_load_92 = U[0].xy; + vector ubo_load_92_xz = vector(f16tof32(ubo_load_92 & 0xFFFF)); + float16_t ubo_load_92_y = f16tof32(ubo_load_92[0] >> 16); + vector zxxy = vector(ubo_load_92_xz[0], ubo_load_92_y, ubo_load_92_xz[1]).zxxy; + uint2 ubo_load_93 = U[0].xy; + vector ubo_load_93_xz = vector(f16tof32(ubo_load_93 & 0xFFFF)); + float16_t ubo_load_93_y = f16tof32(ubo_load_93[0] >> 16); + vector zxxz = vector(ubo_load_93_xz[0], ubo_load_93_y, ubo_load_93_xz[1]).zxxz; + uint2 ubo_load_94 = U[0].xy; + vector ubo_load_94_xz = vector(f16tof32(ubo_load_94 & 0xFFFF)); + float16_t ubo_load_94_y = f16tof32(ubo_load_94[0] >> 16); + vector zxyx = vector(ubo_load_94_xz[0], ubo_load_94_y, ubo_load_94_xz[1]).zxyx; + uint2 ubo_load_95 = U[0].xy; + vector ubo_load_95_xz = vector(f16tof32(ubo_load_95 & 0xFFFF)); + float16_t ubo_load_95_y = f16tof32(ubo_load_95[0] >> 16); + vector zxyy = vector(ubo_load_95_xz[0], ubo_load_95_y, ubo_load_95_xz[1]).zxyy; + uint2 ubo_load_96 = U[0].xy; + vector ubo_load_96_xz = vector(f16tof32(ubo_load_96 & 0xFFFF)); + float16_t ubo_load_96_y = f16tof32(ubo_load_96[0] >> 16); + vector zxyz = vector(ubo_load_96_xz[0], ubo_load_96_y, ubo_load_96_xz[1]).zxyz; + uint2 ubo_load_97 = U[0].xy; + vector ubo_load_97_xz = vector(f16tof32(ubo_load_97 & 0xFFFF)); + float16_t ubo_load_97_y = f16tof32(ubo_load_97[0] >> 16); + vector zxzx = vector(ubo_load_97_xz[0], ubo_load_97_y, ubo_load_97_xz[1]).zxzx; + uint2 ubo_load_98 = U[0].xy; + vector ubo_load_98_xz = vector(f16tof32(ubo_load_98 & 0xFFFF)); + float16_t ubo_load_98_y = f16tof32(ubo_load_98[0] >> 16); + vector zxzy = vector(ubo_load_98_xz[0], ubo_load_98_y, ubo_load_98_xz[1]).zxzy; + uint2 ubo_load_99 = U[0].xy; + vector ubo_load_99_xz = vector(f16tof32(ubo_load_99 & 0xFFFF)); + float16_t ubo_load_99_y = f16tof32(ubo_load_99[0] >> 16); + vector zxzz = vector(ubo_load_99_xz[0], ubo_load_99_y, ubo_load_99_xz[1]).zxzz; + uint2 ubo_load_100 = U[0].xy; + vector ubo_load_100_xz = vector(f16tof32(ubo_load_100 & 0xFFFF)); + float16_t ubo_load_100_y = f16tof32(ubo_load_100[0] >> 16); + vector zyxx = vector(ubo_load_100_xz[0], ubo_load_100_y, ubo_load_100_xz[1]).zyxx; + uint2 ubo_load_101 = U[0].xy; + vector ubo_load_101_xz = vector(f16tof32(ubo_load_101 & 0xFFFF)); + float16_t ubo_load_101_y = f16tof32(ubo_load_101[0] >> 16); + vector zyxy = vector(ubo_load_101_xz[0], ubo_load_101_y, ubo_load_101_xz[1]).zyxy; + uint2 ubo_load_102 = U[0].xy; + vector ubo_load_102_xz = vector(f16tof32(ubo_load_102 & 0xFFFF)); + float16_t ubo_load_102_y = f16tof32(ubo_load_102[0] >> 16); + vector zyxz = vector(ubo_load_102_xz[0], ubo_load_102_y, ubo_load_102_xz[1]).zyxz; + uint2 ubo_load_103 = U[0].xy; + vector ubo_load_103_xz = vector(f16tof32(ubo_load_103 & 0xFFFF)); + float16_t ubo_load_103_y = f16tof32(ubo_load_103[0] >> 16); + vector zyyx = vector(ubo_load_103_xz[0], ubo_load_103_y, ubo_load_103_xz[1]).zyyx; + uint2 ubo_load_104 = U[0].xy; + vector ubo_load_104_xz = vector(f16tof32(ubo_load_104 & 0xFFFF)); + float16_t ubo_load_104_y = f16tof32(ubo_load_104[0] >> 16); + vector zyyy = vector(ubo_load_104_xz[0], ubo_load_104_y, ubo_load_104_xz[1]).zyyy; + uint2 ubo_load_105 = U[0].xy; + vector ubo_load_105_xz = vector(f16tof32(ubo_load_105 & 0xFFFF)); + float16_t ubo_load_105_y = f16tof32(ubo_load_105[0] >> 16); + vector zyyz = vector(ubo_load_105_xz[0], ubo_load_105_y, ubo_load_105_xz[1]).zyyz; + uint2 ubo_load_106 = U[0].xy; + vector ubo_load_106_xz = vector(f16tof32(ubo_load_106 & 0xFFFF)); + float16_t ubo_load_106_y = f16tof32(ubo_load_106[0] >> 16); + vector zyzx = vector(ubo_load_106_xz[0], ubo_load_106_y, ubo_load_106_xz[1]).zyzx; + uint2 ubo_load_107 = U[0].xy; + vector ubo_load_107_xz = vector(f16tof32(ubo_load_107 & 0xFFFF)); + float16_t ubo_load_107_y = f16tof32(ubo_load_107[0] >> 16); + vector zyzy = vector(ubo_load_107_xz[0], ubo_load_107_y, ubo_load_107_xz[1]).zyzy; + uint2 ubo_load_108 = U[0].xy; + vector ubo_load_108_xz = vector(f16tof32(ubo_load_108 & 0xFFFF)); + float16_t ubo_load_108_y = f16tof32(ubo_load_108[0] >> 16); + vector zyzz = vector(ubo_load_108_xz[0], ubo_load_108_y, ubo_load_108_xz[1]).zyzz; + uint2 ubo_load_109 = U[0].xy; + vector ubo_load_109_xz = vector(f16tof32(ubo_load_109 & 0xFFFF)); + float16_t ubo_load_109_y = f16tof32(ubo_load_109[0] >> 16); + vector zzxx = vector(ubo_load_109_xz[0], ubo_load_109_y, ubo_load_109_xz[1]).zzxx; + uint2 ubo_load_110 = U[0].xy; + vector ubo_load_110_xz = vector(f16tof32(ubo_load_110 & 0xFFFF)); + float16_t ubo_load_110_y = f16tof32(ubo_load_110[0] >> 16); + vector zzxy = vector(ubo_load_110_xz[0], ubo_load_110_y, ubo_load_110_xz[1]).zzxy; + uint2 ubo_load_111 = U[0].xy; + vector ubo_load_111_xz = vector(f16tof32(ubo_load_111 & 0xFFFF)); + float16_t ubo_load_111_y = f16tof32(ubo_load_111[0] >> 16); + vector zzxz = vector(ubo_load_111_xz[0], ubo_load_111_y, ubo_load_111_xz[1]).zzxz; + uint2 ubo_load_112 = U[0].xy; + vector ubo_load_112_xz = vector(f16tof32(ubo_load_112 & 0xFFFF)); + float16_t ubo_load_112_y = f16tof32(ubo_load_112[0] >> 16); + vector zzyx = vector(ubo_load_112_xz[0], ubo_load_112_y, ubo_load_112_xz[1]).zzyx; + uint2 ubo_load_113 = U[0].xy; + vector ubo_load_113_xz = vector(f16tof32(ubo_load_113 & 0xFFFF)); + float16_t ubo_load_113_y = f16tof32(ubo_load_113[0] >> 16); + vector zzyy = vector(ubo_load_113_xz[0], ubo_load_113_y, ubo_load_113_xz[1]).zzyy; + uint2 ubo_load_114 = U[0].xy; + vector ubo_load_114_xz = vector(f16tof32(ubo_load_114 & 0xFFFF)); + float16_t ubo_load_114_y = f16tof32(ubo_load_114[0] >> 16); + vector zzyz = vector(ubo_load_114_xz[0], ubo_load_114_y, ubo_load_114_xz[1]).zzyz; + uint2 ubo_load_115 = U[0].xy; + vector ubo_load_115_xz = vector(f16tof32(ubo_load_115 & 0xFFFF)); + float16_t ubo_load_115_y = f16tof32(ubo_load_115[0] >> 16); + vector zzzx = vector(ubo_load_115_xz[0], ubo_load_115_y, ubo_load_115_xz[1]).zzzx; + uint2 ubo_load_116 = U[0].xy; + vector ubo_load_116_xz = vector(f16tof32(ubo_load_116 & 0xFFFF)); + float16_t ubo_load_116_y = f16tof32(ubo_load_116[0] >> 16); + vector zzzy = vector(ubo_load_116_xz[0], ubo_load_116_y, ubo_load_116_xz[1]).zzzy; + uint2 ubo_load_117 = U[0].xy; + vector ubo_load_117_xz = vector(f16tof32(ubo_load_117 & 0xFFFF)); + float16_t ubo_load_117_y = f16tof32(ubo_load_117[0] >> 16); + vector zzzz = vector(ubo_load_117_xz[0], ubo_load_117_y, ubo_load_117_xz[1]).zzzz; +} diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.glsl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.glsl index a5570c5213..7794d4888f 100644 --- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.glsl +++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.glsl @@ -1,18 +1,141 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require -expressions/swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet - v: vec3, - ^^^^^^^^^ - -expressions/swizzle/read/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void unused_entry_point() { + return; +} struct S { -^^^^^^ + f16vec3 v; + uint pad; + uint pad_1; +}; -expressions/swizzle/read/packed_vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var U : S; - ^ +layout(binding = 0, std140) uniform U_block_ubo { + S inner; +} U; + +void f() { + f16vec3 v = U.inner.v; + float16_t x = U.inner.v.x; + float16_t y = U.inner.v.y; + float16_t z = U.inner.v.z; + f16vec2 xx = U.inner.v.xx; + f16vec2 xy = U.inner.v.xy; + f16vec2 xz = U.inner.v.xz; + f16vec2 yx = U.inner.v.yx; + f16vec2 yy = U.inner.v.yy; + f16vec2 yz = U.inner.v.yz; + f16vec2 zx = U.inner.v.zx; + f16vec2 zy = U.inner.v.zy; + f16vec2 zz = U.inner.v.zz; + f16vec3 xxx = U.inner.v.xxx; + f16vec3 xxy = U.inner.v.xxy; + f16vec3 xxz = U.inner.v.xxz; + f16vec3 xyx = U.inner.v.xyx; + f16vec3 xyy = U.inner.v.xyy; + f16vec3 xyz = U.inner.v.xyz; + f16vec3 xzx = U.inner.v.xzx; + f16vec3 xzy = U.inner.v.xzy; + f16vec3 xzz = U.inner.v.xzz; + f16vec3 yxx = U.inner.v.yxx; + f16vec3 yxy = U.inner.v.yxy; + f16vec3 yxz = U.inner.v.yxz; + f16vec3 yyx = U.inner.v.yyx; + f16vec3 yyy = U.inner.v.yyy; + f16vec3 yyz = U.inner.v.yyz; + f16vec3 yzx = U.inner.v.yzx; + f16vec3 yzy = U.inner.v.yzy; + f16vec3 yzz = U.inner.v.yzz; + f16vec3 zxx = U.inner.v.zxx; + f16vec3 zxy = U.inner.v.zxy; + f16vec3 zxz = U.inner.v.zxz; + f16vec3 zyx = U.inner.v.zyx; + f16vec3 zyy = U.inner.v.zyy; + f16vec3 zyz = U.inner.v.zyz; + f16vec3 zzx = U.inner.v.zzx; + f16vec3 zzy = U.inner.v.zzy; + f16vec3 zzz = U.inner.v.zzz; + f16vec4 xxxx = U.inner.v.xxxx; + f16vec4 xxxy = U.inner.v.xxxy; + f16vec4 xxxz = U.inner.v.xxxz; + f16vec4 xxyx = U.inner.v.xxyx; + f16vec4 xxyy = U.inner.v.xxyy; + f16vec4 xxyz = U.inner.v.xxyz; + f16vec4 xxzx = U.inner.v.xxzx; + f16vec4 xxzy = U.inner.v.xxzy; + f16vec4 xxzz = U.inner.v.xxzz; + f16vec4 xyxx = U.inner.v.xyxx; + f16vec4 xyxy = U.inner.v.xyxy; + f16vec4 xyxz = U.inner.v.xyxz; + f16vec4 xyyx = U.inner.v.xyyx; + f16vec4 xyyy = U.inner.v.xyyy; + f16vec4 xyyz = U.inner.v.xyyz; + f16vec4 xyzx = U.inner.v.xyzx; + f16vec4 xyzy = U.inner.v.xyzy; + f16vec4 xyzz = U.inner.v.xyzz; + f16vec4 xzxx = U.inner.v.xzxx; + f16vec4 xzxy = U.inner.v.xzxy; + f16vec4 xzxz = U.inner.v.xzxz; + f16vec4 xzyx = U.inner.v.xzyx; + f16vec4 xzyy = U.inner.v.xzyy; + f16vec4 xzyz = U.inner.v.xzyz; + f16vec4 xzzx = U.inner.v.xzzx; + f16vec4 xzzy = U.inner.v.xzzy; + f16vec4 xzzz = U.inner.v.xzzz; + f16vec4 yxxx = U.inner.v.yxxx; + f16vec4 yxxy = U.inner.v.yxxy; + f16vec4 yxxz = U.inner.v.yxxz; + f16vec4 yxyx = U.inner.v.yxyx; + f16vec4 yxyy = U.inner.v.yxyy; + f16vec4 yxyz = U.inner.v.yxyz; + f16vec4 yxzx = U.inner.v.yxzx; + f16vec4 yxzy = U.inner.v.yxzy; + f16vec4 yxzz = U.inner.v.yxzz; + f16vec4 yyxx = U.inner.v.yyxx; + f16vec4 yyxy = U.inner.v.yyxy; + f16vec4 yyxz = U.inner.v.yyxz; + f16vec4 yyyx = U.inner.v.yyyx; + f16vec4 yyyy = U.inner.v.yyyy; + f16vec4 yyyz = U.inner.v.yyyz; + f16vec4 yyzx = U.inner.v.yyzx; + f16vec4 yyzy = U.inner.v.yyzy; + f16vec4 yyzz = U.inner.v.yyzz; + f16vec4 yzxx = U.inner.v.yzxx; + f16vec4 yzxy = U.inner.v.yzxy; + f16vec4 yzxz = U.inner.v.yzxz; + f16vec4 yzyx = U.inner.v.yzyx; + f16vec4 yzyy = U.inner.v.yzyy; + f16vec4 yzyz = U.inner.v.yzyz; + f16vec4 yzzx = U.inner.v.yzzx; + f16vec4 yzzy = U.inner.v.yzzy; + f16vec4 yzzz = U.inner.v.yzzz; + f16vec4 zxxx = U.inner.v.zxxx; + f16vec4 zxxy = U.inner.v.zxxy; + f16vec4 zxxz = U.inner.v.zxxz; + f16vec4 zxyx = U.inner.v.zxyx; + f16vec4 zxyy = U.inner.v.zxyy; + f16vec4 zxyz = U.inner.v.zxyz; + f16vec4 zxzx = U.inner.v.zxzx; + f16vec4 zxzy = U.inner.v.zxzy; + f16vec4 zxzz = U.inner.v.zxzz; + f16vec4 zyxx = U.inner.v.zyxx; + f16vec4 zyxy = U.inner.v.zyxy; + f16vec4 zyxz = U.inner.v.zyxz; + f16vec4 zyyx = U.inner.v.zyyx; + f16vec4 zyyy = U.inner.v.zyyy; + f16vec4 zyyz = U.inner.v.zyyz; + f16vec4 zyzx = U.inner.v.zyzx; + f16vec4 zyzy = U.inner.v.zyzy; + f16vec4 zyzz = U.inner.v.zyzz; + f16vec4 zzxx = U.inner.v.zzxx; + f16vec4 zzxy = U.inner.v.zzxy; + f16vec4 zzxz = U.inner.v.zzxz; + f16vec4 zzyx = U.inner.v.zzyx; + f16vec4 zzyy = U.inner.v.zzyy; + f16vec4 zzyz = U.inner.v.zzyz; + f16vec4 zzzx = U.inner.v.zzzx; + f16vec4 zzzy = U.inner.v.zzzy; + f16vec4 zzzz = U.inner.v.zzzz; +} diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.msl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.msl index 6c8063b2f1..ab91c3e214 100644 --- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.msl +++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.msl @@ -1,18 +1,145 @@ -SKIP: FAILED +#include -swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet - v: vec3, - ^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; -swizzle/read/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + /* 0x0000 */ packed_half3 v; + /* 0x0006 */ tint_array tint_pad; +}; -swizzle/read/packed_vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var U : S; - ^ +void f(const constant S* const tint_symbol) { + half3 v = half3((*(tint_symbol)).v); + half x = (*(tint_symbol)).v[0]; + half y = (*(tint_symbol)).v[1]; + half z = (*(tint_symbol)).v[2]; + half2 xx = half3((*(tint_symbol)).v).xx; + half2 xy = half3((*(tint_symbol)).v).xy; + half2 xz = half3((*(tint_symbol)).v).xz; + half2 yx = half3((*(tint_symbol)).v).yx; + half2 yy = half3((*(tint_symbol)).v).yy; + half2 yz = half3((*(tint_symbol)).v).yz; + half2 zx = half3((*(tint_symbol)).v).zx; + half2 zy = half3((*(tint_symbol)).v).zy; + half2 zz = half3((*(tint_symbol)).v).zz; + half3 xxx = half3((*(tint_symbol)).v).xxx; + half3 xxy = half3((*(tint_symbol)).v).xxy; + half3 xxz = half3((*(tint_symbol)).v).xxz; + half3 xyx = half3((*(tint_symbol)).v).xyx; + half3 xyy = half3((*(tint_symbol)).v).xyy; + half3 xyz = half3((*(tint_symbol)).v).xyz; + half3 xzx = half3((*(tint_symbol)).v).xzx; + half3 xzy = half3((*(tint_symbol)).v).xzy; + half3 xzz = half3((*(tint_symbol)).v).xzz; + half3 yxx = half3((*(tint_symbol)).v).yxx; + half3 yxy = half3((*(tint_symbol)).v).yxy; + half3 yxz = half3((*(tint_symbol)).v).yxz; + half3 yyx = half3((*(tint_symbol)).v).yyx; + half3 yyy = half3((*(tint_symbol)).v).yyy; + half3 yyz = half3((*(tint_symbol)).v).yyz; + half3 yzx = half3((*(tint_symbol)).v).yzx; + half3 yzy = half3((*(tint_symbol)).v).yzy; + half3 yzz = half3((*(tint_symbol)).v).yzz; + half3 zxx = half3((*(tint_symbol)).v).zxx; + half3 zxy = half3((*(tint_symbol)).v).zxy; + half3 zxz = half3((*(tint_symbol)).v).zxz; + half3 zyx = half3((*(tint_symbol)).v).zyx; + half3 zyy = half3((*(tint_symbol)).v).zyy; + half3 zyz = half3((*(tint_symbol)).v).zyz; + half3 zzx = half3((*(tint_symbol)).v).zzx; + half3 zzy = half3((*(tint_symbol)).v).zzy; + half3 zzz = half3((*(tint_symbol)).v).zzz; + half4 xxxx = half3((*(tint_symbol)).v).xxxx; + half4 xxxy = half3((*(tint_symbol)).v).xxxy; + half4 xxxz = half3((*(tint_symbol)).v).xxxz; + half4 xxyx = half3((*(tint_symbol)).v).xxyx; + half4 xxyy = half3((*(tint_symbol)).v).xxyy; + half4 xxyz = half3((*(tint_symbol)).v).xxyz; + half4 xxzx = half3((*(tint_symbol)).v).xxzx; + half4 xxzy = half3((*(tint_symbol)).v).xxzy; + half4 xxzz = half3((*(tint_symbol)).v).xxzz; + half4 xyxx = half3((*(tint_symbol)).v).xyxx; + half4 xyxy = half3((*(tint_symbol)).v).xyxy; + half4 xyxz = half3((*(tint_symbol)).v).xyxz; + half4 xyyx = half3((*(tint_symbol)).v).xyyx; + half4 xyyy = half3((*(tint_symbol)).v).xyyy; + half4 xyyz = half3((*(tint_symbol)).v).xyyz; + half4 xyzx = half3((*(tint_symbol)).v).xyzx; + half4 xyzy = half3((*(tint_symbol)).v).xyzy; + half4 xyzz = half3((*(tint_symbol)).v).xyzz; + half4 xzxx = half3((*(tint_symbol)).v).xzxx; + half4 xzxy = half3((*(tint_symbol)).v).xzxy; + half4 xzxz = half3((*(tint_symbol)).v).xzxz; + half4 xzyx = half3((*(tint_symbol)).v).xzyx; + half4 xzyy = half3((*(tint_symbol)).v).xzyy; + half4 xzyz = half3((*(tint_symbol)).v).xzyz; + half4 xzzx = half3((*(tint_symbol)).v).xzzx; + half4 xzzy = half3((*(tint_symbol)).v).xzzy; + half4 xzzz = half3((*(tint_symbol)).v).xzzz; + half4 yxxx = half3((*(tint_symbol)).v).yxxx; + half4 yxxy = half3((*(tint_symbol)).v).yxxy; + half4 yxxz = half3((*(tint_symbol)).v).yxxz; + half4 yxyx = half3((*(tint_symbol)).v).yxyx; + half4 yxyy = half3((*(tint_symbol)).v).yxyy; + half4 yxyz = half3((*(tint_symbol)).v).yxyz; + half4 yxzx = half3((*(tint_symbol)).v).yxzx; + half4 yxzy = half3((*(tint_symbol)).v).yxzy; + half4 yxzz = half3((*(tint_symbol)).v).yxzz; + half4 yyxx = half3((*(tint_symbol)).v).yyxx; + half4 yyxy = half3((*(tint_symbol)).v).yyxy; + half4 yyxz = half3((*(tint_symbol)).v).yyxz; + half4 yyyx = half3((*(tint_symbol)).v).yyyx; + half4 yyyy = half3((*(tint_symbol)).v).yyyy; + half4 yyyz = half3((*(tint_symbol)).v).yyyz; + half4 yyzx = half3((*(tint_symbol)).v).yyzx; + half4 yyzy = half3((*(tint_symbol)).v).yyzy; + half4 yyzz = half3((*(tint_symbol)).v).yyzz; + half4 yzxx = half3((*(tint_symbol)).v).yzxx; + half4 yzxy = half3((*(tint_symbol)).v).yzxy; + half4 yzxz = half3((*(tint_symbol)).v).yzxz; + half4 yzyx = half3((*(tint_symbol)).v).yzyx; + half4 yzyy = half3((*(tint_symbol)).v).yzyy; + half4 yzyz = half3((*(tint_symbol)).v).yzyz; + half4 yzzx = half3((*(tint_symbol)).v).yzzx; + half4 yzzy = half3((*(tint_symbol)).v).yzzy; + half4 yzzz = half3((*(tint_symbol)).v).yzzz; + half4 zxxx = half3((*(tint_symbol)).v).zxxx; + half4 zxxy = half3((*(tint_symbol)).v).zxxy; + half4 zxxz = half3((*(tint_symbol)).v).zxxz; + half4 zxyx = half3((*(tint_symbol)).v).zxyx; + half4 zxyy = half3((*(tint_symbol)).v).zxyy; + half4 zxyz = half3((*(tint_symbol)).v).zxyz; + half4 zxzx = half3((*(tint_symbol)).v).zxzx; + half4 zxzy = half3((*(tint_symbol)).v).zxzy; + half4 zxzz = half3((*(tint_symbol)).v).zxzz; + half4 zyxx = half3((*(tint_symbol)).v).zyxx; + half4 zyxy = half3((*(tint_symbol)).v).zyxy; + half4 zyxz = half3((*(tint_symbol)).v).zyxz; + half4 zyyx = half3((*(tint_symbol)).v).zyyx; + half4 zyyy = half3((*(tint_symbol)).v).zyyy; + half4 zyyz = half3((*(tint_symbol)).v).zyyz; + half4 zyzx = half3((*(tint_symbol)).v).zyzx; + half4 zyzy = half3((*(tint_symbol)).v).zyzy; + half4 zyzz = half3((*(tint_symbol)).v).zyzz; + half4 zzxx = half3((*(tint_symbol)).v).zzxx; + half4 zzxy = half3((*(tint_symbol)).v).zzxy; + half4 zzxz = half3((*(tint_symbol)).v).zzxz; + half4 zzyx = half3((*(tint_symbol)).v).zzyx; + half4 zzyy = half3((*(tint_symbol)).v).zzyy; + half4 zzyz = half3((*(tint_symbol)).v).zzyz; + half4 zzzx = half3((*(tint_symbol)).v).zzzx; + half4 zzzy = half3((*(tint_symbol)).v).zzzy; + half4 zzzz = half3((*(tint_symbol)).v).zzzz; +} diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.spvasm b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.spvasm index 6c8063b2f1..d7796c55e7 100644 --- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.spvasm +++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.spvasm @@ -1,18 +1,780 @@ -SKIP: FAILED - -swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet - v: vec3, - ^^^^^^^^^ - -swizzle/read/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -swizzle/read/packed_vec3/f16.wgsl:6:36 note: see declaration of variable -@group(0) @binding(0) var U : S; - ^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 509 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %unused_entry_point "unused_entry_point" + OpExecutionMode %unused_entry_point LocalSize 1 1 1 + OpName %U_block "U_block" + OpMemberName %U_block 0 "inner" + OpName %S "S" + OpMemberName %S 0 "v" + OpName %U "U" + OpName %unused_entry_point "unused_entry_point" + OpName %f "f" + OpName %v "v" + OpName %x "x" + OpName %y "y" + OpName %z "z" + OpName %xx "xx" + OpName %xy "xy" + OpName %xz "xz" + OpName %yx "yx" + OpName %yy "yy" + OpName %yz "yz" + OpName %zx "zx" + OpName %zy "zy" + OpName %zz "zz" + OpName %xxx "xxx" + OpName %xxy "xxy" + OpName %xxz "xxz" + OpName %xyx "xyx" + OpName %xyy "xyy" + OpName %xyz "xyz" + OpName %xzx "xzx" + OpName %xzy "xzy" + OpName %xzz "xzz" + OpName %yxx "yxx" + OpName %yxy "yxy" + OpName %yxz "yxz" + OpName %yyx "yyx" + OpName %yyy "yyy" + OpName %yyz "yyz" + OpName %yzx "yzx" + OpName %yzy "yzy" + OpName %yzz "yzz" + OpName %zxx "zxx" + OpName %zxy "zxy" + OpName %zxz "zxz" + OpName %zyx "zyx" + OpName %zyy "zyy" + OpName %zyz "zyz" + OpName %zzx "zzx" + OpName %zzy "zzy" + OpName %zzz "zzz" + OpName %xxxx "xxxx" + OpName %xxxy "xxxy" + OpName %xxxz "xxxz" + OpName %xxyx "xxyx" + OpName %xxyy "xxyy" + OpName %xxyz "xxyz" + OpName %xxzx "xxzx" + OpName %xxzy "xxzy" + OpName %xxzz "xxzz" + OpName %xyxx "xyxx" + OpName %xyxy "xyxy" + OpName %xyxz "xyxz" + OpName %xyyx "xyyx" + OpName %xyyy "xyyy" + OpName %xyyz "xyyz" + OpName %xyzx "xyzx" + OpName %xyzy "xyzy" + OpName %xyzz "xyzz" + OpName %xzxx "xzxx" + OpName %xzxy "xzxy" + OpName %xzxz "xzxz" + OpName %xzyx "xzyx" + OpName %xzyy "xzyy" + OpName %xzyz "xzyz" + OpName %xzzx "xzzx" + OpName %xzzy "xzzy" + OpName %xzzz "xzzz" + OpName %yxxx "yxxx" + OpName %yxxy "yxxy" + OpName %yxxz "yxxz" + OpName %yxyx "yxyx" + OpName %yxyy "yxyy" + OpName %yxyz "yxyz" + OpName %yxzx "yxzx" + OpName %yxzy "yxzy" + OpName %yxzz "yxzz" + OpName %yyxx "yyxx" + OpName %yyxy "yyxy" + OpName %yyxz "yyxz" + OpName %yyyx "yyyx" + OpName %yyyy "yyyy" + OpName %yyyz "yyyz" + OpName %yyzx "yyzx" + OpName %yyzy "yyzy" + OpName %yyzz "yyzz" + OpName %yzxx "yzxx" + OpName %yzxy "yzxy" + OpName %yzxz "yzxz" + OpName %yzyx "yzyx" + OpName %yzyy "yzyy" + OpName %yzyz "yzyz" + OpName %yzzx "yzzx" + OpName %yzzy "yzzy" + OpName %yzzz "yzzz" + OpName %zxxx "zxxx" + OpName %zxxy "zxxy" + OpName %zxxz "zxxz" + OpName %zxyx "zxyx" + OpName %zxyy "zxyy" + OpName %zxyz "zxyz" + OpName %zxzx "zxzx" + OpName %zxzy "zxzy" + OpName %zxzz "zxzz" + OpName %zyxx "zyxx" + OpName %zyxy "zyxy" + OpName %zyxz "zyxz" + OpName %zyyx "zyyx" + OpName %zyyy "zyyy" + OpName %zyyz "zyyz" + OpName %zyzx "zyzx" + OpName %zyzy "zyzy" + OpName %zyzz "zyzz" + OpName %zzxx "zzxx" + OpName %zzxy "zzxy" + OpName %zzxz "zzxz" + OpName %zzyx "zzyx" + OpName %zzyy "zzyy" + OpName %zzyz "zzyz" + OpName %zzzx "zzzx" + OpName %zzzy "zzzy" + OpName %zzzz "zzzz" + OpDecorate %U_block Block + OpMemberDecorate %U_block 0 Offset 0 + OpMemberDecorate %S 0 Offset 0 + OpDecorate %U NonWritable + OpDecorate %U DescriptorSet 0 + OpDecorate %U Binding 0 + %half = OpTypeFloat 16 + %v3half = OpTypeVector %half 3 + %S = OpTypeStruct %v3half + %U_block = OpTypeStruct %S +%_ptr_Uniform_U_block = OpTypePointer Uniform %U_block + %U = OpVariable %_ptr_Uniform_U_block Uniform + %void = OpTypeVoid + %7 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 +%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half +%_ptr_Function_v3half = OpTypePointer Function %v3half + %20 = OpConstantNull %v3half +%_ptr_Uniform_half = OpTypePointer Uniform %half +%_ptr_Function_half = OpTypePointer Function %half + %26 = OpConstantNull %half + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %v2half = OpTypeVector %half 2 +%_ptr_Function_v2half = OpTypePointer Function %v2half + %41 = OpConstantNull %v2half + %v4half = OpTypeVector %half 4 +%_ptr_Function_v4half = OpTypePointer Function %v4half + %188 = OpConstantNull %v4half +%unused_entry_point = OpFunction %void None %7 + %10 = OpLabel + OpReturn + OpFunctionEnd + %f = OpFunction %void None %7 + %12 = OpLabel + %v = OpVariable %_ptr_Function_v3half Function %20 + %x = OpVariable %_ptr_Function_half Function %26 + %y = OpVariable %_ptr_Function_half Function %26 + %z = OpVariable %_ptr_Function_half Function %26 + %xx = OpVariable %_ptr_Function_v2half Function %41 + %xy = OpVariable %_ptr_Function_v2half Function %41 + %xz = OpVariable %_ptr_Function_v2half Function %41 + %yx = OpVariable %_ptr_Function_v2half Function %41 + %yy = OpVariable %_ptr_Function_v2half Function %41 + %yz = OpVariable %_ptr_Function_v2half Function %41 + %zx = OpVariable %_ptr_Function_v2half Function %41 + %zy = OpVariable %_ptr_Function_v2half Function %41 + %zz = OpVariable %_ptr_Function_v2half Function %41 + %xxx = OpVariable %_ptr_Function_v3half Function %20 + %xxy = OpVariable %_ptr_Function_v3half Function %20 + %xxz = OpVariable %_ptr_Function_v3half Function %20 + %xyx = OpVariable %_ptr_Function_v3half Function %20 + %xyy = OpVariable %_ptr_Function_v3half Function %20 + %xyz = OpVariable %_ptr_Function_v3half Function %20 + %xzx = OpVariable %_ptr_Function_v3half Function %20 + %xzy = OpVariable %_ptr_Function_v3half Function %20 + %xzz = OpVariable %_ptr_Function_v3half Function %20 + %yxx = OpVariable %_ptr_Function_v3half Function %20 + %yxy = OpVariable %_ptr_Function_v3half Function %20 + %yxz = OpVariable %_ptr_Function_v3half Function %20 + %yyx = OpVariable %_ptr_Function_v3half Function %20 + %yyy = OpVariable %_ptr_Function_v3half Function %20 + %yyz = OpVariable %_ptr_Function_v3half Function %20 + %yzx = OpVariable %_ptr_Function_v3half Function %20 + %yzy = OpVariable %_ptr_Function_v3half Function %20 + %yzz = OpVariable %_ptr_Function_v3half Function %20 + %zxx = OpVariable %_ptr_Function_v3half Function %20 + %zxy = OpVariable %_ptr_Function_v3half Function %20 + %zxz = OpVariable %_ptr_Function_v3half Function %20 + %zyx = OpVariable %_ptr_Function_v3half Function %20 + %zyy = OpVariable %_ptr_Function_v3half Function %20 + %zyz = OpVariable %_ptr_Function_v3half Function %20 + %zzx = OpVariable %_ptr_Function_v3half Function %20 + %zzy = OpVariable %_ptr_Function_v3half Function %20 + %zzz = OpVariable %_ptr_Function_v3half Function %20 + %xxxx = OpVariable %_ptr_Function_v4half Function %188 + %xxxy = OpVariable %_ptr_Function_v4half Function %188 + %xxxz = OpVariable %_ptr_Function_v4half Function %188 + %xxyx = OpVariable %_ptr_Function_v4half Function %188 + %xxyy = OpVariable %_ptr_Function_v4half Function %188 + %xxyz = OpVariable %_ptr_Function_v4half Function %188 + %xxzx = OpVariable %_ptr_Function_v4half Function %188 + %xxzy = OpVariable %_ptr_Function_v4half Function %188 + %xxzz = OpVariable %_ptr_Function_v4half Function %188 + %xyxx = OpVariable %_ptr_Function_v4half Function %188 + %xyxy = OpVariable %_ptr_Function_v4half Function %188 + %xyxz = OpVariable %_ptr_Function_v4half Function %188 + %xyyx = OpVariable %_ptr_Function_v4half Function %188 + %xyyy = OpVariable %_ptr_Function_v4half Function %188 + %xyyz = OpVariable %_ptr_Function_v4half Function %188 + %xyzx = OpVariable %_ptr_Function_v4half Function %188 + %xyzy = OpVariable %_ptr_Function_v4half Function %188 + %xyzz = OpVariable %_ptr_Function_v4half Function %188 + %xzxx = OpVariable %_ptr_Function_v4half Function %188 + %xzxy = OpVariable %_ptr_Function_v4half Function %188 + %xzxz = OpVariable %_ptr_Function_v4half Function %188 + %xzyx = OpVariable %_ptr_Function_v4half Function %188 + %xzyy = OpVariable %_ptr_Function_v4half Function %188 + %xzyz = OpVariable %_ptr_Function_v4half Function %188 + %xzzx = OpVariable %_ptr_Function_v4half Function %188 + %xzzy = OpVariable %_ptr_Function_v4half Function %188 + %xzzz = OpVariable %_ptr_Function_v4half Function %188 + %yxxx = OpVariable %_ptr_Function_v4half Function %188 + %yxxy = OpVariable %_ptr_Function_v4half Function %188 + %yxxz = OpVariable %_ptr_Function_v4half Function %188 + %yxyx = OpVariable %_ptr_Function_v4half Function %188 + %yxyy = OpVariable %_ptr_Function_v4half Function %188 + %yxyz = OpVariable %_ptr_Function_v4half Function %188 + %yxzx = OpVariable %_ptr_Function_v4half Function %188 + %yxzy = OpVariable %_ptr_Function_v4half Function %188 + %yxzz = OpVariable %_ptr_Function_v4half Function %188 + %yyxx = OpVariable %_ptr_Function_v4half Function %188 + %yyxy = OpVariable %_ptr_Function_v4half Function %188 + %yyxz = OpVariable %_ptr_Function_v4half Function %188 + %yyyx = OpVariable %_ptr_Function_v4half Function %188 + %yyyy = OpVariable %_ptr_Function_v4half Function %188 + %yyyz = OpVariable %_ptr_Function_v4half Function %188 + %yyzx = OpVariable %_ptr_Function_v4half Function %188 + %yyzy = OpVariable %_ptr_Function_v4half Function %188 + %yyzz = OpVariable %_ptr_Function_v4half Function %188 + %yzxx = OpVariable %_ptr_Function_v4half Function %188 + %yzxy = OpVariable %_ptr_Function_v4half Function %188 + %yzxz = OpVariable %_ptr_Function_v4half Function %188 + %yzyx = OpVariable %_ptr_Function_v4half Function %188 + %yzyy = OpVariable %_ptr_Function_v4half Function %188 + %yzyz = OpVariable %_ptr_Function_v4half Function %188 + %yzzx = OpVariable %_ptr_Function_v4half Function %188 + %yzzy = OpVariable %_ptr_Function_v4half Function %188 + %yzzz = OpVariable %_ptr_Function_v4half Function %188 + %zxxx = OpVariable %_ptr_Function_v4half Function %188 + %zxxy = OpVariable %_ptr_Function_v4half Function %188 + %zxxz = OpVariable %_ptr_Function_v4half Function %188 + %zxyx = OpVariable %_ptr_Function_v4half Function %188 + %zxyy = OpVariable %_ptr_Function_v4half Function %188 + %zxyz = OpVariable %_ptr_Function_v4half Function %188 + %zxzx = OpVariable %_ptr_Function_v4half Function %188 + %zxzy = OpVariable %_ptr_Function_v4half Function %188 + %zxzz = OpVariable %_ptr_Function_v4half Function %188 + %zyxx = OpVariable %_ptr_Function_v4half Function %188 + %zyxy = OpVariable %_ptr_Function_v4half Function %188 + %zyxz = OpVariable %_ptr_Function_v4half Function %188 + %zyyx = OpVariable %_ptr_Function_v4half Function %188 + %zyyy = OpVariable %_ptr_Function_v4half Function %188 + %zyyz = OpVariable %_ptr_Function_v4half Function %188 + %zyzx = OpVariable %_ptr_Function_v4half Function %188 + %zyzy = OpVariable %_ptr_Function_v4half Function %188 + %zyzz = OpVariable %_ptr_Function_v4half Function %188 + %zzxx = OpVariable %_ptr_Function_v4half Function %188 + %zzxy = OpVariable %_ptr_Function_v4half Function %188 + %zzxz = OpVariable %_ptr_Function_v4half Function %188 + %zzyx = OpVariable %_ptr_Function_v4half Function %188 + %zzyy = OpVariable %_ptr_Function_v4half Function %188 + %zzyz = OpVariable %_ptr_Function_v4half Function %188 + %zzzx = OpVariable %_ptr_Function_v4half Function %188 + %zzzy = OpVariable %_ptr_Function_v4half Function %188 + %zzzz = OpVariable %_ptr_Function_v4half Function %188 + %16 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %17 = OpLoad %v3half %16 + OpStore %v %17 + %22 = OpAccessChain %_ptr_Uniform_half %U %uint_0 %uint_0 %uint_0 + %23 = OpLoad %half %22 + OpStore %x %23 + %28 = OpAccessChain %_ptr_Uniform_half %U %uint_0 %uint_0 %uint_1 + %29 = OpLoad %half %28 + OpStore %y %29 + %32 = OpAccessChain %_ptr_Uniform_half %U %uint_0 %uint_0 %uint_2 + %33 = OpLoad %half %32 + OpStore %z %33 + %35 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %37 = OpLoad %v3half %35 + %38 = OpVectorShuffle %v2half %37 %37 0 0 + OpStore %xx %38 + %42 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %43 = OpLoad %v3half %42 + %44 = OpVectorShuffle %v2half %43 %43 0 1 + OpStore %xy %44 + %46 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %47 = OpLoad %v3half %46 + %48 = OpVectorShuffle %v2half %47 %47 0 2 + OpStore %xz %48 + %50 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %51 = OpLoad %v3half %50 + %52 = OpVectorShuffle %v2half %51 %51 1 0 + OpStore %yx %52 + %54 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %55 = OpLoad %v3half %54 + %56 = OpVectorShuffle %v2half %55 %55 1 1 + OpStore %yy %56 + %58 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %59 = OpLoad %v3half %58 + %60 = OpVectorShuffle %v2half %59 %59 1 2 + OpStore %yz %60 + %62 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %63 = OpLoad %v3half %62 + %64 = OpVectorShuffle %v2half %63 %63 2 0 + OpStore %zx %64 + %66 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %67 = OpLoad %v3half %66 + %68 = OpVectorShuffle %v2half %67 %67 2 1 + OpStore %zy %68 + %70 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %71 = OpLoad %v3half %70 + %72 = OpVectorShuffle %v2half %71 %71 2 2 + OpStore %zz %72 + %74 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %75 = OpLoad %v3half %74 + %76 = OpVectorShuffle %v3half %75 %75 0 0 0 + OpStore %xxx %76 + %78 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %79 = OpLoad %v3half %78 + %80 = OpVectorShuffle %v3half %79 %79 0 0 1 + OpStore %xxy %80 + %82 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %83 = OpLoad %v3half %82 + %84 = OpVectorShuffle %v3half %83 %83 0 0 2 + OpStore %xxz %84 + %86 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %87 = OpLoad %v3half %86 + %88 = OpVectorShuffle %v3half %87 %87 0 1 0 + OpStore %xyx %88 + %90 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %91 = OpLoad %v3half %90 + %92 = OpVectorShuffle %v3half %91 %91 0 1 1 + OpStore %xyy %92 + %94 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %95 = OpLoad %v3half %94 + %96 = OpVectorShuffle %v3half %95 %95 0 1 2 + OpStore %xyz %96 + %98 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %99 = OpLoad %v3half %98 + %100 = OpVectorShuffle %v3half %99 %99 0 2 0 + OpStore %xzx %100 + %102 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %103 = OpLoad %v3half %102 + %104 = OpVectorShuffle %v3half %103 %103 0 2 1 + OpStore %xzy %104 + %106 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %107 = OpLoad %v3half %106 + %108 = OpVectorShuffle %v3half %107 %107 0 2 2 + OpStore %xzz %108 + %110 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %111 = OpLoad %v3half %110 + %112 = OpVectorShuffle %v3half %111 %111 1 0 0 + OpStore %yxx %112 + %114 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %115 = OpLoad %v3half %114 + %116 = OpVectorShuffle %v3half %115 %115 1 0 1 + OpStore %yxy %116 + %118 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %119 = OpLoad %v3half %118 + %120 = OpVectorShuffle %v3half %119 %119 1 0 2 + OpStore %yxz %120 + %122 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %123 = OpLoad %v3half %122 + %124 = OpVectorShuffle %v3half %123 %123 1 1 0 + OpStore %yyx %124 + %126 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %127 = OpLoad %v3half %126 + %128 = OpVectorShuffle %v3half %127 %127 1 1 1 + OpStore %yyy %128 + %130 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %131 = OpLoad %v3half %130 + %132 = OpVectorShuffle %v3half %131 %131 1 1 2 + OpStore %yyz %132 + %134 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %135 = OpLoad %v3half %134 + %136 = OpVectorShuffle %v3half %135 %135 1 2 0 + OpStore %yzx %136 + %138 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %139 = OpLoad %v3half %138 + %140 = OpVectorShuffle %v3half %139 %139 1 2 1 + OpStore %yzy %140 + %142 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %143 = OpLoad %v3half %142 + %144 = OpVectorShuffle %v3half %143 %143 1 2 2 + OpStore %yzz %144 + %146 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %147 = OpLoad %v3half %146 + %148 = OpVectorShuffle %v3half %147 %147 2 0 0 + OpStore %zxx %148 + %150 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %151 = OpLoad %v3half %150 + %152 = OpVectorShuffle %v3half %151 %151 2 0 1 + OpStore %zxy %152 + %154 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %155 = OpLoad %v3half %154 + %156 = OpVectorShuffle %v3half %155 %155 2 0 2 + OpStore %zxz %156 + %158 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %159 = OpLoad %v3half %158 + %160 = OpVectorShuffle %v3half %159 %159 2 1 0 + OpStore %zyx %160 + %162 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %163 = OpLoad %v3half %162 + %164 = OpVectorShuffle %v3half %163 %163 2 1 1 + OpStore %zyy %164 + %166 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %167 = OpLoad %v3half %166 + %168 = OpVectorShuffle %v3half %167 %167 2 1 2 + OpStore %zyz %168 + %170 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %171 = OpLoad %v3half %170 + %172 = OpVectorShuffle %v3half %171 %171 2 2 0 + OpStore %zzx %172 + %174 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %175 = OpLoad %v3half %174 + %176 = OpVectorShuffle %v3half %175 %175 2 2 1 + OpStore %zzy %176 + %178 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %179 = OpLoad %v3half %178 + %180 = OpVectorShuffle %v3half %179 %179 2 2 2 + OpStore %zzz %180 + %182 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %184 = OpLoad %v3half %182 + %185 = OpVectorShuffle %v4half %184 %184 0 0 0 0 + OpStore %xxxx %185 + %189 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %190 = OpLoad %v3half %189 + %191 = OpVectorShuffle %v4half %190 %190 0 0 0 1 + OpStore %xxxy %191 + %193 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %194 = OpLoad %v3half %193 + %195 = OpVectorShuffle %v4half %194 %194 0 0 0 2 + OpStore %xxxz %195 + %197 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %198 = OpLoad %v3half %197 + %199 = OpVectorShuffle %v4half %198 %198 0 0 1 0 + OpStore %xxyx %199 + %201 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %202 = OpLoad %v3half %201 + %203 = OpVectorShuffle %v4half %202 %202 0 0 1 1 + OpStore %xxyy %203 + %205 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %206 = OpLoad %v3half %205 + %207 = OpVectorShuffle %v4half %206 %206 0 0 1 2 + OpStore %xxyz %207 + %209 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %210 = OpLoad %v3half %209 + %211 = OpVectorShuffle %v4half %210 %210 0 0 2 0 + OpStore %xxzx %211 + %213 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %214 = OpLoad %v3half %213 + %215 = OpVectorShuffle %v4half %214 %214 0 0 2 1 + OpStore %xxzy %215 + %217 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %218 = OpLoad %v3half %217 + %219 = OpVectorShuffle %v4half %218 %218 0 0 2 2 + OpStore %xxzz %219 + %221 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %222 = OpLoad %v3half %221 + %223 = OpVectorShuffle %v4half %222 %222 0 1 0 0 + OpStore %xyxx %223 + %225 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %226 = OpLoad %v3half %225 + %227 = OpVectorShuffle %v4half %226 %226 0 1 0 1 + OpStore %xyxy %227 + %229 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %230 = OpLoad %v3half %229 + %231 = OpVectorShuffle %v4half %230 %230 0 1 0 2 + OpStore %xyxz %231 + %233 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %234 = OpLoad %v3half %233 + %235 = OpVectorShuffle %v4half %234 %234 0 1 1 0 + OpStore %xyyx %235 + %237 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %238 = OpLoad %v3half %237 + %239 = OpVectorShuffle %v4half %238 %238 0 1 1 1 + OpStore %xyyy %239 + %241 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %242 = OpLoad %v3half %241 + %243 = OpVectorShuffle %v4half %242 %242 0 1 1 2 + OpStore %xyyz %243 + %245 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %246 = OpLoad %v3half %245 + %247 = OpVectorShuffle %v4half %246 %246 0 1 2 0 + OpStore %xyzx %247 + %249 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %250 = OpLoad %v3half %249 + %251 = OpVectorShuffle %v4half %250 %250 0 1 2 1 + OpStore %xyzy %251 + %253 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %254 = OpLoad %v3half %253 + %255 = OpVectorShuffle %v4half %254 %254 0 1 2 2 + OpStore %xyzz %255 + %257 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %258 = OpLoad %v3half %257 + %259 = OpVectorShuffle %v4half %258 %258 0 2 0 0 + OpStore %xzxx %259 + %261 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %262 = OpLoad %v3half %261 + %263 = OpVectorShuffle %v4half %262 %262 0 2 0 1 + OpStore %xzxy %263 + %265 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %266 = OpLoad %v3half %265 + %267 = OpVectorShuffle %v4half %266 %266 0 2 0 2 + OpStore %xzxz %267 + %269 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %270 = OpLoad %v3half %269 + %271 = OpVectorShuffle %v4half %270 %270 0 2 1 0 + OpStore %xzyx %271 + %273 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %274 = OpLoad %v3half %273 + %275 = OpVectorShuffle %v4half %274 %274 0 2 1 1 + OpStore %xzyy %275 + %277 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %278 = OpLoad %v3half %277 + %279 = OpVectorShuffle %v4half %278 %278 0 2 1 2 + OpStore %xzyz %279 + %281 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %282 = OpLoad %v3half %281 + %283 = OpVectorShuffle %v4half %282 %282 0 2 2 0 + OpStore %xzzx %283 + %285 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %286 = OpLoad %v3half %285 + %287 = OpVectorShuffle %v4half %286 %286 0 2 2 1 + OpStore %xzzy %287 + %289 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %290 = OpLoad %v3half %289 + %291 = OpVectorShuffle %v4half %290 %290 0 2 2 2 + OpStore %xzzz %291 + %293 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %294 = OpLoad %v3half %293 + %295 = OpVectorShuffle %v4half %294 %294 1 0 0 0 + OpStore %yxxx %295 + %297 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %298 = OpLoad %v3half %297 + %299 = OpVectorShuffle %v4half %298 %298 1 0 0 1 + OpStore %yxxy %299 + %301 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %302 = OpLoad %v3half %301 + %303 = OpVectorShuffle %v4half %302 %302 1 0 0 2 + OpStore %yxxz %303 + %305 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %306 = OpLoad %v3half %305 + %307 = OpVectorShuffle %v4half %306 %306 1 0 1 0 + OpStore %yxyx %307 + %309 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %310 = OpLoad %v3half %309 + %311 = OpVectorShuffle %v4half %310 %310 1 0 1 1 + OpStore %yxyy %311 + %313 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %314 = OpLoad %v3half %313 + %315 = OpVectorShuffle %v4half %314 %314 1 0 1 2 + OpStore %yxyz %315 + %317 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %318 = OpLoad %v3half %317 + %319 = OpVectorShuffle %v4half %318 %318 1 0 2 0 + OpStore %yxzx %319 + %321 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %322 = OpLoad %v3half %321 + %323 = OpVectorShuffle %v4half %322 %322 1 0 2 1 + OpStore %yxzy %323 + %325 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %326 = OpLoad %v3half %325 + %327 = OpVectorShuffle %v4half %326 %326 1 0 2 2 + OpStore %yxzz %327 + %329 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %330 = OpLoad %v3half %329 + %331 = OpVectorShuffle %v4half %330 %330 1 1 0 0 + OpStore %yyxx %331 + %333 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %334 = OpLoad %v3half %333 + %335 = OpVectorShuffle %v4half %334 %334 1 1 0 1 + OpStore %yyxy %335 + %337 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %338 = OpLoad %v3half %337 + %339 = OpVectorShuffle %v4half %338 %338 1 1 0 2 + OpStore %yyxz %339 + %341 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %342 = OpLoad %v3half %341 + %343 = OpVectorShuffle %v4half %342 %342 1 1 1 0 + OpStore %yyyx %343 + %345 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %346 = OpLoad %v3half %345 + %347 = OpVectorShuffle %v4half %346 %346 1 1 1 1 + OpStore %yyyy %347 + %349 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %350 = OpLoad %v3half %349 + %351 = OpVectorShuffle %v4half %350 %350 1 1 1 2 + OpStore %yyyz %351 + %353 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %354 = OpLoad %v3half %353 + %355 = OpVectorShuffle %v4half %354 %354 1 1 2 0 + OpStore %yyzx %355 + %357 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %358 = OpLoad %v3half %357 + %359 = OpVectorShuffle %v4half %358 %358 1 1 2 1 + OpStore %yyzy %359 + %361 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %362 = OpLoad %v3half %361 + %363 = OpVectorShuffle %v4half %362 %362 1 1 2 2 + OpStore %yyzz %363 + %365 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %366 = OpLoad %v3half %365 + %367 = OpVectorShuffle %v4half %366 %366 1 2 0 0 + OpStore %yzxx %367 + %369 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %370 = OpLoad %v3half %369 + %371 = OpVectorShuffle %v4half %370 %370 1 2 0 1 + OpStore %yzxy %371 + %373 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %374 = OpLoad %v3half %373 + %375 = OpVectorShuffle %v4half %374 %374 1 2 0 2 + OpStore %yzxz %375 + %377 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %378 = OpLoad %v3half %377 + %379 = OpVectorShuffle %v4half %378 %378 1 2 1 0 + OpStore %yzyx %379 + %381 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %382 = OpLoad %v3half %381 + %383 = OpVectorShuffle %v4half %382 %382 1 2 1 1 + OpStore %yzyy %383 + %385 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %386 = OpLoad %v3half %385 + %387 = OpVectorShuffle %v4half %386 %386 1 2 1 2 + OpStore %yzyz %387 + %389 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %390 = OpLoad %v3half %389 + %391 = OpVectorShuffle %v4half %390 %390 1 2 2 0 + OpStore %yzzx %391 + %393 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %394 = OpLoad %v3half %393 + %395 = OpVectorShuffle %v4half %394 %394 1 2 2 1 + OpStore %yzzy %395 + %397 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %398 = OpLoad %v3half %397 + %399 = OpVectorShuffle %v4half %398 %398 1 2 2 2 + OpStore %yzzz %399 + %401 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %402 = OpLoad %v3half %401 + %403 = OpVectorShuffle %v4half %402 %402 2 0 0 0 + OpStore %zxxx %403 + %405 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %406 = OpLoad %v3half %405 + %407 = OpVectorShuffle %v4half %406 %406 2 0 0 1 + OpStore %zxxy %407 + %409 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %410 = OpLoad %v3half %409 + %411 = OpVectorShuffle %v4half %410 %410 2 0 0 2 + OpStore %zxxz %411 + %413 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %414 = OpLoad %v3half %413 + %415 = OpVectorShuffle %v4half %414 %414 2 0 1 0 + OpStore %zxyx %415 + %417 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %418 = OpLoad %v3half %417 + %419 = OpVectorShuffle %v4half %418 %418 2 0 1 1 + OpStore %zxyy %419 + %421 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %422 = OpLoad %v3half %421 + %423 = OpVectorShuffle %v4half %422 %422 2 0 1 2 + OpStore %zxyz %423 + %425 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %426 = OpLoad %v3half %425 + %427 = OpVectorShuffle %v4half %426 %426 2 0 2 0 + OpStore %zxzx %427 + %429 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %430 = OpLoad %v3half %429 + %431 = OpVectorShuffle %v4half %430 %430 2 0 2 1 + OpStore %zxzy %431 + %433 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %434 = OpLoad %v3half %433 + %435 = OpVectorShuffle %v4half %434 %434 2 0 2 2 + OpStore %zxzz %435 + %437 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %438 = OpLoad %v3half %437 + %439 = OpVectorShuffle %v4half %438 %438 2 1 0 0 + OpStore %zyxx %439 + %441 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %442 = OpLoad %v3half %441 + %443 = OpVectorShuffle %v4half %442 %442 2 1 0 1 + OpStore %zyxy %443 + %445 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %446 = OpLoad %v3half %445 + %447 = OpVectorShuffle %v4half %446 %446 2 1 0 2 + OpStore %zyxz %447 + %449 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %450 = OpLoad %v3half %449 + %451 = OpVectorShuffle %v4half %450 %450 2 1 1 0 + OpStore %zyyx %451 + %453 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %454 = OpLoad %v3half %453 + %455 = OpVectorShuffle %v4half %454 %454 2 1 1 1 + OpStore %zyyy %455 + %457 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %458 = OpLoad %v3half %457 + %459 = OpVectorShuffle %v4half %458 %458 2 1 1 2 + OpStore %zyyz %459 + %461 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %462 = OpLoad %v3half %461 + %463 = OpVectorShuffle %v4half %462 %462 2 1 2 0 + OpStore %zyzx %463 + %465 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %466 = OpLoad %v3half %465 + %467 = OpVectorShuffle %v4half %466 %466 2 1 2 1 + OpStore %zyzy %467 + %469 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %470 = OpLoad %v3half %469 + %471 = OpVectorShuffle %v4half %470 %470 2 1 2 2 + OpStore %zyzz %471 + %473 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %474 = OpLoad %v3half %473 + %475 = OpVectorShuffle %v4half %474 %474 2 2 0 0 + OpStore %zzxx %475 + %477 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %478 = OpLoad %v3half %477 + %479 = OpVectorShuffle %v4half %478 %478 2 2 0 1 + OpStore %zzxy %479 + %481 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %482 = OpLoad %v3half %481 + %483 = OpVectorShuffle %v4half %482 %482 2 2 0 2 + OpStore %zzxz %483 + %485 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %486 = OpLoad %v3half %485 + %487 = OpVectorShuffle %v4half %486 %486 2 2 1 0 + OpStore %zzyx %487 + %489 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %490 = OpLoad %v3half %489 + %491 = OpVectorShuffle %v4half %490 %490 2 2 1 1 + OpStore %zzyy %491 + %493 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %494 = OpLoad %v3half %493 + %495 = OpVectorShuffle %v4half %494 %494 2 2 1 2 + OpStore %zzyz %495 + %497 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %498 = OpLoad %v3half %497 + %499 = OpVectorShuffle %v4half %498 %498 2 2 2 0 + OpStore %zzzx %499 + %501 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %502 = OpLoad %v3half %501 + %503 = OpVectorShuffle %v4half %502 %502 2 2 2 1 + OpStore %zzzy %503 + %505 = OpAccessChain %_ptr_Uniform_v3half %U %uint_0 %uint_0 + %506 = OpLoad %v3half %505 + %507 = OpVectorShuffle %v4half %506 %506 2 2 2 2 + OpStore %zzzz %507 + OpReturn + OpFunctionEnd diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.wgsl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.wgsl index 6c8063b2f1..ada9f1fc6f 100644 --- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.wgsl +++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.wgsl @@ -1,18 +1,131 @@ -SKIP: FAILED +enable f16; -swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet - v: vec3, - ^^^^^^^^^ - -swizzle/read/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + v : vec3, +} -swizzle/read/packed_vec3/f16.wgsl:6:36 note: see declaration of variable @group(0) @binding(0) var U : S; - ^ +fn f() { + var v = U.v; + var x = U.v.x; + var y = U.v.y; + var z = U.v.z; + var xx = U.v.xx; + var xy = U.v.xy; + var xz = U.v.xz; + var yx = U.v.yx; + var yy = U.v.yy; + var yz = U.v.yz; + var zx = U.v.zx; + var zy = U.v.zy; + var zz = U.v.zz; + var xxx = U.v.xxx; + var xxy = U.v.xxy; + var xxz = U.v.xxz; + var xyx = U.v.xyx; + var xyy = U.v.xyy; + var xyz = U.v.xyz; + var xzx = U.v.xzx; + var xzy = U.v.xzy; + var xzz = U.v.xzz; + var yxx = U.v.yxx; + var yxy = U.v.yxy; + var yxz = U.v.yxz; + var yyx = U.v.yyx; + var yyy = U.v.yyy; + var yyz = U.v.yyz; + var yzx = U.v.yzx; + var yzy = U.v.yzy; + var yzz = U.v.yzz; + var zxx = U.v.zxx; + var zxy = U.v.zxy; + var zxz = U.v.zxz; + var zyx = U.v.zyx; + var zyy = U.v.zyy; + var zyz = U.v.zyz; + var zzx = U.v.zzx; + var zzy = U.v.zzy; + var zzz = U.v.zzz; + var xxxx = U.v.xxxx; + var xxxy = U.v.xxxy; + var xxxz = U.v.xxxz; + var xxyx = U.v.xxyx; + var xxyy = U.v.xxyy; + var xxyz = U.v.xxyz; + var xxzx = U.v.xxzx; + var xxzy = U.v.xxzy; + var xxzz = U.v.xxzz; + var xyxx = U.v.xyxx; + var xyxy = U.v.xyxy; + var xyxz = U.v.xyxz; + var xyyx = U.v.xyyx; + var xyyy = U.v.xyyy; + var xyyz = U.v.xyyz; + var xyzx = U.v.xyzx; + var xyzy = U.v.xyzy; + var xyzz = U.v.xyzz; + var xzxx = U.v.xzxx; + var xzxy = U.v.xzxy; + var xzxz = U.v.xzxz; + var xzyx = U.v.xzyx; + var xzyy = U.v.xzyy; + var xzyz = U.v.xzyz; + var xzzx = U.v.xzzx; + var xzzy = U.v.xzzy; + var xzzz = U.v.xzzz; + var yxxx = U.v.yxxx; + var yxxy = U.v.yxxy; + var yxxz = U.v.yxxz; + var yxyx = U.v.yxyx; + var yxyy = U.v.yxyy; + var yxyz = U.v.yxyz; + var yxzx = U.v.yxzx; + var yxzy = U.v.yxzy; + var yxzz = U.v.yxzz; + var yyxx = U.v.yyxx; + var yyxy = U.v.yyxy; + var yyxz = U.v.yyxz; + var yyyx = U.v.yyyx; + var yyyy = U.v.yyyy; + var yyyz = U.v.yyyz; + var yyzx = U.v.yyzx; + var yyzy = U.v.yyzy; + var yyzz = U.v.yyzz; + var yzxx = U.v.yzxx; + var yzxy = U.v.yzxy; + var yzxz = U.v.yzxz; + var yzyx = U.v.yzyx; + var yzyy = U.v.yzyy; + var yzyz = U.v.yzyz; + var yzzx = U.v.yzzx; + var yzzy = U.v.yzzy; + var yzzz = U.v.yzzz; + var zxxx = U.v.zxxx; + var zxxy = U.v.zxxy; + var zxxz = U.v.zxxz; + var zxyx = U.v.zxyx; + var zxyy = U.v.zxyy; + var zxyz = U.v.zxyz; + var zxzx = U.v.zxzx; + var zxzy = U.v.zxzy; + var zxzz = U.v.zxzz; + var zyxx = U.v.zyxx; + var zyxy = U.v.zyxy; + var zyxz = U.v.zyxz; + var zyyx = U.v.zyyx; + var zyyy = U.v.zyyy; + var zyyz = U.v.zyyz; + var zyzx = U.v.zyzx; + var zyzy = U.v.zyzy; + var zyzz = U.v.zyzz; + var zzxx = U.v.zzxx; + var zzxy = U.v.zzxy; + var zzxz = U.v.zzxz; + var zzyx = U.v.zzyx; + var zzyy = U.v.zzyy; + var zzyz = U.v.zzyz; + var zzzx = U.v.zzzx; + var zzzy = U.v.zzzy; + var zzzz = U.v.zzzz; +} diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.dxc.hlsl index 4053a55bde..61cc5359ce 100644 --- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.dxc.hlsl @@ -1,18 +1,13 @@ -SKIP: FAILED +[numthreads(1, 1, 1)] +void unused_entry_point() { + return; +} -swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet - v: vec3, - ^^^^^^^^^ - -swizzle/write/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -swizzle/write/packed_vec3/f16.wgsl:6:48 note: see declaration of variable -@group(0) @binding(0) var U : S; - ^ +RWByteAddressBuffer U : register(u0, space0); +void f() { + U.Store >(0u, vector(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h))); + U.Store(0u, float16_t(1.0h)); + U.Store(2u, float16_t(2.0h)); + U.Store(4u, float16_t(3.0h)); +} diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.glsl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.glsl index cb935a3be7..a4cf8e2a47 100644 --- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.glsl +++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.glsl @@ -1,18 +1,22 @@ -SKIP: FAILED +#version 310 es +#extension GL_AMD_gpu_shader_half_float : require -expressions/swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet - v: vec3, - ^^^^^^^^^ - -expressions/swizzle/write/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void unused_entry_point() { + return; +} struct S { -^^^^^^ + f16vec3 v; +}; -expressions/swizzle/write/packed_vec3/f16.wgsl:6:48 note: see declaration of variable -@group(0) @binding(0) var U : S; - ^ +layout(binding = 0, std430) buffer U_block_ssbo { + S inner; +} U; + +void f() { + U.inner.v = f16vec3(1.0hf, 2.0hf, 3.0hf); + U.inner.v.x = 1.0hf; + U.inner.v.y = 2.0hf; + U.inner.v.z = 3.0hf; +} diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.msl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.msl index 4053a55bde..92500cc64b 100644 --- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.msl +++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.msl @@ -1,18 +1,28 @@ -SKIP: FAILED +#include -swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet - v: vec3, - ^^^^^^^^^ +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; -swizzle/write/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + /* 0x0000 */ packed_half3 v; + /* 0x0006 */ tint_array tint_pad; +}; -swizzle/write/packed_vec3/f16.wgsl:6:48 note: see declaration of variable -@group(0) @binding(0) var U : S; - ^ +void f(device S* const tint_symbol) { + (*(tint_symbol)).v = half3(1.0h, 2.0h, 3.0h); + (*(tint_symbol)).v[0] = 1.0h; + (*(tint_symbol)).v[1] = 2.0h; + (*(tint_symbol)).v[2] = 3.0h; +} diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.spvasm b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.spvasm index 4053a55bde..0efe146a09 100644 --- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.spvasm +++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.spvasm @@ -1,18 +1,59 @@ -SKIP: FAILED - -swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet - v: vec3, - ^^^^^^^^^ - -swizzle/write/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; -struct S { -^^^^^^ - -swizzle/write/packed_vec3/f16.wgsl:6:48 note: see declaration of variable -@group(0) @binding(0) var U : S; - ^ - +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 27 +; Schema: 0 + OpCapability Shader + OpCapability Float16 + OpCapability UniformAndStorageBuffer16BitAccess + OpCapability StorageBuffer16BitAccess + OpCapability StorageInputOutput16 + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %unused_entry_point "unused_entry_point" + OpExecutionMode %unused_entry_point LocalSize 1 1 1 + OpName %U_block "U_block" + OpMemberName %U_block 0 "inner" + OpName %S "S" + OpMemberName %S 0 "v" + OpName %U "U" + OpName %unused_entry_point "unused_entry_point" + OpName %f "f" + OpDecorate %U_block Block + OpMemberDecorate %U_block 0 Offset 0 + OpMemberDecorate %S 0 Offset 0 + OpDecorate %U DescriptorSet 0 + OpDecorate %U Binding 0 + %half = OpTypeFloat 16 + %v3half = OpTypeVector %half 3 + %S = OpTypeStruct %v3half + %U_block = OpTypeStruct %S +%_ptr_StorageBuffer_U_block = OpTypePointer StorageBuffer %U_block + %U = OpVariable %_ptr_StorageBuffer_U_block StorageBuffer + %void = OpTypeVoid + %7 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 +%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half +%half_0x1p_0 = OpConstant %half 0x1p+0 +%half_0x1p_1 = OpConstant %half 0x1p+1 +%half_0x1_8p_1 = OpConstant %half 0x1.8p+1 + %20 = OpConstantComposite %v3half %half_0x1p_0 %half_0x1p_1 %half_0x1_8p_1 +%_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%unused_entry_point = OpFunction %void None %7 + %10 = OpLabel + OpReturn + OpFunctionEnd + %f = OpFunction %void None %7 + %12 = OpLabel + %16 = OpAccessChain %_ptr_StorageBuffer_v3half %U %uint_0 %uint_0 + OpStore %16 %20 + %22 = OpAccessChain %_ptr_StorageBuffer_half %U %uint_0 %uint_0 %uint_0 + OpStore %22 %half_0x1p_0 + %24 = OpAccessChain %_ptr_StorageBuffer_half %U %uint_0 %uint_0 %uint_1 + OpStore %24 %half_0x1p_1 + %26 = OpAccessChain %_ptr_StorageBuffer_half %U %uint_0 %uint_0 %uint_2 + OpStore %26 %half_0x1_8p_1 + OpReturn + OpFunctionEnd diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.wgsl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.wgsl index 4053a55bde..daa08f6459 100644 --- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.wgsl +++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.wgsl @@ -1,18 +1,14 @@ -SKIP: FAILED +enable f16; -swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet - v: vec3, - ^^^^^^^^^ - -swizzle/write/packed_vec3/f16.wgsl:2:1 note: see layout of struct: -/* align(8) size(8) */ struct S { -/* offset(0) align(8) size(6) */ v : vec3; -/* offset(6) align(1) size(2) */ // -- implicit struct size padding --; -/* */ }; struct S { -^^^^^^ + v : vec3, +} -swizzle/write/packed_vec3/f16.wgsl:6:48 note: see declaration of variable @group(0) @binding(0) var U : S; - ^ +fn f() { + U.v = vec3(1.0h, 2.0h, 3.0h); + U.v.x = 1.0h; + U.v.y = 2.0h; + U.v.z = 3.0h; +}