mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-10 05:57:51 +00:00
reader/spirv: Decompose arrays with strides
Transform any SPIR-V that has an array with a custom stride:
@stride(S) array<T, N>
into:
struct strided_arr {
@size(S) er : T;
};
array<strided_arr, N>
Also remove any @stride decorations that match the default array stride.
Bug: tint:1394
Bug: tint:1381
Change-Id: I8be8f3a76c5335fdb2bc5183388366091dbc7642
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/78781
Reviewed-by: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Tint LUCI CQ
parent
de857e1c58
commit
009d129103
71
test/array/strides.spvasm
Normal file
71
test/array/strides.spvasm
Normal file
@@ -0,0 +1,71 @@
|
||||
; type ARR_A = @stride(8) array<f32, 2>;
|
||||
; type ARR_B = @stride(128) array<@stride(16) array<ARR_A, 4>, 3>;
|
||||
; struct S {
|
||||
; a : ARR_B;
|
||||
; };
|
||||
; @group(0) @binding(0) var<storage, read_write> s : S;
|
||||
;
|
||||
; @stage(compute) @workgroup_size(1)
|
||||
; fn f() {
|
||||
; let a : ARR_B = s.a;
|
||||
; let b : array<@stride(8) array<f32, 2>, 3> = s.a[3];
|
||||
; let c = s.a[3][2];
|
||||
; let d = s.a[3][2][1];
|
||||
; s.a = ARR_B();
|
||||
; s.a[3][2][1] = 5.0;
|
||||
; }
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %f "f"
|
||||
OpExecutionMode %f LocalSize 1 1 1
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "a"
|
||||
OpName %s "s"
|
||||
OpName %f "f"
|
||||
OpDecorate %S Block
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpDecorate %_arr_float_uint_2 ArrayStride 8
|
||||
OpDecorate %_arr__arr_float_uint_2_uint_3 ArrayStride 16
|
||||
OpDecorate %_arr__arr__arr_float_uint_2_uint_3_uint_4 ArrayStride 128
|
||||
OpDecorate %s DescriptorSet 0
|
||||
OpDecorate %s Binding 0
|
||||
%float = OpTypeFloat 32
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr_float_uint_2 = OpTypeArray %float %uint_2
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr__arr_float_uint_2_uint_3 = OpTypeArray %_arr_float_uint_2 %uint_3
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr__arr__arr_float_uint_2_uint_3_uint_4 = OpTypeArray %_arr__arr_float_uint_2_uint_3 %uint_4
|
||||
%S = OpTypeStruct %_arr__arr__arr_float_uint_2_uint_3_uint_4
|
||||
%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
|
||||
%s = OpVariable %_ptr_StorageBuffer_S StorageBuffer
|
||||
%void = OpTypeVoid
|
||||
%12 = OpTypeFunction %void
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_StorageBuffer__arr__arr__arr_float_uint_2_uint_3_uint_4 = OpTypePointer StorageBuffer %_arr__arr__arr_float_uint_2_uint_3_uint_4
|
||||
%int = OpTypeInt 32 1
|
||||
%int_3 = OpConstant %int 3
|
||||
%_ptr_StorageBuffer__arr__arr_float_uint_2_uint_3 = OpTypePointer StorageBuffer %_arr__arr_float_uint_2_uint_3
|
||||
%int_2 = OpConstant %int 2
|
||||
%_ptr_StorageBuffer__arr_float_uint_2 = OpTypePointer StorageBuffer %_arr_float_uint_2
|
||||
%int_1 = OpConstant %int 1
|
||||
%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
|
||||
%34 = OpConstantNull %_arr__arr__arr_float_uint_2_uint_3_uint_4
|
||||
%float_5 = OpConstant %float 5
|
||||
%f = OpFunction %void None %12
|
||||
%15 = OpLabel
|
||||
%18 = OpAccessChain %_ptr_StorageBuffer__arr__arr__arr_float_uint_2_uint_3_uint_4 %s %uint_0
|
||||
%19 = OpLoad %_arr__arr__arr_float_uint_2_uint_3_uint_4 %18
|
||||
%23 = OpAccessChain %_ptr_StorageBuffer__arr__arr_float_uint_2_uint_3 %s %uint_0 %int_3
|
||||
%24 = OpLoad %_arr__arr_float_uint_2_uint_3 %23
|
||||
%27 = OpAccessChain %_ptr_StorageBuffer__arr_float_uint_2 %s %uint_0 %int_3 %int_2
|
||||
%28 = OpLoad %_arr_float_uint_2 %27
|
||||
%31 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_3 %int_2 %int_1
|
||||
%32 = OpLoad %float %31
|
||||
%33 = OpAccessChain %_ptr_StorageBuffer__arr__arr__arr_float_uint_2_uint_3_uint_4 %s %uint_0
|
||||
OpStore %33 %34
|
||||
%35 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_3 %int_2 %int_1
|
||||
OpStore %35 %float_5
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
38
test/array/strides.spvasm.expected.glsl
Normal file
38
test/array/strides.spvasm.expected.glsl
Normal file
@@ -0,0 +1,38 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
struct strided_arr {
|
||||
float el;
|
||||
};
|
||||
|
||||
struct strided_arr_1 {
|
||||
strided_arr el[3][2];
|
||||
};
|
||||
|
||||
struct S {
|
||||
strided_arr_1 a[4];
|
||||
};
|
||||
|
||||
layout(binding = 0) buffer S_1 {
|
||||
strided_arr_1 a[4];
|
||||
} s;
|
||||
void f_1() {
|
||||
strided_arr_1 x_19[4] = s.a;
|
||||
strided_arr x_24[3][2] = s.a[3].el;
|
||||
strided_arr x_28[2] = s.a[3].el[2];
|
||||
float x_32 = s.a[3].el[2][1].el;
|
||||
strided_arr_1 tint_symbol[4] = strided_arr_1[4](strided_arr_1(strided_arr[3][2](strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)), strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)), strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)))), strided_arr_1(strided_arr[3][2](strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)), strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)), strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)))), strided_arr_1(strided_arr[3][2](strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)), strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)), strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)))), strided_arr_1(strided_arr[3][2](strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)), strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)), strided_arr[2](strided_arr(0.0f), strided_arr(0.0f)))));
|
||||
s.a = tint_symbol;
|
||||
s.a[3].el[2][1].el = 5.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
void f() {
|
||||
f_1();
|
||||
}
|
||||
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
void main() {
|
||||
f();
|
||||
return;
|
||||
}
|
||||
103
test/array/strides.spvasm.expected.hlsl
Normal file
103
test/array/strides.spvasm.expected.hlsl
Normal file
@@ -0,0 +1,103 @@
|
||||
struct strided_arr {
|
||||
float el;
|
||||
};
|
||||
struct strided_arr_1 {
|
||||
strided_arr el[3][2];
|
||||
};
|
||||
|
||||
RWByteAddressBuffer s : register(u0, space0);
|
||||
|
||||
strided_arr tint_symbol_4(RWByteAddressBuffer buffer, uint offset) {
|
||||
const strided_arr tint_symbol_12 = {asfloat(buffer.Load((offset + 0u)))};
|
||||
return tint_symbol_12;
|
||||
}
|
||||
|
||||
typedef strided_arr tint_symbol_3_ret[2];
|
||||
tint_symbol_3_ret tint_symbol_3(RWByteAddressBuffer buffer, uint offset) {
|
||||
strided_arr arr[2] = (strided_arr[2])0;
|
||||
{
|
||||
[loop] for(uint i = 0u; (i < 2u); i = (i + 1u)) {
|
||||
arr[i] = tint_symbol_4(buffer, (offset + (i * 8u)));
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
typedef strided_arr tint_symbol_2_ret[3][2];
|
||||
tint_symbol_2_ret tint_symbol_2(RWByteAddressBuffer buffer, uint offset) {
|
||||
strided_arr arr_1[3][2] = (strided_arr[3][2])0;
|
||||
{
|
||||
[loop] for(uint i_1 = 0u; (i_1 < 3u); i_1 = (i_1 + 1u)) {
|
||||
arr_1[i_1] = tint_symbol_3(buffer, (offset + (i_1 * 16u)));
|
||||
}
|
||||
}
|
||||
return arr_1;
|
||||
}
|
||||
|
||||
strided_arr_1 tint_symbol_1(RWByteAddressBuffer buffer, uint offset) {
|
||||
const strided_arr_1 tint_symbol_13 = {tint_symbol_2(buffer, (offset + 0u))};
|
||||
return tint_symbol_13;
|
||||
}
|
||||
|
||||
typedef strided_arr_1 tint_symbol_ret[4];
|
||||
tint_symbol_ret tint_symbol(RWByteAddressBuffer buffer, uint offset) {
|
||||
strided_arr_1 arr_2[4] = (strided_arr_1[4])0;
|
||||
{
|
||||
[loop] for(uint i_2 = 0u; (i_2 < 4u); i_2 = (i_2 + 1u)) {
|
||||
arr_2[i_2] = tint_symbol_1(buffer, (offset + (i_2 * 128u)));
|
||||
}
|
||||
}
|
||||
return arr_2;
|
||||
}
|
||||
|
||||
void tint_symbol_10(RWByteAddressBuffer buffer, uint offset, strided_arr value) {
|
||||
buffer.Store((offset + 0u), asuint(value.el));
|
||||
}
|
||||
|
||||
void tint_symbol_9(RWByteAddressBuffer buffer, uint offset, strided_arr value[2]) {
|
||||
strided_arr array_2[2] = value;
|
||||
{
|
||||
[loop] for(uint i_3 = 0u; (i_3 < 2u); i_3 = (i_3 + 1u)) {
|
||||
tint_symbol_10(buffer, (offset + (i_3 * 8u)), array_2[i_3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tint_symbol_8(RWByteAddressBuffer buffer, uint offset, strided_arr value[3][2]) {
|
||||
strided_arr array_1[3][2] = value;
|
||||
{
|
||||
[loop] for(uint i_4 = 0u; (i_4 < 3u); i_4 = (i_4 + 1u)) {
|
||||
tint_symbol_9(buffer, (offset + (i_4 * 16u)), array_1[i_4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tint_symbol_7(RWByteAddressBuffer buffer, uint offset, strided_arr_1 value) {
|
||||
tint_symbol_8(buffer, (offset + 0u), value.el);
|
||||
}
|
||||
|
||||
void tint_symbol_6(RWByteAddressBuffer buffer, uint offset, strided_arr_1 value[4]) {
|
||||
strided_arr_1 array[4] = value;
|
||||
{
|
||||
[loop] for(uint i_5 = 0u; (i_5 < 4u); i_5 = (i_5 + 1u)) {
|
||||
tint_symbol_7(buffer, (offset + (i_5 * 128u)), array[i_5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void f_1() {
|
||||
const strided_arr_1 x_19[4] = tint_symbol(s, 0u);
|
||||
const strided_arr x_24[3][2] = tint_symbol_2(s, 384u);
|
||||
const strided_arr x_28[2] = tint_symbol_3(s, 416u);
|
||||
const float x_32 = asfloat(s.Load(424u));
|
||||
const strided_arr_1 tint_symbol_14[4] = (strided_arr_1[4])0;
|
||||
tint_symbol_6(s, 0u, tint_symbol_14);
|
||||
s.Store(424u, asuint(5.0f));
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void f() {
|
||||
f_1();
|
||||
return;
|
||||
}
|
||||
40
test/array/strides.spvasm.expected.msl
Normal file
40
test/array/strides.spvasm.expected.msl
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct strided_arr {
|
||||
/* 0x0000 */ float el;
|
||||
/* 0x0004 */ int8_t tint_pad[4];
|
||||
};
|
||||
struct tint_array_wrapper {
|
||||
/* 0x0000 */ strided_arr arr[2];
|
||||
};
|
||||
struct tint_array_wrapper_1 {
|
||||
/* 0x0000 */ tint_array_wrapper arr[3];
|
||||
};
|
||||
struct strided_arr_1 {
|
||||
/* 0x0000 */ tint_array_wrapper_1 el;
|
||||
/* 0x0030 */ int8_t tint_pad_1[80];
|
||||
};
|
||||
struct tint_array_wrapper_2 {
|
||||
/* 0x0000 */ strided_arr_1 arr[4];
|
||||
};
|
||||
struct S {
|
||||
/* 0x0000 */ tint_array_wrapper_2 a;
|
||||
};
|
||||
|
||||
void f_1(device S* const tint_symbol_1) {
|
||||
tint_array_wrapper_2 const x_19 = (*(tint_symbol_1)).a;
|
||||
tint_array_wrapper_1 const x_24 = (*(tint_symbol_1)).a.arr[3].el;
|
||||
tint_array_wrapper const x_28 = (*(tint_symbol_1)).a.arr[3].el.arr[2];
|
||||
float const x_32 = (*(tint_symbol_1)).a.arr[3].el.arr[2].arr[1].el;
|
||||
tint_array_wrapper_2 const tint_symbol = {.arr={}};
|
||||
(*(tint_symbol_1)).a = tint_symbol;
|
||||
(*(tint_symbol_1)).a.arr[3].el.arr[2].arr[1].el = 5.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
kernel void f(device S* tint_symbol_2 [[buffer(0)]]) {
|
||||
f_1(tint_symbol_2);
|
||||
return;
|
||||
}
|
||||
|
||||
74
test/array/strides.spvasm.expected.spvasm
Normal file
74
test/array/strides.spvasm.expected.spvasm
Normal file
@@ -0,0 +1,74 @@
|
||||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 42
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %f "f"
|
||||
OpExecutionMode %f LocalSize 1 1 1
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "a"
|
||||
OpName %strided_arr_1 "strided_arr_1"
|
||||
OpMemberName %strided_arr_1 0 "el"
|
||||
OpName %strided_arr "strided_arr"
|
||||
OpMemberName %strided_arr 0 "el"
|
||||
OpName %s "s"
|
||||
OpName %f_1 "f_1"
|
||||
OpName %f "f"
|
||||
OpDecorate %S Block
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpMemberDecorate %strided_arr_1 0 Offset 0
|
||||
OpMemberDecorate %strided_arr 0 Offset 0
|
||||
OpDecorate %_arr_strided_arr_uint_2 ArrayStride 8
|
||||
OpDecorate %_arr__arr_strided_arr_uint_2_uint_3 ArrayStride 16
|
||||
OpDecorate %_arr_strided_arr_1_uint_4 ArrayStride 128
|
||||
OpDecorate %s DescriptorSet 0
|
||||
OpDecorate %s Binding 0
|
||||
%float = OpTypeFloat 32
|
||||
%strided_arr = OpTypeStruct %float
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr_strided_arr_uint_2 = OpTypeArray %strided_arr %uint_2
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr__arr_strided_arr_uint_2_uint_3 = OpTypeArray %_arr_strided_arr_uint_2 %uint_3
|
||||
%strided_arr_1 = OpTypeStruct %_arr__arr_strided_arr_uint_2_uint_3
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_strided_arr_1_uint_4 = OpTypeArray %strided_arr_1 %uint_4
|
||||
%S = OpTypeStruct %_arr_strided_arr_1_uint_4
|
||||
%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
|
||||
%s = OpVariable %_ptr_StorageBuffer_S StorageBuffer
|
||||
%void = OpTypeVoid
|
||||
%14 = OpTypeFunction %void
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_StorageBuffer__arr_strided_arr_1_uint_4 = OpTypePointer StorageBuffer %_arr_strided_arr_1_uint_4
|
||||
%int = OpTypeInt 32 1
|
||||
%int_3 = OpConstant %int 3
|
||||
%_ptr_StorageBuffer__arr__arr_strided_arr_uint_2_uint_3 = OpTypePointer StorageBuffer %_arr__arr_strided_arr_uint_2_uint_3
|
||||
%int_2 = OpConstant %int 2
|
||||
%_ptr_StorageBuffer__arr_strided_arr_uint_2 = OpTypePointer StorageBuffer %_arr_strided_arr_uint_2
|
||||
%int_1 = OpConstant %int 1
|
||||
%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
|
||||
%36 = OpConstantNull %_arr_strided_arr_1_uint_4
|
||||
%float_5 = OpConstant %float 5
|
||||
%f_1 = OpFunction %void None %14
|
||||
%17 = OpLabel
|
||||
%20 = OpAccessChain %_ptr_StorageBuffer__arr_strided_arr_1_uint_4 %s %uint_0
|
||||
%21 = OpLoad %_arr_strided_arr_1_uint_4 %20
|
||||
%25 = OpAccessChain %_ptr_StorageBuffer__arr__arr_strided_arr_uint_2_uint_3 %s %uint_0 %int_3 %uint_0
|
||||
%26 = OpLoad %_arr__arr_strided_arr_uint_2_uint_3 %25
|
||||
%29 = OpAccessChain %_ptr_StorageBuffer__arr_strided_arr_uint_2 %s %uint_0 %int_3 %uint_0 %int_2
|
||||
%30 = OpLoad %_arr_strided_arr_uint_2 %29
|
||||
%33 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_3 %uint_0 %int_2 %int_1 %uint_0
|
||||
%34 = OpLoad %float %33
|
||||
%35 = OpAccessChain %_ptr_StorageBuffer__arr_strided_arr_1_uint_4 %s %uint_0
|
||||
OpStore %35 %36
|
||||
%37 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_3 %uint_0 %int_2 %int_1 %uint_0
|
||||
OpStore %37 %float_5
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%f = OpFunction %void None %14
|
||||
%40 = OpLabel
|
||||
%41 = OpFunctionCall %void %f_1
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
36
test/array/strides.spvasm.expected.wgsl
Normal file
36
test/array/strides.spvasm.expected.wgsl
Normal file
@@ -0,0 +1,36 @@
|
||||
struct strided_arr {
|
||||
@size(8)
|
||||
el : f32;
|
||||
}
|
||||
|
||||
type Arr = array<strided_arr, 2u>;
|
||||
|
||||
type Arr_1 = array<Arr, 3u>;
|
||||
|
||||
struct strided_arr_1 {
|
||||
@size(128)
|
||||
el : Arr_1;
|
||||
}
|
||||
|
||||
type Arr_2 = array<strided_arr_1, 4u>;
|
||||
|
||||
struct S {
|
||||
a : Arr_2;
|
||||
}
|
||||
|
||||
@group(0) @binding(0) var<storage, read_write> s : S;
|
||||
|
||||
fn f_1() {
|
||||
let x_19 : Arr_2 = s.a;
|
||||
let x_24 : Arr_1 = s.a[3].el;
|
||||
let x_28 : Arr = s.a[3].el[2];
|
||||
let x_32 : f32 = s.a[3].el[2][1].el;
|
||||
s.a = array<strided_arr_1, 4u>();
|
||||
s.a[3].el[2][1].el = 5.0;
|
||||
return;
|
||||
}
|
||||
|
||||
@stage(compute) @workgroup_size(1, 1, 1)
|
||||
fn f() {
|
||||
f_1();
|
||||
}
|
||||
Reference in New Issue
Block a user