Skip to content

Commit

Permalink
[SPIRV] Reimplement flat conversion. (microsoft#6189)
Browse files Browse the repository at this point in the history
The implementation of flat conversion in the spir-v codegen is very
adhoc. This changes the implemetation to match what is done in DXIL. For
now I have only reimplemented to catch all case. I will leave the
special cases as they seem to be correct for what they do, and will
generate less verbose code.

Fixes microsoft#4906

---------

Co-authored-by: Nathan Gauër <[email protected]>
  • Loading branch information
s-perron and Keenuts authored Jan 30, 2024
1 parent 8b66d5a commit 8019c71
Show file tree
Hide file tree
Showing 9 changed files with 557 additions and 155 deletions.
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 @@ -760,10 +760,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 @@ -1213,6 +1211,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

0 comments on commit 8019c71

Please sign in to comment.