Commit a2e75310 by steve-lunarg

HLSL: inter-stage structure splitting.

This adds structure splitting, which among other things will enable GS support where input structs are passed, and thus become input arrays of structs in the GS inputs. That is a common GS case. The salient points of this PR are: * Structure splitting has been changed from "always between stages" to "only into the VS and out of the PS". It had previously happened between stages because it's not legal to pass a struct containing a builtin IO variable. * Structs passed between stages are now split into a struct containing ONLY user types, and a collection of loose builtin IO variables, if any. The user-part is passed as a normal struct between stages, which is valid SPIR-V now that the builtin IO is removed. * Internal to the shader, a sanitized struct (with IO qualifiers removed) is used, so that e.g, functions can work unmodified. * If a builtin IO such as Position occurs in an arrayed struct, for example as an input to a GS, the array reference is moved to the split-off loose variable, which is given the array dimension itself. When passing things around inside the shader, such as over a function call, the the original type is used in a sanitized form that removes the builtIn qualifications and makes them temporaries. This means internal function calls do not have to change. However, the type when returned from the shader will be member-wise copied from the internal sanitized one to the external type. The sanitized type is used in variable declarations. When copying split types and unsplit, if a sub-struct contains only user variables, it is copied as a single entity to avoid more AST verbosity. Above strategy arrived at with talks with @johnkslang. This is a big complex change. I'm inclined to leave it as a WIP until it can get some exposure to real world cases.
parent 807a0d9e
...@@ -9,7 +9,7 @@ output primitive = line_strip ...@@ -9,7 +9,7 @@ output primitive = line_strip
0:16 Function Parameters: 0:16 Function Parameters:
0:16 'VertexID' (layout(location=0 ) in 3-element array of uint) 0:16 'VertexID' (layout(location=0 ) in 3-element array of uint)
0:16 'test' (layout(location=3 ) in 3-element array of uint) 0:16 'test' (layout(location=3 ) in 3-element array of uint)
0:16 'OutputStream' (out structure{temp float myfloat, temp int something}) 0:16 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:? Sequence 0:? Sequence
0:19 move second child to first child (temp float) 0:19 move second child to first child (temp float)
0:19 myfloat: direct index for structure (temp float) 0:19 myfloat: direct index for structure (temp float)
...@@ -43,20 +43,19 @@ output primitive = line_strip ...@@ -43,20 +43,19 @@ output primitive = line_strip
0:20 0 (const int) 0:20 0 (const int)
0:22 Sequence 0:22 Sequence
0:22 move second child to first child (temp structure{temp float myfloat, temp int something}) 0:22 move second child to first child (temp structure{temp float myfloat, temp int something})
0:22 'OutputStream' (out structure{temp float myfloat, temp int something}) 0:22 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:22 'Vert' (temp structure{temp float myfloat, temp int something}) 0:22 'Vert' (temp structure{temp float myfloat, temp int something})
0:22 EmitVertex (temp void) 0:22 EmitVertex (temp void)
0:23 Sequence 0:23 Sequence
0:23 move second child to first child (temp structure{temp float myfloat, temp int something}) 0:23 move second child to first child (temp structure{temp float myfloat, temp int something})
0:23 'OutputStream' (out structure{temp float myfloat, temp int something}) 0:23 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:23 'Vert' (temp structure{temp float myfloat, temp int something}) 0:23 'Vert' (temp structure{temp float myfloat, temp int something})
0:23 EmitVertex (temp void) 0:23 EmitVertex (temp void)
0:24 EndPrimitive (temp void) 0:24 EndPrimitive (temp void)
0:? Linker Objects 0:? Linker Objects
0:? 'VertexID' (layout(location=0 ) in 3-element array of uint) 0:? 'VertexID' (layout(location=0 ) in 3-element array of uint)
0:? 'test' (layout(location=3 ) in 3-element array of uint) 0:? 'test' (layout(location=3 ) in 3-element array of uint)
0:? 'myfloat' (layout(location=0 ) out float) 0:? 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:? 'something' (layout(location=1 ) out int)
Linked geometry stage: Linked geometry stage:
...@@ -72,7 +71,7 @@ output primitive = line_strip ...@@ -72,7 +71,7 @@ output primitive = line_strip
0:16 Function Parameters: 0:16 Function Parameters:
0:16 'VertexID' (layout(location=0 ) in 3-element array of uint) 0:16 'VertexID' (layout(location=0 ) in 3-element array of uint)
0:16 'test' (layout(location=3 ) in 3-element array of uint) 0:16 'test' (layout(location=3 ) in 3-element array of uint)
0:16 'OutputStream' (out structure{temp float myfloat, temp int something}) 0:16 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:? Sequence 0:? Sequence
0:19 move second child to first child (temp float) 0:19 move second child to first child (temp float)
0:19 myfloat: direct index for structure (temp float) 0:19 myfloat: direct index for structure (temp float)
...@@ -106,29 +105,28 @@ output primitive = line_strip ...@@ -106,29 +105,28 @@ output primitive = line_strip
0:20 0 (const int) 0:20 0 (const int)
0:22 Sequence 0:22 Sequence
0:22 move second child to first child (temp structure{temp float myfloat, temp int something}) 0:22 move second child to first child (temp structure{temp float myfloat, temp int something})
0:22 'OutputStream' (out structure{temp float myfloat, temp int something}) 0:22 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:22 'Vert' (temp structure{temp float myfloat, temp int something}) 0:22 'Vert' (temp structure{temp float myfloat, temp int something})
0:22 EmitVertex (temp void) 0:22 EmitVertex (temp void)
0:23 Sequence 0:23 Sequence
0:23 move second child to first child (temp structure{temp float myfloat, temp int something}) 0:23 move second child to first child (temp structure{temp float myfloat, temp int something})
0:23 'OutputStream' (out structure{temp float myfloat, temp int something}) 0:23 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:23 'Vert' (temp structure{temp float myfloat, temp int something}) 0:23 'Vert' (temp structure{temp float myfloat, temp int something})
0:23 EmitVertex (temp void) 0:23 EmitVertex (temp void)
0:24 EndPrimitive (temp void) 0:24 EndPrimitive (temp void)
0:? Linker Objects 0:? Linker Objects
0:? 'VertexID' (layout(location=0 ) in 3-element array of uint) 0:? 'VertexID' (layout(location=0 ) in 3-element array of uint)
0:? 'test' (layout(location=3 ) in 3-element array of uint) 0:? 'test' (layout(location=3 ) in 3-element array of uint)
0:? 'myfloat' (layout(location=0 ) out float) 0:? 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:? 'something' (layout(location=1 ) out int)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 45 // Id's are bound by 41
Capability Geometry Capability Geometry
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Geometry 4 "main" 16 31 38 42 44 EntryPoint Geometry 4 "main" 16 31 38
ExecutionMode 4 Triangles ExecutionMode 4 Triangles
ExecutionMode 4 Invocations 1 ExecutionMode 4 Invocations 1
ExecutionMode 4 OutputLineStrip ExecutionMode 4 OutputLineStrip
...@@ -141,12 +139,9 @@ output primitive = line_strip ...@@ -141,12 +139,9 @@ output primitive = line_strip
Name 16 "test" Name 16 "test"
Name 31 "VertexID" Name 31 "VertexID"
Name 38 "OutputStream" Name 38 "OutputStream"
Name 42 "myfloat"
Name 44 "something"
Decorate 16(test) Location 3 Decorate 16(test) Location 3
Decorate 31(VertexID) Location 0 Decorate 31(VertexID) Location 0
Decorate 42(myfloat) Location 0 Decorate 38(OutputStream) Location 0
Decorate 44(something) Location 1
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
...@@ -167,10 +162,6 @@ output primitive = line_strip ...@@ -167,10 +162,6 @@ output primitive = line_strip
35: TypePointer Function 7(int) 35: TypePointer Function 7(int)
37: TypePointer Output 8(PSInput) 37: TypePointer Output 8(PSInput)
38(OutputStream): 37(ptr) Variable Output 38(OutputStream): 37(ptr) Variable Output
41: TypePointer Output 6(float)
42(myfloat): 41(ptr) Variable Output
43: TypePointer Output 7(int)
44(something): 43(ptr) Variable Output
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
10(Vert): 9(ptr) Variable Function 10(Vert): 9(ptr) Variable Function
......
hlsl.struct.split.trivial.vert
Shader version: 450
0:? Sequence
0:16 Function Definition: main(struct-VS_INPUT-vf41;vf4; (temp structure{temp 4-component vector of float Pos})
0:16 Function Parameters:
0:16 'vsin' (in structure{temp 4-component vector of float Pos_in})
0:16 'Pos_loose' (in 4-component vector of float Position)
0:? Sequence
0:19 move second child to first child (temp 4-component vector of float)
0:19 Pos: direct index for structure (temp 4-component vector of float)
0:19 'vsout' (temp structure{temp 4-component vector of float Pos})
0:19 Constant:
0:19 0 (const int)
0:19 add (temp 4-component vector of float)
0:? 'Pos_in' (in 4-component vector of float Position)
0:19 'Pos_loose' (in 4-component vector of float Position)
0:21 Sequence
0:21 Sequence
0:21 move second child to first child (temp 4-component vector of float)
0:? 'Pos' (out 4-component vector of float Position)
0:21 Pos: direct index for structure (temp 4-component vector of float)
0:21 'vsout' (temp structure{temp 4-component vector of float Pos})
0:21 Constant:
0:21 0 (const int)
0:21 Branch: Return
0:? Linker Objects
0:? 'Pos' (out 4-component vector of float Position)
0:? 'Pos_in' (in 4-component vector of float Position)
0:? 'Pos_loose' (in 4-component vector of float Position)
Linked vertex stage:
Shader version: 450
0:? Sequence
0:16 Function Definition: main(struct-VS_INPUT-vf41;vf4; (temp structure{temp 4-component vector of float Pos})
0:16 Function Parameters:
0:16 'vsin' (in structure{temp 4-component vector of float Pos_in})
0:16 'Pos_loose' (in 4-component vector of float Position)
0:? Sequence
0:19 move second child to first child (temp 4-component vector of float)
0:19 Pos: direct index for structure (temp 4-component vector of float)
0:19 'vsout' (temp structure{temp 4-component vector of float Pos})
0:19 Constant:
0:19 0 (const int)
0:19 add (temp 4-component vector of float)
0:? 'Pos_in' (in 4-component vector of float Position)
0:19 'Pos_loose' (in 4-component vector of float Position)
0:21 Sequence
0:21 Sequence
0:21 move second child to first child (temp 4-component vector of float)
0:? 'Pos' (out 4-component vector of float Position)
0:21 Pos: direct index for structure (temp 4-component vector of float)
0:21 'vsout' (temp structure{temp 4-component vector of float Pos})
0:21 Constant:
0:21 0 (const int)
0:21 Branch: Return
0:? Linker Objects
0:? 'Pos' (out 4-component vector of float Position)
0:? 'Pos_in' (in 4-component vector of float Position)
0:? 'Pos_loose' (in 4-component vector of float Position)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 26
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 14 16 22
Name 4 "main"
Name 8 "VS_OUTPUT"
MemberName 8(VS_OUTPUT) 0 "Pos"
Name 10 "vsout"
Name 14 "Pos_in"
Name 16 "Pos_loose"
Name 22 "Pos"
Decorate 14(Pos_in) BuiltIn Position
Decorate 16(Pos_loose) BuiltIn Position
Decorate 22(Pos) BuiltIn Position
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8(VS_OUTPUT): TypeStruct 7(fvec4)
9: TypePointer Function 8(VS_OUTPUT)
11: TypeInt 32 1
12: 11(int) Constant 0
13: TypePointer Input 7(fvec4)
14(Pos_in): 13(ptr) Variable Input
16(Pos_loose): 13(ptr) Variable Input
19: TypePointer Function 7(fvec4)
21: TypePointer Output 7(fvec4)
22(Pos): 21(ptr) Variable Output
4(main): 2 Function None 3
5: Label
10(vsout): 9(ptr) Variable Function
15: 7(fvec4) Load 14(Pos_in)
17: 7(fvec4) Load 16(Pos_loose)
18: 7(fvec4) FAdd 15 17
20: 19(ptr) AccessChain 10(vsout) 12
Store 20 18
23: 19(ptr) AccessChain 10(vsout) 12
24: 7(fvec4) Load 23
Store 22(Pos) 24
Return
FunctionEnd
...@@ -9,7 +9,7 @@ struct PS_OUTPUT ...@@ -9,7 +9,7 @@ struct PS_OUTPUT
PS_OUTPUT Func1() PS_OUTPUT Func1()
{ {
return PS_OUTPUT(float4(1), 2, 3, 4); return PS_OUTPUT(float4(1,1,1,1), 2, 3, 4);
} }
PS_OUTPUT main() PS_OUTPUT main()
......
#define foobarblee zzzz
#define ar qqqq
#define MACRO1(x,y) foo##x##y
// #define MACRO2 abc##def
// #define SPACE_IN_MACRO int var1
float4 main() : SV_Target0
{
// float MACRO2 = 10;
float MACRO1(b##ar,blee) = 3;
return float4(foobarblee,0,0,0);
}
struct VS_INPUT
{
int x0_in : foo0;
float4 Pos_in : SV_Position;
int x1_in : foo1;
};
struct VS_OUTPUT
{
int x0_out : foo0;
float4 Pos_out : SV_Position;
int x1_out : foo1;
};
VS_OUTPUT main(VS_INPUT vsin, float4 Pos_loose : SV_Position)
{
VS_OUTPUT vsout;
vsout.x0_out = vsin.x0_in;
vsout.Pos_out = vsin.Pos_in + Pos_loose;
vsout.x1_out = vsin.x1_in;
return vsout;
}
// Test passing split structs to functions.
struct VS_INPUT
{
int x0_in : foo0;
float4 Pos_in : SV_Position;
int x1_in : foo1;
};
struct VS_OUTPUT
{
int x0_out : foo0;
float4 Pos_out : SV_Position;
int x1_out : foo1;
};
void Fn1(VS_INPUT fn1_in, VS_OUTPUT fn1_out) {
fn1_in.Pos_in + fn1_out.Pos_out;
}
VS_OUTPUT main(VS_INPUT vsin)
{
VS_OUTPUT vsout;
vsout.x0_out = vsin.x0_in;
vsout.Pos_out = vsin.Pos_in;
vsout.x1_out = vsin.x1_in;
Fn1(vsin, vsout);
return vsout;
}
// Test trivial case for structure splitting: the IN and OUT structs have ONLY an interstage IO.
// This should fall back to flattening, and not produce any empty structures.
struct VS_INPUT
{
float4 Pos_in : SV_Position;
};
struct VS_OUTPUT
{
float4 Pos : SV_Position;
};
VS_OUTPUT main(VS_INPUT vsin, float4 Pos_loose : SV_Position)
{
VS_OUTPUT vsout;
vsout.Pos = vsin.Pos_in + Pos_loose;
return vsout;
}
struct VertexData { struct VertexData {
float4 position : POSITION; float4 position : POSITION;
float4 color : COLOR0; float4 color : COLOR0;
float2 uv : TEXCOORD0; float2 uv : TEXCOORD0;
};
struct PS_IN {
float4 position : SV_POSITION;
float4 color : COLOR0;
float2 uv : TEXCOORD0;
}; };
[maxvertexcount(4)] [maxvertexcount(4)]
void main(line VertexData vin[2], inout TriangleStream<VertexData> outStream) void main(line VertexData vin[2], inout TriangleStream<PS_IN> outStream)
{ {
VertexData vout; PS_IN vout;
vout.color = vin[0].color; vout.color = vin[1].color;
vout.uv = vin[0].uv; vout.uv = vin[1].uv;
vout.position = vin[0].position; vout.position = vin[1].position;
outStream.Append(vout); outStream.Append(vout);
} }
...@@ -1223,6 +1223,16 @@ public: ...@@ -1223,6 +1223,16 @@ public:
typeName = NewPoolTString(copyOf.typeName->c_str()); typeName = NewPoolTString(copyOf.typeName->c_str());
} }
// Recursively make temporary
void makeTemporary()
{
getQualifier().makeTemporary();
if (isStruct())
for (unsigned int i = 0; i < structure->size(); ++i)
(*structure)[i].type->makeTemporary();
}
TType* clone() const TType* clone() const
{ {
TType *newType = new TType(); TType *newType = new TType();
...@@ -1309,6 +1319,20 @@ public: ...@@ -1309,6 +1319,20 @@ public:
virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
// Return true if this is interstage IO
virtual bool isInterstageIO() const
{
switch (getQualifier().builtIn) {
case EbvPosition:
case EbvPointSize:
case EbvClipDistance:
case EbvCullDistance:
return true;
default:
return false;
}
}
// Recursively checks if the type contains the given basic type // Recursively checks if the type contains the given basic type
virtual bool containsBasicType(TBasicType checkType) const virtual bool containsBasicType(TBasicType checkType) const
{ {
...@@ -1376,6 +1400,34 @@ public: ...@@ -1376,6 +1400,34 @@ public:
return false; return false;
} }
// Recursively checks if the type contains an interstage IO builtin
virtual bool containsInterstageIO() const
{
if (isInterstageIO())
return true;
if (! structure)
return false;
for (unsigned int i = 0; i < structure->size(); ++i) {
if ((*structure)[i].type->containsInterstageIO())
return true;
}
return false;
}
// Recursively checks whether a struct contains only interstage IO
virtual bool containsOnlyInterstageIO() const
{
if (! structure)
return isInterstageIO();
for (unsigned int i = 0; i < structure->size(); ++i) {
if (!(*structure)[i].type->containsOnlyInterstageIO())
return false;
}
return true;
}
virtual bool containsNonOpaque() const virtual bool containsNonOpaque() const
{ {
// list all non-opaque types // list all non-opaque types
......
...@@ -204,6 +204,9 @@ INSTANTIATE_TEST_CASE_P( ...@@ -204,6 +204,9 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.shapeConvRet.frag", "main"}, {"hlsl.shapeConvRet.frag", "main"},
{"hlsl.stringtoken.frag", "main"}, {"hlsl.stringtoken.frag", "main"},
{"hlsl.string.frag", "main"}, {"hlsl.string.frag", "main"},
{"hlsl.struct.split-1.vert", "main"},
{"hlsl.struct.split.call.vert", "main"},
{"hlsl.struct.split.trivial.vert", "main"},
{"hlsl.structarray.flatten.frag", "main"}, {"hlsl.structarray.flatten.frag", "main"},
{"hlsl.structarray.flatten.geom", "main"}, {"hlsl.structarray.flatten.geom", "main"},
{"hlsl.structin.vert", "main"}, {"hlsl.structin.vert", "main"},
......
...@@ -185,6 +185,9 @@ protected: ...@@ -185,6 +185,9 @@ protected:
void inheritGlobalDefaults(TQualifier& dst) const; void inheritGlobalDefaults(TQualifier& dst) const;
TVariable* makeInternalVariable(const char* name, const TType&) const; TVariable* makeInternalVariable(const char* name, const TType&) const;
TVariable* makeInternalVariable(const TString& name, const TType& type) const {
return makeInternalVariable(name.c_str(), type);
}
TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool track); TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool track);
void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool track); void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool track);
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
...@@ -197,7 +200,7 @@ protected: ...@@ -197,7 +200,7 @@ protected:
// Array and struct flattening // Array and struct flattening
bool shouldFlatten(const TType& type) const; bool shouldFlatten(const TType& type) const;
TIntermTyped* flattenAccess(const TSourceLoc&, TIntermTyped* base, int member); TIntermTyped* flattenAccess(TIntermTyped* base, int member);
bool shouldFlattenIO(const TType&) const; bool shouldFlattenIO(const TType&) const;
bool shouldFlattenUniform(const TType&) const; bool shouldFlattenUniform(const TType&) const;
bool wasFlattened(const TIntermTyped* node) const; bool wasFlattened(const TIntermTyped* node) const;
...@@ -205,11 +208,29 @@ protected: ...@@ -205,11 +208,29 @@ protected:
int addFlattenedMember(const TSourceLoc& loc, const TVariable&, const TType&, TFlattenData&, const TString& name, bool track); int addFlattenedMember(const TSourceLoc& loc, const TVariable&, const TType&, TFlattenData&, const TString& name, bool track);
bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); } bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); }
// Structure splitting (splits interstage builtin types into its own struct)
bool shouldSplit(const TSourceLoc& loc, const TType&);
TIntermTyped* splitAccess(const TSourceLoc& loc, TIntermTyped*& base, int& member);
TType& split(TType& type);
void split(TIntermTyped*);
void split(const TVariable&);
bool wasSplit(const TIntermTyped* node) const;
bool wasSplit(int id) const { return splitIoVars.find(id) != splitIoVars.end(); }
TVariable* getSplitIoVar(const TIntermTyped* node) const;
TVariable* getSplitIoVar(const TVariable* var) const;
TVariable* getSplitIoVar(int id) const;
void addInterstageIoToLinkage();
void flatten(const TSourceLoc& loc, const TVariable& variable); void flatten(const TSourceLoc& loc, const TVariable& variable);
int flatten(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name); int flatten(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
int flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name); int flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
int flattenArray(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name); int flattenArray(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
// Type sanitization: return existing sanitized (temporary) type if there is one, else make new one.
TType* sanitizeType(TType*);
void finish(); // post-processing
// Current state of parsing // Current state of parsing
struct TPragma contextPragma; struct TPragma contextPragma;
int loopNestingLevel; // 0 if outside all loops int loopNestingLevel; // 0 if outside all loops
...@@ -275,6 +296,14 @@ protected: ...@@ -275,6 +296,14 @@ protected:
TVector<int> flattenLevel; // nested postfix operator level for flattening TVector<int> flattenLevel; // nested postfix operator level for flattening
TVector<int> flattenOffset; // cumulative offset for flattening TVector<int> flattenOffset; // cumulative offset for flattening
// Sanitized type map. During declarations we use the sanitized form of the type
// if it exists.
TMap<const TTypeList*, TType*> sanitizedTypeMap;
// Structure splitting data:
TMap<TBuiltInVariable, TVariable*> interstageIo; // new structure created for interstage IO from user structs.
TMap<int, TVariable*> splitIoVars; // individual flattened variables
unsigned int nextInLocation; unsigned int nextInLocation;
unsigned int nextOutLocation; unsigned int nextOutLocation;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment