From ab9b5f3aa5996054993f01914fe5a6833a2c8e38 Mon Sep 17 00:00:00 2001 From: Zhaoming Jiang Date: Thu, 24 Nov 2022 05:25:35 +0000 Subject: [PATCH] Tint: Implement f16 in uniform and storage address space This CL implements f16 in uniform and storage address space, allowing using f16 types in uniform and storage buffers on all backends. Tint uint tests and Dawn E2E tests are added to validate the f16 types work as expected. Bug: tint:1473, tint:1502 Change-Id: I15e3de1033d3727f2ea33f4657f682c5f13c2153 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/106320 Kokoro: Kokoro Commit-Queue: Zhaoming Jiang Reviewed-by: Ben Clayton --- .../ComputeLayoutMemoryBufferTests.cpp | 395 +- src/tint/BUILD.gn | 2 + src/tint/CMakeLists.txt | 2 + .../address_space_layout_validation_test.cc | 23 + .../resolver/address_space_validation_test.cc | 358 +- src/tint/resolver/validator.cc | 12 +- src/tint/transform/decompose_memory_access.cc | 28 + src/tint/transform/decompose_memory_access.h | 4 + .../transform/decompose_memory_access_test.cc | 3492 ++++++++++------ src/tint/transform/std140.cc | 9 +- src/tint/transform/std140.h | 11 +- src/tint/transform/std140_exhaustive_test.cc | 18 + src/tint/transform/std140_f16_test.cc | 3596 +++++++++++++++++ src/tint/transform/std140_f32_test.cc | 3359 +++++++++++++++ src/tint/transform/std140_test.cc | 3354 +-------------- src/tint/writer/hlsl/generator_impl.cc | 294 +- .../generator_impl_member_accessor_test.cc | 1527 ++++++- src/tint/writer/spirv/builder.cc | 6 +- src/tint/writer/spirv/builder_type_test.cc | 182 +- .../arrayLength/8421b9.wgsl.expected.dxc.hlsl | 44 +- .../arrayLength/8421b9.wgsl.expected.fxc.hlsl | 44 +- .../arrayLength/8421b9.wgsl.expected.glsl | 73 +- .../arrayLength/8421b9.wgsl.expected.msl | 61 +- .../arrayLength/8421b9.wgsl.expected.spvasm | 101 +- .../arrayLength/8421b9.wgsl.expected.wgsl | 34 +- .../arrayLength/cbd6b5.wgsl.expected.dxc.hlsl | 44 +- .../arrayLength/cbd6b5.wgsl.expected.fxc.hlsl | 44 +- .../arrayLength/cbd6b5.wgsl.expected.glsl | 73 +- .../arrayLength/cbd6b5.wgsl.expected.msl | 61 +- .../arrayLength/cbd6b5.wgsl.expected.spvasm | 100 +- .../arrayLength/cbd6b5.wgsl.expected.wgsl | 34 +- .../arrayLength/8421b9.wgsl.expected.dxc.hlsl | 44 +- .../arrayLength/8421b9.wgsl.expected.fxc.hlsl | 44 +- .../var/arrayLength/8421b9.wgsl.expected.glsl | 73 +- .../var/arrayLength/8421b9.wgsl.expected.msl | 61 +- .../arrayLength/8421b9.wgsl.expected.spvasm | 101 +- .../var/arrayLength/8421b9.wgsl.expected.wgsl | 34 +- .../arrayLength/cbd6b5.wgsl.expected.dxc.hlsl | 44 +- .../arrayLength/cbd6b5.wgsl.expected.fxc.hlsl | 44 +- .../var/arrayLength/cbd6b5.wgsl.expected.glsl | 73 +- .../var/arrayLength/cbd6b5.wgsl.expected.msl | 61 +- .../arrayLength/cbd6b5.wgsl.expected.spvasm | 100 +- .../var/arrayLength/cbd6b5.wgsl.expected.wgsl | 34 +- .../mat3x2-vec3/f16.wgsl.expected.dxc.hlsl | 37 +- .../mul/mat3x2-vec3/f16.wgsl.expected.glsl | 50 +- .../mul/mat3x2-vec3/f16.wgsl.expected.msl | 38 +- .../mul/mat3x2-vec3/f16.wgsl.expected.spvasm | 91 +- .../mul/mat3x2-vec3/f16.wgsl.expected.wgsl | 25 +- .../mat3x3-vec3/f16.wgsl.expected.dxc.hlsl | 45 +- .../mul/mat3x3-vec3/f16.wgsl.expected.glsl | 43 +- .../mul/mat3x3-vec3/f16.wgsl.expected.msl | 36 +- .../mul/mat3x3-vec3/f16.wgsl.expected.spvasm | 88 +- .../mul/mat3x3-vec3/f16.wgsl.expected.wgsl | 24 +- .../vec3-mat3x3/f16.wgsl.expected.dxc.hlsl | 45 +- .../mul/vec3-mat3x3/f16.wgsl.expected.glsl | 43 +- .../mul/vec3-mat3x3/f16.wgsl.expected.msl | 36 +- .../mul/vec3-mat3x3/f16.wgsl.expected.spvasm | 88 +- .../mul/vec3-mat3x3/f16.wgsl.expected.wgsl | 24 +- .../vec3-mat4x3/f16.wgsl.expected.dxc.hlsl | 50 +- .../mul/vec3-mat4x3/f16.wgsl.expected.glsl | 48 +- .../mul/vec3-mat4x3/f16.wgsl.expected.msl | 36 +- .../mul/vec3-mat4x3/f16.wgsl.expected.spvasm | 94 +- .../mul/vec3-mat4x3/f16.wgsl.expected.wgsl | 24 +- .../packed_vec3/f16.wgsl.expected.dxc.hlsl | 500 ++- .../read/packed_vec3/f16.wgsl.expected.glsl | 151 +- .../read/packed_vec3/f16.wgsl.expected.msl | 153 +- .../read/packed_vec3/f16.wgsl.expected.spvasm | 798 +++- .../read/packed_vec3/f16.wgsl.expected.wgsl | 139 +- .../packed_vec3/f16.wgsl.expected.dxc.hlsl | 27 +- .../write/packed_vec3/f16.wgsl.expected.glsl | 32 +- .../write/packed_vec3/f16.wgsl.expected.msl | 36 +- .../packed_vec3/f16.wgsl.expected.spvasm | 77 +- .../write/packed_vec3/f16.wgsl.expected.wgsl | 22 +- 73 files changed, 15168 insertions(+), 5830 deletions(-) create mode 100644 src/tint/transform/std140_f16_test.cc create mode 100644 src/tint/transform/std140_f32_test.cc 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; +}