mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
ParseHelper: assign xfb_offset for struct members too
If the out variable is a struct type, with a xfb_offset explicitly assigned, the members need to get their xfb_offset assigned. This is specially relevant, as we cannot use layout qualifiers on struct members.
This commit is contained in:
parent
0ac199df32
commit
af8c1bdb16
@ -0,0 +1,93 @@
|
||||
spv.xfbOffsetOnStructMembersAssignment.vert
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80007
|
||||
// Id's are bound by 40
|
||||
|
||||
Capability Shader
|
||||
Capability TransformFeedback
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Vertex 4 "main" 9 21 34 38 39
|
||||
ExecutionMode 4 Xfb
|
||||
Source GLSL 450
|
||||
Name 4 "main"
|
||||
Name 7 "S"
|
||||
MemberName 7(S) 0 "x1_out"
|
||||
MemberName 7(S) 1 "x2_out"
|
||||
Name 9 "s1"
|
||||
Name 19 "S2"
|
||||
MemberName 19(S2) 0 "y1_out"
|
||||
MemberName 19(S2) 1 "y2_out"
|
||||
Name 21 "s2"
|
||||
Name 32 "gl_PerVertex"
|
||||
MemberName 32(gl_PerVertex) 0 "gl_Position"
|
||||
MemberName 32(gl_PerVertex) 1 "gl_PointSize"
|
||||
MemberName 32(gl_PerVertex) 2 "gl_ClipDistance"
|
||||
MemberName 32(gl_PerVertex) 3 "gl_CullDistance"
|
||||
Name 34 ""
|
||||
Name 38 "gl_VertexID"
|
||||
Name 39 "gl_InstanceID"
|
||||
MemberDecorate 7(S) 0 Offset 16
|
||||
MemberDecorate 7(S) 1 Offset 20
|
||||
Decorate 9(s1) Location 0
|
||||
Decorate 9(s1) XfbBuffer 2
|
||||
Decorate 9(s1) XfbStride 24
|
||||
MemberDecorate 19(S2) 0 Offset 8
|
||||
MemberDecorate 19(S2) 1 Offset 12
|
||||
Decorate 21(s2) Location 5
|
||||
Decorate 21(s2) XfbBuffer 1
|
||||
Decorate 21(s2) XfbStride 28
|
||||
MemberDecorate 32(gl_PerVertex) 0 BuiltIn Position
|
||||
MemberDecorate 32(gl_PerVertex) 1 BuiltIn PointSize
|
||||
MemberDecorate 32(gl_PerVertex) 2 BuiltIn ClipDistance
|
||||
MemberDecorate 32(gl_PerVertex) 3 BuiltIn CullDistance
|
||||
Decorate 32(gl_PerVertex) Block
|
||||
Decorate 34 XfbBuffer 0
|
||||
Decorate 34 XfbStride 0
|
||||
Decorate 38(gl_VertexID) BuiltIn VertexId
|
||||
Decorate 39(gl_InstanceID) BuiltIn InstanceId
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeFloat 32
|
||||
7(S): TypeStruct 6(float) 6(float)
|
||||
8: TypePointer Output 7(S)
|
||||
9(s1): 8(ptr) Variable Output
|
||||
10: TypeInt 32 1
|
||||
11: 10(int) Constant 0
|
||||
12: 6(float) Constant 1084227584
|
||||
13: TypePointer Output 6(float)
|
||||
15: 10(int) Constant 1
|
||||
16: 6(float) Constant 1086324736
|
||||
18: TypeVector 6(float) 4
|
||||
19(S2): TypeStruct 6(float) 18(fvec4)
|
||||
20: TypePointer Output 19(S2)
|
||||
21(s2): 20(ptr) Variable Output
|
||||
22: 6(float) Constant 1088421888
|
||||
24: 6(float) Constant 1065353216
|
||||
25: 6(float) Constant 0
|
||||
26: 18(fvec4) ConstantComposite 24 25 25 24
|
||||
27: TypePointer Output 18(fvec4)
|
||||
29: TypeInt 32 0
|
||||
30: 29(int) Constant 1
|
||||
31: TypeArray 6(float) 30
|
||||
32(gl_PerVertex): TypeStruct 18(fvec4) 6(float) 31 31
|
||||
33: TypePointer Output 32(gl_PerVertex)
|
||||
34: 33(ptr) Variable Output
|
||||
35: 18(fvec4) ConstantComposite 25 25 25 25
|
||||
37: TypePointer Input 10(int)
|
||||
38(gl_VertexID): 37(ptr) Variable Input
|
||||
39(gl_InstanceID): 37(ptr) Variable Input
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
14: 13(ptr) AccessChain 9(s1) 11
|
||||
Store 14 12
|
||||
17: 13(ptr) AccessChain 9(s1) 15
|
||||
Store 17 16
|
||||
23: 13(ptr) AccessChain 21(s2) 11
|
||||
Store 23 22
|
||||
28: 27(ptr) AccessChain 21(s2) 15
|
||||
Store 28 26
|
||||
36: 27(ptr) AccessChain 34 11
|
||||
Store 36 35
|
||||
Return
|
||||
FunctionEnd
|
23
Test/spv.xfbOffsetOnStructMembersAssignment.vert
Normal file
23
Test/spv.xfbOffsetOnStructMembersAssignment.vert
Normal file
@ -0,0 +1,23 @@
|
||||
#version 450
|
||||
|
||||
layout(xfb_buffer=2) out;
|
||||
|
||||
struct S {
|
||||
float x1_out;
|
||||
float x2_out;
|
||||
};
|
||||
|
||||
layout(location=0, xfb_offset = 16) out S s1;
|
||||
|
||||
layout(location=5, xfb_buffer=1, xfb_offset=8) out struct S2 {
|
||||
float y1_out;
|
||||
vec4 y2_out;
|
||||
}s2;
|
||||
|
||||
void main() {
|
||||
s1.x1_out = 5.0;
|
||||
s1.x2_out = 6.0;
|
||||
s2.y1_out = 7.0;
|
||||
s2.y2_out = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
@ -4030,7 +4030,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
|
||||
if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) {
|
||||
if (!currentBlockQualifier.hasXfbBuffer())
|
||||
currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
|
||||
fixBlockXfbOffsets(currentBlockQualifier, newTypeList);
|
||||
fixXfbOffsets(currentBlockQualifier, newTypeList);
|
||||
}
|
||||
|
||||
// Edit and error check the container against the redeclaration
|
||||
@ -6099,6 +6099,11 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
||||
// fix up
|
||||
fixOffset(loc, *symbol);
|
||||
|
||||
if (symbol->getType().getBasicType() == EbtStruct) {
|
||||
fixXfbOffsets(symbol->getWritableType().getQualifier(),
|
||||
*(symbol->getWritableType().getWritableStruct()));
|
||||
}
|
||||
|
||||
return initNode;
|
||||
}
|
||||
|
||||
@ -6823,7 +6828,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
||||
|
||||
// Process the members
|
||||
fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
|
||||
fixBlockXfbOffsets(currentBlockQualifier, typeList);
|
||||
fixXfbOffsets(currentBlockQualifier, typeList);
|
||||
fixBlockUniformOffsets(currentBlockQualifier, typeList);
|
||||
for (unsigned int member = 0; member < typeList.size(); ++member)
|
||||
layoutTypeCheck(typeList[member].loc, *typeList[member].type);
|
||||
@ -7065,7 +7070,7 @@ void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifi
|
||||
}
|
||||
}
|
||||
|
||||
void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
|
||||
void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
|
||||
{
|
||||
// "If a block is qualified with xfb_offset, all its
|
||||
// members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
|
||||
|
@ -403,7 +403,7 @@ public:
|
||||
void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
|
||||
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
|
||||
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
||||
void fixBlockXfbOffsets(TQualifier&, TTypeList&);
|
||||
void fixXfbOffsets(TQualifier&, TTypeList&);
|
||||
void fixBlockUniformOffsets(TQualifier&, TTypeList&);
|
||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
|
||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||
|
@ -440,6 +440,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
"spv.rankShift.comp",
|
||||
"spv.specConst.vert",
|
||||
"spv.OVR_multiview.vert",
|
||||
"spv.xfbOffsetOnStructMembersAssignment.vert",
|
||||
})),
|
||||
FileNameAsCustomTestSuffix
|
||||
);
|
||||
|
@ -8555,7 +8555,7 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TS
|
||||
|
||||
// Process the members
|
||||
fixBlockLocations(loc, type.getQualifier(), typeList, memberWithLocation, memberWithoutLocation);
|
||||
fixBlockXfbOffsets(type.getQualifier(), typeList);
|
||||
fixXfbOffsets(type.getQualifier(), typeList);
|
||||
fixBlockUniformOffsets(type.getQualifier(), typeList);
|
||||
|
||||
// reverse merge, so that currentBlockQualifier now has all layout information
|
||||
@ -8638,7 +8638,7 @@ void HlslParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qual
|
||||
}
|
||||
}
|
||||
|
||||
void HlslParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
|
||||
void HlslParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
|
||||
{
|
||||
// "If a block is qualified with xfb_offset, all its
|
||||
// members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
|
||||
|
@ -155,7 +155,7 @@ public:
|
||||
void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0);
|
||||
void declareStructBufferCounter(const TSourceLoc& loc, const TType& bufferType, const TString& name);
|
||||
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
||||
void fixBlockXfbOffsets(TQualifier&, TTypeList&);
|
||||
void fixXfbOffsets(TQualifier&, TTypeList&);
|
||||
void fixBlockUniformOffsets(const TQualifier&, TTypeList&);
|
||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
|
||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||
|
Loading…
Reference in New Issue
Block a user