HLSL: Fix #1432: Globally initialize local static variables.
This commit is contained in:
parent
64315a8aed
commit
cf6bd066b9
7 changed files with 257 additions and 12 deletions
218
Test/baseResults/hlsl.staticFuncInit.frag.out
Executable file
218
Test/baseResults/hlsl.staticFuncInit.frag.out
Executable file
|
|
@ -0,0 +1,218 @@
|
||||||
|
hlsl.staticFuncInit.frag
|
||||||
|
Shader version: 500
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:12Sequence
|
||||||
|
0:1 Sequence
|
||||||
|
0:1 move second child to first child ( temp float)
|
||||||
|
0:1 'x' ( global float)
|
||||||
|
0:1 Constant:
|
||||||
|
0:1 1.000000
|
||||||
|
0:5 Sequence
|
||||||
|
0:5 move second child to first child ( temp float)
|
||||||
|
0:5 'x' ( global float)
|
||||||
|
0:5 Constant:
|
||||||
|
0:5 2.000000
|
||||||
|
0:4 Function Definition: f1( ( temp float)
|
||||||
|
0:4 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:6 add second child into first child ( temp float)
|
||||||
|
0:6 'x' ( global float)
|
||||||
|
0:6 Constant:
|
||||||
|
0:6 10.000000
|
||||||
|
0:7 Branch: Return with expression
|
||||||
|
0:7 'x' ( global float)
|
||||||
|
0:12 Sequence
|
||||||
|
0:12 move second child to first child ( temp float)
|
||||||
|
0:12 'x' ( global float)
|
||||||
|
0:12 Constant:
|
||||||
|
0:12 7.000000
|
||||||
|
0:11 Function Definition: f2(f1; ( temp float)
|
||||||
|
0:11 Function Parameters:
|
||||||
|
0:11 'p' ( in float)
|
||||||
|
0:? Sequence
|
||||||
|
0:13 add second child into first child ( temp float)
|
||||||
|
0:13 'x' ( global float)
|
||||||
|
0:13 'p' ( in float)
|
||||||
|
0:14 Branch: Return with expression
|
||||||
|
0:14 'x' ( global float)
|
||||||
|
0:18 Function Definition: @main( ( temp 4-component vector of float)
|
||||||
|
0:18 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:19 Branch: Return with expression
|
||||||
|
0:19 Construct vec4 ( temp 4-component vector of float)
|
||||||
|
0:19 add ( temp float)
|
||||||
|
0:19 add ( temp float)
|
||||||
|
0:19 add ( temp float)
|
||||||
|
0:19 add ( temp float)
|
||||||
|
0:19 'x' ( global float)
|
||||||
|
0:19 Function Call: f1( ( temp float)
|
||||||
|
0:19 Function Call: f1( ( temp float)
|
||||||
|
0:19 Function Call: f2(f1; ( temp float)
|
||||||
|
0:19 Constant:
|
||||||
|
0:19 5.000000
|
||||||
|
0:19 Function Call: f2(f1; ( temp float)
|
||||||
|
0:19 'x' ( global float)
|
||||||
|
0:18 Function Definition: main( ( temp void)
|
||||||
|
0:18 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:18 move second child to first child ( temp 4-component vector of float)
|
||||||
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
|
0:18 Function Call: @main( ( temp 4-component vector of float)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'x' ( global float)
|
||||||
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
|
|
||||||
|
|
||||||
|
Linked fragment stage:
|
||||||
|
|
||||||
|
|
||||||
|
Shader version: 500
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:12Sequence
|
||||||
|
0:1 Sequence
|
||||||
|
0:1 move second child to first child ( temp float)
|
||||||
|
0:1 'x' ( global float)
|
||||||
|
0:1 Constant:
|
||||||
|
0:1 1.000000
|
||||||
|
0:5 Sequence
|
||||||
|
0:5 move second child to first child ( temp float)
|
||||||
|
0:5 'x' ( global float)
|
||||||
|
0:5 Constant:
|
||||||
|
0:5 2.000000
|
||||||
|
0:4 Function Definition: f1( ( temp float)
|
||||||
|
0:4 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:6 add second child into first child ( temp float)
|
||||||
|
0:6 'x' ( global float)
|
||||||
|
0:6 Constant:
|
||||||
|
0:6 10.000000
|
||||||
|
0:7 Branch: Return with expression
|
||||||
|
0:7 'x' ( global float)
|
||||||
|
0:12 Sequence
|
||||||
|
0:12 move second child to first child ( temp float)
|
||||||
|
0:12 'x' ( global float)
|
||||||
|
0:12 Constant:
|
||||||
|
0:12 7.000000
|
||||||
|
0:11 Function Definition: f2(f1; ( temp float)
|
||||||
|
0:11 Function Parameters:
|
||||||
|
0:11 'p' ( in float)
|
||||||
|
0:? Sequence
|
||||||
|
0:13 add second child into first child ( temp float)
|
||||||
|
0:13 'x' ( global float)
|
||||||
|
0:13 'p' ( in float)
|
||||||
|
0:14 Branch: Return with expression
|
||||||
|
0:14 'x' ( global float)
|
||||||
|
0:18 Function Definition: @main( ( temp 4-component vector of float)
|
||||||
|
0:18 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:19 Branch: Return with expression
|
||||||
|
0:19 Construct vec4 ( temp 4-component vector of float)
|
||||||
|
0:19 add ( temp float)
|
||||||
|
0:19 add ( temp float)
|
||||||
|
0:19 add ( temp float)
|
||||||
|
0:19 add ( temp float)
|
||||||
|
0:19 'x' ( global float)
|
||||||
|
0:19 Function Call: f1( ( temp float)
|
||||||
|
0:19 Function Call: f1( ( temp float)
|
||||||
|
0:19 Function Call: f2(f1; ( temp float)
|
||||||
|
0:19 Constant:
|
||||||
|
0:19 5.000000
|
||||||
|
0:19 Function Call: f2(f1; ( temp float)
|
||||||
|
0:19 'x' ( global float)
|
||||||
|
0:18 Function Definition: main( ( temp void)
|
||||||
|
0:18 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:18 move second child to first child ( temp 4-component vector of float)
|
||||||
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
|
0:18 Function Call: @main( ( temp 4-component vector of float)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'x' ( global float)
|
||||||
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80007
|
||||||
|
// Id's are bound by 57
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "main" 55
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Source HLSL 500
|
||||||
|
Name 4 "main"
|
||||||
|
Name 8 "f1("
|
||||||
|
Name 13 "f2(f1;"
|
||||||
|
Name 12 "p"
|
||||||
|
Name 17 "@main("
|
||||||
|
Name 20 "x"
|
||||||
|
Name 22 "x"
|
||||||
|
Name 24 "x"
|
||||||
|
Name 44 "param"
|
||||||
|
Name 47 "param"
|
||||||
|
Name 55 "@entryPointOutput"
|
||||||
|
Decorate 55(@entryPointOutput) Location 0
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeFloat 32
|
||||||
|
7: TypeFunction 6(float)
|
||||||
|
10: TypePointer Function 6(float)
|
||||||
|
11: TypeFunction 6(float) 10(ptr)
|
||||||
|
15: TypeVector 6(float) 4
|
||||||
|
16: TypeFunction 15(fvec4)
|
||||||
|
19: TypePointer Private 6(float)
|
||||||
|
20(x): 19(ptr) Variable Private
|
||||||
|
21: 6(float) Constant 1065353216
|
||||||
|
22(x): 19(ptr) Variable Private
|
||||||
|
23: 6(float) Constant 1073741824
|
||||||
|
24(x): 19(ptr) Variable Private
|
||||||
|
25: 6(float) Constant 1088421888
|
||||||
|
26: 6(float) Constant 1092616192
|
||||||
|
43: 6(float) Constant 1084227584
|
||||||
|
54: TypePointer Output 15(fvec4)
|
||||||
|
55(@entryPointOutput): 54(ptr) Variable Output
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
Store 20(x) 21
|
||||||
|
Store 22(x) 23
|
||||||
|
Store 24(x) 25
|
||||||
|
56: 15(fvec4) FunctionCall 17(@main()
|
||||||
|
Store 55(@entryPointOutput) 56
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
||||||
|
8(f1(): 6(float) Function None 7
|
||||||
|
9: Label
|
||||||
|
27: 6(float) Load 22(x)
|
||||||
|
28: 6(float) FAdd 27 26
|
||||||
|
Store 22(x) 28
|
||||||
|
29: 6(float) Load 22(x)
|
||||||
|
ReturnValue 29
|
||||||
|
FunctionEnd
|
||||||
|
13(f2(f1;): 6(float) Function None 11
|
||||||
|
12(p): 10(ptr) FunctionParameter
|
||||||
|
14: Label
|
||||||
|
32: 6(float) Load 12(p)
|
||||||
|
33: 6(float) Load 24(x)
|
||||||
|
34: 6(float) FAdd 33 32
|
||||||
|
Store 24(x) 34
|
||||||
|
35: 6(float) Load 24(x)
|
||||||
|
ReturnValue 35
|
||||||
|
FunctionEnd
|
||||||
|
17(@main(): 15(fvec4) Function None 16
|
||||||
|
18: Label
|
||||||
|
44(param): 10(ptr) Variable Function
|
||||||
|
47(param): 10(ptr) Variable Function
|
||||||
|
38: 6(float) Load 20(x)
|
||||||
|
39: 6(float) FunctionCall 8(f1()
|
||||||
|
40: 6(float) FAdd 38 39
|
||||||
|
41: 6(float) FunctionCall 8(f1()
|
||||||
|
42: 6(float) FAdd 40 41
|
||||||
|
Store 44(param) 43
|
||||||
|
45: 6(float) FunctionCall 13(f2(f1;) 44(param)
|
||||||
|
46: 6(float) FAdd 42 45
|
||||||
|
48: 6(float) Load 20(x)
|
||||||
|
Store 47(param) 48
|
||||||
|
49: 6(float) FunctionCall 13(f2(f1;) 47(param)
|
||||||
|
50: 6(float) FAdd 46 49
|
||||||
|
51: 15(fvec4) CompositeConstruct 50 50 50 50
|
||||||
|
ReturnValue 51
|
||||||
|
FunctionEnd
|
||||||
20
Test/hlsl.staticFuncInit.frag
Executable file
20
Test/hlsl.staticFuncInit.frag
Executable file
|
|
@ -0,0 +1,20 @@
|
||||||
|
static float x = 1.0;
|
||||||
|
|
||||||
|
float f1()
|
||||||
|
{
|
||||||
|
static float x = 2.0;
|
||||||
|
x += 10.0;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float f2(float p)
|
||||||
|
{
|
||||||
|
static float x = 7.0;
|
||||||
|
x += p;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 main() : SV_TARGET
|
||||||
|
{
|
||||||
|
return x + f1() + f1() + f2(5.0) + f2(x);
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
// This header is generated by the make-revision script.
|
// This header is generated by the make-revision script.
|
||||||
|
|
||||||
#define GLSLANG_PATCH_LEVEL 2797
|
#define GLSLANG_PATCH_LEVEL 2801
|
||||||
|
|
|
||||||
1
gtests/Hlsl.FromFile.cpp
Normal file → Executable file
1
gtests/Hlsl.FromFile.cpp
Normal file → Executable file
|
|
@ -318,6 +318,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
{"hlsl.self_cast.frag", "main"},
|
{"hlsl.self_cast.frag", "main"},
|
||||||
{"hlsl.snorm.uav.comp", "main"},
|
{"hlsl.snorm.uav.comp", "main"},
|
||||||
{"hlsl.staticMemberFunction.frag", "main"},
|
{"hlsl.staticMemberFunction.frag", "main"},
|
||||||
|
{"hlsl.staticFuncInit.frag", "main"},
|
||||||
{"hlsl.store.rwbyteaddressbuffer.type.comp", "main"},
|
{"hlsl.store.rwbyteaddressbuffer.type.comp", "main"},
|
||||||
{"hlsl.stringtoken.frag", "main"},
|
{"hlsl.stringtoken.frag", "main"},
|
||||||
{"hlsl.string.frag", "main"},
|
{"hlsl.string.frag", "main"},
|
||||||
|
|
|
||||||
|
|
@ -126,8 +126,6 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
|
||||||
//
|
//
|
||||||
bool HlslGrammar::acceptCompilationUnit()
|
bool HlslGrammar::acceptCompilationUnit()
|
||||||
{
|
{
|
||||||
TIntermNode* unitNode = nullptr;
|
|
||||||
|
|
||||||
if (! acceptDeclarationList(unitNode))
|
if (! acceptDeclarationList(unitNode))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -324,7 +322,7 @@ bool HlslGrammar::acceptSamplerDeclarationDX9(TType& /*type*/)
|
||||||
// node for all the initializers. Each function created is a top-level node to grow
|
// node for all the initializers. Each function created is a top-level node to grow
|
||||||
// into the passed-in nodeList.
|
// into the passed-in nodeList.
|
||||||
//
|
//
|
||||||
// If 'nodeList' is passed in as non-null, it must an aggregate to extend for
|
// If 'nodeList' is passed in as non-null, it must be an aggregate to extend for
|
||||||
// each top-level node the declaration creates. Otherwise, if only one top-level
|
// each top-level node the declaration creates. Otherwise, if only one top-level
|
||||||
// node in generated here, that is want is returned in nodeList.
|
// node in generated here, that is want is returned in nodeList.
|
||||||
//
|
//
|
||||||
|
|
@ -506,11 +504,16 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
|
||||||
if (initializers != nullptr)
|
if (initializers != nullptr)
|
||||||
initializers->setOperator(EOpSequence);
|
initializers->setOperator(EOpSequence);
|
||||||
|
|
||||||
// Add the initializers' aggregate to the nodeList we were handed.
|
// if we have a locally scoped static, it needs a globally scoped initializer
|
||||||
if (nodeList)
|
if (declaredType.getQualifier().storage == EvqGlobal && !parseContext.symbolTable.atGlobalLevel()) {
|
||||||
nodeList = intermediate.growAggregate(nodeList, initializers);
|
unitNode = intermediate.growAggregate(unitNode, initializers, idToken.loc);
|
||||||
else
|
} else {
|
||||||
nodeList = initializers;
|
// Add the initializers' aggregate to the nodeList we were handed.
|
||||||
|
if (nodeList)
|
||||||
|
nodeList = intermediate.growAggregate(nodeList, initializers);
|
||||||
|
else
|
||||||
|
nodeList = initializers;
|
||||||
|
}
|
||||||
|
|
||||||
// SEMICOLON
|
// SEMICOLON
|
||||||
if (! acceptTokenClass(EHTokSemicolon)) {
|
if (! acceptTokenClass(EHTokSemicolon)) {
|
||||||
|
|
@ -651,7 +654,7 @@ bool HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
||||||
do {
|
do {
|
||||||
switch (peek()) {
|
switch (peek()) {
|
||||||
case EHTokStatic:
|
case EHTokStatic:
|
||||||
qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
|
qualifier.storage = EvqGlobal;
|
||||||
break;
|
break;
|
||||||
case EHTokExtern:
|
case EHTokExtern:
|
||||||
// TODO: no meaning in glslang?
|
// TODO: no meaning in glslang?
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ namespace glslang {
|
||||||
public:
|
public:
|
||||||
HlslGrammar(HlslScanContext& scanner, HlslParseContext& parseContext)
|
HlslGrammar(HlslScanContext& scanner, HlslParseContext& parseContext)
|
||||||
: HlslTokenStream(scanner), parseContext(parseContext), intermediate(parseContext.intermediate),
|
: HlslTokenStream(scanner), parseContext(parseContext), intermediate(parseContext.intermediate),
|
||||||
typeIdentifiers(false) { }
|
typeIdentifiers(false), unitNode(nullptr) { }
|
||||||
virtual ~HlslGrammar() { }
|
virtual ~HlslGrammar() { }
|
||||||
|
|
||||||
bool parse();
|
bool parse();
|
||||||
|
|
@ -133,6 +133,7 @@ namespace glslang {
|
||||||
HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate
|
HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate
|
||||||
TIntermediate& intermediate; // the final product, the intermediate representation, includes the AST
|
TIntermediate& intermediate; // the final product, the intermediate representation, includes the AST
|
||||||
bool typeIdentifiers; // shader uses some types as identifiers
|
bool typeIdentifiers; // shader uses some types as identifiers
|
||||||
|
TIntermNode* unitNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
||||||
|
|
@ -7866,6 +7866,8 @@ TVariable* HlslParseContext::declareNonArray(const TSourceLoc& loc, const TStrin
|
||||||
// Returning nullptr just means there is no code to execute to handle the
|
// Returning nullptr just means there is no code to execute to handle the
|
||||||
// initializer, which will, for example, be the case for constant initializers.
|
// initializer, which will, for example, be the case for constant initializers.
|
||||||
//
|
//
|
||||||
|
// Returns a subtree that accomplished the initialization.
|
||||||
|
//
|
||||||
TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
|
TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue