Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIRV] Reimplement flat conversion. #6189

Merged
merged 6 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
432 changes: 303 additions & 129 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp

Large diffs are not rendered by default.

24 changes: 21 additions & 3 deletions tools/clang/lib/SPIRV/SpirvEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -759,10 +759,8 @@ class SpirvEmitter : public ASTConsumer {

private:
/// \brief Performs a FlatConversion implicit cast. Fills an instance of the
/// given type with initializer <result-id>. The initializer is of type
/// initType.
/// given type with initializer <result-id>.
SpirvInstruction *processFlatConversion(const QualType type,
const QualType initType,
SpirvInstruction *initId,
SourceLocation,
SourceRange range = {});
Expand Down Expand Up @@ -1248,6 +1246,26 @@ class SpirvEmitter : public ASTConsumer {
/// Returns a function scope parameter with the same type as |param|.
SpirvVariable *createFunctionScopeTempFromParameter(const ParmVarDecl *param);

/// Returns a vector of SpirvInstruction that is the decompostion of `inst`
/// into scalars. This is recursive. For example, a struct of a 4 element
/// vector will return 4 scalars.
std::vector<SpirvInstruction *> decomposeToScalars(SpirvInstruction *inst);

/// Returns a spirv instruction with the value of the given type and layout
/// rule that is obtained by assigning each scalar in `type` to corresponding
/// value in `scalars`. This is the inverse of `decomposeToScalars`.
SpirvInstruction *
generateFromScalars(QualType type, std::vector<SpirvInstruction *> &scalars,
SpirvLayoutRule layoutRule);

/// Returns a spirv instruction with the value of the given type and layout
/// rule that is obtained by assigning `scalar` each scalar in `type`. This is
/// the same as calling `generateFromScalars` with a sufficiently large vector
/// where every element is `scalar`.
SpirvInstruction *splatScalarToGenerate(QualType type,
SpirvInstruction *scalar,
SpirvLayoutRule rule);

public:
/// \brief Wrapper method to create a fatal error message and report it
/// in the diagnostic engine associated with this consumer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ struct S {
uint64_t f;
};

struct T {
int32_t i;
int64_t j;
};

struct UT {
uint32_t i;
uint64_t j;
};

void main() {

// CHECK: [[inf:%[0-9]+]] = OpFDiv %float %float_1 %float_0
Expand Down Expand Up @@ -47,4 +57,27 @@ void main() {
// CHECK-NEXT: {{%[0-9]+}} = OpCompositeConstruct %S [[a2_float]] [[a_float_0]] [[a2_double]] [[a]] [[a_int64]] [[a_uint64]]
double a;
S s1 = (S)(a);

// TODO(6188): This is wrong because we lose most significant bits in the literal.
// CHECK: [[lit:%[0-9]+]] = OpIAdd %int %int_0 %int_1
// CHECK: [[longLit:%[0-9]+]] = OpSConvert %long [[lit]]
// CHECK: [[t:%[0-9]+]] = OpCompositeConstruct %T [[lit]] [[longLit]]
// CHECK: OpStore %t [[t]]
T t = (T)(0x100000000+1);

// TODO(6188): This is wrong because we lose most significant bits in the literal.
// CHECK: [[lit:%[0-9]+]] = OpIAdd %uint %uint_0 %uint_1
// CHECK: [[longLit:%[0-9]+]] = OpUConvert %ulong [[lit]]
// CHECK: [[t:%[0-9]+]] = OpCompositeConstruct %UT [[lit]] [[longLit]]
// CHECK: OpStore %ut [[t]]
UT ut = (UT)(0x100000000ul+1);

// TODO(6188): This is wrong because we lose most significant bits in the literal.
// CHECK: [[longLit:%[0-9]+]] = OpIAdd %ulong %ulong_4294967296 %ulong_1
// CHECK: [[lit:%[0-9]+]] = OpUConvert %uint [[longLit]]
// CHECK: [[lit2:%[0-9]+]] = OpBitcast %int [[lit]]
// CHECK: [[longLit2:%[0-9]+]] = OpBitcast %long [[longLit]]
// CHECK: [[t:%[0-9]+]] = OpCompositeConstruct %T [[lit2]] [[longLit2]]
// CHECK: OpStore %t2 [[t]]
T t2 = (T)(0x100000000ull+1);
}
52 changes: 52 additions & 0 deletions tools/clang/test/CodeGenSPIRV/cast.flat-conversion.matrix.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// RUN: %dxc -T ps_6_0 -E main %s -spirv -Zpc | FileCheck %s -check-prefix=COL -check-prefix=CHECK
// RUN: %dxc -T ps_6_0 -E main %s -spirv -Zpr | FileCheck %s -check-prefix=ROW -check-prefix=CHECK

struct S {
float2x3 a;
};

struct T {
float a[6];
};

RWStructuredBuffer<S> s_output;
RWStructuredBuffer<T> t_output;

// See https://github.com/microsoft/DirectXShaderCompiler/blob/438781364eea22d188b337be1dfa4174ed7d928c/docs/SPIR-V.rst#L723.
// COL: OpMemberDecorate %S 0 RowMajor
// ROW: OpMemberDecorate %S 0 ColMajor

// The DXIL generated for the two cases seem to produce the same results,
// and this matches that behaviour.
// CHECK: [[array_const:%[0-9]+]] = OpConstantComposite %_arr_float_uint_6 %float_0 %float_1 %float_2 %float_3 %float_4 %float_5
// CHECK: [[t:%[0-9]+]] = OpConstantComposite %T [[array_const]]

// The DXIL that is generates different order for the values depending on
// whether the matrix is column or row major. However, for SPIR-V, the value
// stored in both cases is the same because the decoration, which is checked
// above, is what determines the layout in memory for the value.

// CHECK: [[row0:%[0-9]+]] = OpConstantComposite %v3float %float_0 %float_1 %float_2
// CHECK: [[row1:%[0-9]+]] = OpConstantComposite %v3float %float_3 %float_4 %float_5
// CHECK: [[mat:%[0-9]+]] = OpConstantComposite %mat2v3float %33 %34
// CHECK: [[s:%[0-9]+]] = OpConstantComposite %S %35

void main() {
S s;
[unroll]
for( int i = 0; i < 2; ++i) {
[unroll]
for( int j = 0; j < 3; ++j) {
s.a[i][j] = i*3+j;
}
}
// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Uniform_T %t_output %int_0 %uint_0
// CHECK: OpStore [[ac]] [[t]]
T t = (T)(s);
t_output[0] = t;

// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %s_output %int_0 %uint_0
// CHECK: OpStore [[ac]] [[s]]
s = (S)t;
s_output[0] = s;
}
43 changes: 40 additions & 3 deletions tools/clang/test/CodeGenSPIRV/cast.flat-conversion.vector.hlsl
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s

struct S {
struct S1 {
float2 data[2];
};

StructuredBuffer<S> MySB;
StructuredBuffer<S1> MySB;

struct S2 {
float b0;
float3 b1;
};

struct S3 {
float3 vec;
};

StructuredBuffer<float4> input2;




float4 main() : SV_TARGET
{
Expand All @@ -19,5 +33,28 @@ float4 main() : SV_TARGET
// CHECK-NEXT: [[val:%[0-9]+]] = OpCompositeConstruct %_arr_float_uint_4 [[v1]] [[v2]] [[v3]] [[v4]]
// CHECK-NEXT: OpStore %data [[val]]
float data[4] = (float[4])MySB[0].data;
return data[1];


// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Uniform_v4float %input2 %int_0 %uint_0
// CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad %v4float [[ac]]
// CHECK-NEXT: [[elem0:%[0-9]+]] = OpCompositeExtract %float [[ld]] 0
// CHECK-NEXT: [[elem1:%[0-9]+]] = OpCompositeExtract %float [[ld]] 1
// CHECK-NEXT: [[elem2:%[0-9]+]] = OpCompositeExtract %float [[ld]] 2
// CHECK-NEXT: [[elem3:%[0-9]+]] = OpCompositeExtract %float [[ld]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v3float [[elem1]] [[elem2]] [[elem3]]
// CHECK-NEXT: OpCompositeConstruct %S2 [[elem0]] [[vec]]
S2 d2 = (S2)input2[0];


// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Uniform_v4float %input2 %int_0 %uint_0
// CHECK-NEXT: [[ld:%[0-9]+]] = OpLoad %v4float [[ac]]
// CHECK-NEXT: [[elem0:%[0-9]+]] = OpCompositeExtract %float [[ld]] 0
// CHECK-NEXT: [[elem1:%[0-9]+]] = OpCompositeExtract %float [[ld]] 1
// CHECK-NEXT: [[elem2:%[0-9]+]] = OpCompositeExtract %float [[ld]] 2
// CHECK-NEXT: [[elem3:%[0-9]+]] = OpCompositeExtract %float [[ld]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v3float [[elem0]] [[elem1]] [[elem2]]
// CHECK-NEXT: OpCompositeConstruct %S3 [[vec]]
S3 d3 = (S3)input2[0];

return 0;
}
27 changes: 22 additions & 5 deletions tools/clang/test/CodeGenSPIRV/cast.struct-to-int.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct Vectors {

RWStructuredBuffer<uint> buf : r0;
RWStructuredBuffer<uint64_t> lbuf : r1;
RWStructuredBuffer<Vectors> vbuf : r2;

// CHECK: OpName [[BUF:%[^ ]*]] "buf"
// CHECK: OpName [[LBUF:%[^ ]*]] "lbuf"
Expand Down Expand Up @@ -83,22 +84,21 @@ void main()
// CHECK: [[COLORS:%[^ ]*]] = OpLoad [[TWOCOLORS]]
// CHECK: [[COLORS0:%[^ ]*]] = OpCompositeExtract [[COLORRGBA]] [[COLORS]] 0
// CHECK: [[COLORS00:%[^ ]*]] = OpCompositeExtract [[UINT]] [[COLORS0]] 0
// CHECK: [[COLORS000:%[^ ]*]] = OpBitFieldUExtract [[UINT]] [[COLORS00]] [[U0]] [[U8]]
// CHECK: [[BUF00:%[^ ]*]] = OpAccessChain %{{[^ ]*}} [[BUF]] [[I0]] [[U0]]
// CHECK: OpStore [[BUF00]] [[COLORS000]]
// CHECK: OpStore [[BUF00]] [[COLORS00]]

buf[0] -= (uint) rgb;
// CHECK: [[RGB:%[^ ]*]] = OpLoad [[COLORRGB]]
// CHECK: [[RGB0:%[^ ]*]] = OpCompositeExtract [[UINT]] [[RGB]] 0
// CHECK: [[RGB00:%[^ ]*]] = OpBitFieldUExtract [[UINT]] [[RGB0]] [[U0]] [[U8]]
// CHECK: [[BUF00_0:%[^ ]*]] = OpAccessChain %{{[^ ]*}} [[BUF]] [[I0]] [[U0]]
// CHECK: [[V1:%[^ ]*]] = OpLoad [[UINT]] [[BUF00_0]]
// CHECK: [[V2:%[^ ]*]] = OpISub [[UINT]] [[V1]] [[RGB00]]
// CHECK: [[V2:%[^ ]*]] = OpISub [[UINT]] [[V1]] [[RGB0]]
// CHECK: OpStore [[BUF00_0]] [[V2]]

lbuf[0] = (uint64_t) v;
// CHECK: [[VECS:%[^ ]*]] = OpLoad [[VECTORS]]
// CHECK: [[VECS00:%[^ ]*]] = OpCompositeExtract [[UINT]] [[VECS]] 0 0
// CHECK: [[VECS0:%[^ ]*]] = OpCompositeExtract {{%v2uint}} [[VECS]] 0
// CHECK: [[VECS00:%[^ ]*]] = OpCompositeExtract [[UINT]] [[VECS0]] 0
// CHECK: [[V1_0:%[^ ]*]] = OpUConvert [[ULONG]] [[VECS00]]
// CHECK: [[LBUF00:%[^ ]*]] = OpAccessChain %{{[^ ]*}} [[LBUF]] [[I0]] [[U0]]
// CHECK: OpStore [[LBUF00]] [[V1_0]]
Expand All @@ -112,5 +112,22 @@ void main()
// CHECK: [[V3:%[^ ]*]] = OpLoad [[ULONG]] [[LBUF00_0]]
// CHECK: [[V4:%[^ ]*]] = OpIAdd [[ULONG]] [[V3]] [[V2_0]]
// CHECK: OpStore [[LBUF00_0]] [[V4]]

vbuf[0] = (Vectors) colors;
// CHECK: [[c0:%[^ ]*]] = OpLoad {{%[^ ]*}} %colors
// CHECK: [[c0_0:%[^ ]+]] = OpCompositeExtract %ColorRGBA [[c0]] 0
// The entire bit container extracted for each bitfield.
// CHECK: [[c0_0_0:%[^ ]*]] = OpCompositeExtract %uint [[c0_0]] 0
// CHECK: [[c0_0_1:%[^ ]*]] = OpCompositeExtract %uint [[c0_0]] 0
// CHECK: [[c0_0_2:%[^ ]*]] = OpCompositeExtract %uint [[c0_0]] 0
// CHECK: [[c0_0_3:%[^ ]*]] = OpCompositeExtract %uint [[c0_0]] 0
// CHECK: [[v0:%[^ ]*]] = OpCompositeConstruct %v2uint [[c0_0_0]] [[c0_0_1]]
// CHECK: [[v1:%[^ ]*]] = OpCompositeConstruct %v2uint [[c0_0_2]] [[c0_0_3]]
// CHECK: [[v:%[^ ]*]] = OpCompositeConstruct %Vectors_0 [[v0]] [[v1]]
// CHECK: [[vbuf:%[^ ]*]] = OpAccessChain %{{[^ ]*}} %vbuf [[I0]] [[U0]]
// CHECK: [[v0:%[^ ]*]] = OpCompositeExtract %v2uint [[v]] 0
// CHECK: [[v1:%[^ ]*]] = OpCompositeExtract %v2uint [[v]] 1
// CHECK: [[v:%[^ ]*]] = OpCompositeConstruct %Vectors [[v0]] [[v1]]
// CHECK: OpStore [[vbuf]] [[v]]
}

41 changes: 33 additions & 8 deletions tools/clang/test/CodeGenSPIRV/spirv.legal.cbuffer.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,24 @@ float4 main(in float4 pos : SV_Position) : SV_Target
// Initializing a T with a ConstantBuffer<T> is a copy
// CHECK: [[val:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[tmp:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: OpStore %buffer1 [[tmp]]
S buffer1 = myCBuffer;

// Assigning a ConstantBuffer<T> to a T is a copy
// CHECK: [[val_0:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
// CHECK-NEXT: [[vec_0:%[0-9]+]] = OpCompositeExtract %v4float [[val_0]] 0
// CHECK-NEXT: [[tmp_0:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_0]]
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val_0]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[tmp_0:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: OpStore %buffer2 [[tmp_0]]
S buffer2;
buffer2 = myCBuffer;
Expand All @@ -51,26 +61,41 @@ float4 main(in float4 pos : SV_Position) : SV_Target
// Write out each component recursively
// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %myASBuffer %uint_0 {{%[0-9]+}}
// CHECK-NEXT: [[val_2:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
// CHECK-NEXT: [[vec_1:%[0-9]+]] = OpCompositeExtract %v4float [[val_2]] 0
// CHECK-NEXT: [[tmp_1:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_1]]
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val_2]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[tmp_1:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: [[vec_2:%[0-9]+]] = OpCompositeExtract %v4float [[tmp_1]] 0
// CHECK-NEXT: [[tmp_2:%[0-9]+]] = OpCompositeConstruct %S [[vec_2]]
// CHECK-NEXT: OpStore [[ptr]] [[tmp_2]]
myASBuffer.Append(myCBuffer);

// Passing a ConstantBuffer<T> to a T parameter is a copy
// CHECK: [[val_3:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
// CHECK-NEXT: [[vec_3:%[0-9]+]] = OpCompositeExtract %v4float [[val_3]] 0
// CHECK-NEXT: [[tmp_3:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_3]]
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val_3]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[tmp_3:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: OpStore %param_var_buffer [[tmp_3]]
return doStuff(myCBuffer);
}

S retStuff() {
// Returning a ConstantBuffer<T> as a T is a copy
// CHECK: [[val_4:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
// CHECK-NEXT: [[vec_4:%[0-9]+]] = OpCompositeExtract %v4float [[val_4]] 0
// CHECK-NEXT: [[ret:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_4]]
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val_4]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[ret:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: OpReturnValue [[ret]]
return myCBuffer;
}
39 changes: 32 additions & 7 deletions tools/clang/test/CodeGenSPIRV/spirv.legal.tbuffer.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,24 @@ float4 main(in float4 pos : SV_Position) : SV_Target
// Initializing a T with a TextureBuffer<T> is a copy
// CHECK: [[val:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val]] 0
// CHECK-NEXT: [[tmp:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK: [[tmp:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: OpStore %buffer1 [[tmp]]
S buffer1 = myTBuffer;

// Assigning a TextureBuffer<T> to a T is a copy
// CHECK: [[val_0:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer
// CHECK-NEXT: [[vec_0:%[0-9]+]] = OpCompositeExtract %v4float [[val_0]] 0
// CHECK-NEXT: [[tmp_0:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_0]]
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val_0]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[tmp_0:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: OpStore %buffer2 [[tmp_0]]
S buffer2;
buffer2 = myTBuffer;
Expand All @@ -57,6 +67,11 @@ float4 main(in float4 pos : SV_Position) : SV_Target
// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %myASBuffer %uint_0 {{%[0-9]+}}
// CHECK-NEXT: [[tb:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer
// CHECK-NEXT: [[vec_1:%[0-9]+]] = OpCompositeExtract %v4float [[tb]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec_1]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec_1]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec_1]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec_1]] 3
// CHECK-NEXT: [[vec_1:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[loc:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_1]]
// CHECK-NEXT: [[vec_2:%[0-9]+]] = OpCompositeExtract %v4float [[loc]] 0
// CHECK-NEXT: [[val_2:%[0-9]+]] = OpCompositeConstruct %S [[vec_2]]
Expand All @@ -65,17 +80,27 @@ float4 main(in float4 pos : SV_Position) : SV_Target

// Passing a TextureBuffer<T> to a T parameter is a copy
// CHECK: [[val_3:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer
// CHECK-NEXT: [[vec_3:%[0-9]+]] = OpCompositeExtract %v4float [[val_3]] 0
// CHECK-NEXT: [[tmp_1:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_3]]
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val_3]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[tmp_1:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: OpStore %param_var_buffer [[tmp_1]]
return doStuff(myTBuffer);
}

S retStuff() {
// Returning a TextureBuffer<T> as a T is a copy
// CHECK: [[val_4:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer
// CHECK-NEXT: [[vec_4:%[0-9]+]] = OpCompositeExtract %v4float [[val_4]] 0
// CHECK-NEXT: [[ret:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_4]]
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val_4]] 0
// CHECK-NEXT: [[e0:%[0-9]+]] = OpCompositeExtract %float [[vec]] 0
// CHECK-NEXT: [[e1:%[0-9]+]] = OpCompositeExtract %float [[vec]] 1
// CHECK-NEXT: [[e2:%[0-9]+]] = OpCompositeExtract %float [[vec]] 2
// CHECK-NEXT: [[e3:%[0-9]+]] = OpCompositeExtract %float [[vec]] 3
// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeConstruct %v4float [[e0]] [[e1]] [[e2]] [[e3]]
// CHECK-NEXT: [[ret:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]]
// CHECK-NEXT: OpReturnValue [[ret]]
return myTBuffer;
}
Loading
Loading