--- /dev/null
+hlsl.doLoop.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:7 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:2 Function Parameters:
+0:2 'input' (temp 4-component vector of float)
+0:? Sequence
+0:3 Loop with condition not tested first
+0:3 Loop Condition
+0:3 Constant:
+0:3 false (const bool)
+0:3 No loop body
+0:4 Loop with condition not tested first
+0:4 Loop Condition
+0:4 Constant:
+0:4 false (const bool)
+0:4 No loop body
+0:5 Loop with condition not tested first
+0:5 Loop Condition
+0:5 Compare Equal (temp bool)
+0:5 'input' (temp 4-component vector of float)
+0:5 'input' (temp 4-component vector of float)
+0:5 Loop Body
+0:5 Branch: Return with expression
+0:5 'input' (temp 4-component vector of float)
+0:? Linker Objects
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:7 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:2 Function Parameters:
+0:2 'input' (temp 4-component vector of float)
+0:? Sequence
+0:3 Loop with condition not tested first
+0:3 Loop Condition
+0:3 Constant:
+0:3 false (const bool)
+0:3 No loop body
+0:4 Loop with condition not tested first
+0:4 Loop Condition
+0:4 Constant:
+0:4 false (const bool)
+0:4 No loop body
+0:5 Loop with condition not tested first
+0:5 Loop Condition
+0:5 Compare Equal (temp bool)
+0:5 'input' (temp 4-component vector of float)
+0:5 'input' (temp 4-component vector of float)
+0:5 Loop Body
+0:5 Branch: Return with expression
+0:5 'input' (temp 4-component vector of float)
+0:? Linker Objects
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 31
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "PixelShaderFunction"
+ ExecutionMode 4 OriginUpperLeft
+ Source HLSL 450
+ Name 4 "PixelShaderFunction"
+ Name 23 "input"
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 10: TypeBool
+ 11: 10(bool) ConstantFalse
+ 20: TypeFloat 32
+ 21: TypeVector 20(float) 4
+ 22: TypePointer Function 21(fvec4)
+ 28: TypeVector 10(bool) 4
+4(PixelShaderFunction): 2 Function None 3
+ 5: Label
+ 23(input): 22(ptr) Variable Function
+ Branch 6
+ 6: Label
+ LoopMerge 8 9 None
+ Branch 7
+ 7: Label
+ Branch 9
+ 9: Label
+ BranchConditional 11 6 8
+ 8: Label
+ Branch 12
+ 12: Label
+ LoopMerge 14 15 None
+ Branch 13
+ 13: Label
+ Branch 15
+ 15: Label
+ BranchConditional 11 12 14
+ 14: Label
+ Branch 16
+ 16: Label
+ LoopMerge 18 19 None
+ Branch 17
+ 17: Label
+ 24: 21(fvec4) Load 23(input)
+ ReturnValue 24
+ 19: Label
+ 26: 21(fvec4) Load 23(input)
+ 27: 21(fvec4) Load 23(input)
+ 29: 28(bvec4) FOrdEqual 26 27
+ 30: 10(bool) All 29
+ BranchConditional 30 16 18
+ 18: Label
+ Return
+ FunctionEnd
--- /dev/null
+hlsl.forLoop.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:9 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:2 Function Parameters:
+0:2 'input' (temp 4-component vector of float)
+0:? Sequence
+0:? Sequence
+0:3 Loop with condition tested first
+0:3 No loop condition
+0:3 No loop body
+0:4 Sequence
+0:4 Pre-Increment (temp 4-component vector of float)
+0:4 'input' (temp 4-component vector of float)
+0:4 Loop with condition tested first
+0:4 No loop condition
+0:4 No loop body
+0:? Sequence
+0:5 Loop with condition tested first
+0:5 Loop Condition
+0:5 Compare Not Equal (temp bool)
+0:5 'input' (temp 4-component vector of float)
+0:5 'input' (temp 4-component vector of float)
+0:5 No loop body
+0:? Sequence
+0:6 Loop with condition tested first
+0:6 Loop Condition
+0:6 Compare Not Equal (temp bool)
+0:6 'input' (temp 4-component vector of float)
+0:6 'input' (temp 4-component vector of float)
+0:6 Loop Body
+0:? Sequence
+0:6 Branch: Return with expression
+0:6 Negate value (temp 4-component vector of float)
+0:6 'input' (temp 4-component vector of float)
+0:7 Sequence
+0:7 Pre-Decrement (temp 4-component vector of float)
+0:7 'input' (temp 4-component vector of float)
+0:7 Loop with condition tested first
+0:7 Loop Condition
+0:7 Compare Not Equal (temp bool)
+0:7 'input' (temp 4-component vector of float)
+0:7 'input' (temp 4-component vector of float)
+0:7 Loop Body
+0:? Sequence
+0:7 Branch: Return with expression
+0:7 Negate value (temp 4-component vector of float)
+0:7 'input' (temp 4-component vector of float)
+0:7 Loop Terminal Expression
+0:7 add second child into first child (temp 4-component vector of float)
+0:7 'input' (temp 4-component vector of float)
+0:7 Constant:
+0:7 2.000000
+0:? Linker Objects
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:9 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:2 Function Parameters:
+0:2 'input' (temp 4-component vector of float)
+0:? Sequence
+0:? Sequence
+0:3 Loop with condition tested first
+0:3 No loop condition
+0:3 No loop body
+0:4 Sequence
+0:4 Pre-Increment (temp 4-component vector of float)
+0:4 'input' (temp 4-component vector of float)
+0:4 Loop with condition tested first
+0:4 No loop condition
+0:4 No loop body
+0:? Sequence
+0:5 Loop with condition tested first
+0:5 Loop Condition
+0:5 Compare Not Equal (temp bool)
+0:5 'input' (temp 4-component vector of float)
+0:5 'input' (temp 4-component vector of float)
+0:5 No loop body
+0:? Sequence
+0:6 Loop with condition tested first
+0:6 Loop Condition
+0:6 Compare Not Equal (temp bool)
+0:6 'input' (temp 4-component vector of float)
+0:6 'input' (temp 4-component vector of float)
+0:6 Loop Body
+0:? Sequence
+0:6 Branch: Return with expression
+0:6 Negate value (temp 4-component vector of float)
+0:6 'input' (temp 4-component vector of float)
+0:7 Sequence
+0:7 Pre-Decrement (temp 4-component vector of float)
+0:7 'input' (temp 4-component vector of float)
+0:7 Loop with condition tested first
+0:7 Loop Condition
+0:7 Compare Not Equal (temp bool)
+0:7 'input' (temp 4-component vector of float)
+0:7 'input' (temp 4-component vector of float)
+0:7 Loop Body
+0:? Sequence
+0:7 Branch: Return with expression
+0:7 Negate value (temp 4-component vector of float)
+0:7 'input' (temp 4-component vector of float)
+0:7 Loop Terminal Expression
+0:7 add second child into first child (temp 4-component vector of float)
+0:7 'input' (temp 4-component vector of float)
+0:7 Constant:
+0:7 2.000000
+0:? Linker Objects
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 64
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "PixelShaderFunction"
+ ExecutionMode 4 OriginUpperLeft
+ Source HLSL 450
+ Name 4 "PixelShaderFunction"
+ Name 13 "input"
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 10: TypeFloat 32
+ 11: TypeVector 10(float) 4
+ 12: TypePointer Function 11(fvec4)
+ 15: 10(float) Constant 1065353216
+ 29: TypeBool
+ 30: TypeVector 29(bool) 4
+ 60: 10(float) Constant 1073741824
+4(PixelShaderFunction): 2 Function None 3
+ 5: Label
+ 13(input): 12(ptr) Variable Function
+ Branch 6
+ 6: Label
+ LoopMerge 8 9 None
+ Branch 7
+ 7: Label
+ Branch 9
+ 9: Label
+ Branch 6
+ 8: Label
+ 14: 11(fvec4) Load 13(input)
+ 16: 11(fvec4) CompositeConstruct 15 15 15 15
+ 17: 11(fvec4) FAdd 14 16
+ Store 13(input) 17
+ Branch 18
+ 18: Label
+ LoopMerge 20 21 None
+ Branch 19
+ 19: Label
+ Branch 21
+ 21: Label
+ Branch 18
+ 20: Label
+ Branch 22
+ 22: Label
+ LoopMerge 24 25 None
+ Branch 26
+ 26: Label
+ 27: 11(fvec4) Load 13(input)
+ 28: 11(fvec4) Load 13(input)
+ 31: 30(bvec4) FOrdNotEqual 27 28
+ 32: 29(bool) Any 31
+ BranchConditional 32 23 24
+ 23: Label
+ Branch 25
+ 25: Label
+ Branch 22
+ 24: Label
+ Branch 33
+ 33: Label
+ LoopMerge 35 36 None
+ Branch 37
+ 37: Label
+ 38: 11(fvec4) Load 13(input)
+ 39: 11(fvec4) Load 13(input)
+ 40: 30(bvec4) FOrdNotEqual 38 39
+ 41: 29(bool) Any 40
+ BranchConditional 41 34 35
+ 34: Label
+ 42: 11(fvec4) Load 13(input)
+ 43: 11(fvec4) FNegate 42
+ ReturnValue 43
+ 36: Label
+ Branch 33
+ 35: Label
+ 45: 11(fvec4) Load 13(input)
+ 46: 11(fvec4) CompositeConstruct 15 15 15 15
+ 47: 11(fvec4) FSub 45 46
+ Store 13(input) 47
+ Branch 48
+ 48: Label
+ LoopMerge 50 51 None
+ Branch 52
+ 52: Label
+ 53: 11(fvec4) Load 13(input)
+ 54: 11(fvec4) Load 13(input)
+ 55: 30(bvec4) FOrdNotEqual 53 54
+ 56: 29(bool) Any 55
+ BranchConditional 56 49 50
+ 49: Label
+ 57: 11(fvec4) Load 13(input)
+ 58: 11(fvec4) FNegate 57
+ ReturnValue 58
+ 51: Label
+ 61: 11(fvec4) Load 13(input)
+ 62: 11(fvec4) CompositeConstruct 60 60 60 60
+ 63: 11(fvec4) FAdd 61 62
+ Store 13(input) 63
+ Branch 48
+ 50: Label
+ Return
+ FunctionEnd
--- /dev/null
+hlsl.whileLoop.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:8 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:2 Function Parameters:
+0:2 'input' (temp 4-component vector of float)
+0:? Sequence
+0:3 Loop with condition tested first
+0:3 Loop Condition
+0:3 Compare Not Equal (temp bool)
+0:3 'input' (temp 4-component vector of float)
+0:3 'input' (temp 4-component vector of float)
+0:3 Loop Body
+0:? Sequence
+0:3 Branch: Return with expression
+0:3 'input' (temp 4-component vector of float)
+0:4 Loop with condition tested first
+0:4 Loop Condition
+0:4 Constant:
+0:4 false (const bool)
+0:4 No loop body
+0:5 Loop with condition tested first
+0:5 Loop Condition
+0:5 Constant:
+0:5 false (const bool)
+0:5 No loop body
+0:6 Loop with condition tested first
+0:6 Loop Condition
+0:6 Constant:
+0:6 false (const bool)
+0:6 No loop body
+0:? Linker Objects
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:8 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:2 Function Parameters:
+0:2 'input' (temp 4-component vector of float)
+0:? Sequence
+0:3 Loop with condition tested first
+0:3 Loop Condition
+0:3 Compare Not Equal (temp bool)
+0:3 'input' (temp 4-component vector of float)
+0:3 'input' (temp 4-component vector of float)
+0:3 Loop Body
+0:? Sequence
+0:3 Branch: Return with expression
+0:3 'input' (temp 4-component vector of float)
+0:4 Loop with condition tested first
+0:4 Loop Condition
+0:4 Constant:
+0:4 false (const bool)
+0:4 No loop body
+0:5 Loop with condition tested first
+0:5 Loop Condition
+0:5 Constant:
+0:5 false (const bool)
+0:5 No loop body
+0:6 Loop with condition tested first
+0:6 Loop Condition
+0:6 Constant:
+0:6 false (const bool)
+0:6 No loop body
+0:? Linker Objects
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 39
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "PixelShaderFunction"
+ ExecutionMode 4 OriginUpperLeft
+ Source HLSL 450
+ Name 4 "PixelShaderFunction"
+ Name 14 "input"
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 11: TypeFloat 32
+ 12: TypeVector 11(float) 4
+ 13: TypePointer Function 12(fvec4)
+ 17: TypeBool
+ 18: TypeVector 17(bool) 4
+ 28: 17(bool) ConstantFalse
+4(PixelShaderFunction): 2 Function None 3
+ 5: Label
+ 14(input): 13(ptr) Variable Function
+ Branch 6
+ 6: Label
+ LoopMerge 8 9 None
+ Branch 10
+ 10: Label
+ 15: 12(fvec4) Load 14(input)
+ 16: 12(fvec4) Load 14(input)
+ 19: 18(bvec4) FOrdNotEqual 15 16
+ 20: 17(bool) Any 19
+ BranchConditional 20 7 8
+ 7: Label
+ 21: 12(fvec4) Load 14(input)
+ ReturnValue 21
+ 9: Label
+ Branch 6
+ 8: Label
+ Branch 23
+ 23: Label
+ LoopMerge 25 26 None
+ Branch 27
+ 27: Label
+ BranchConditional 28 24 25
+ 24: Label
+ Branch 26
+ 26: Label
+ Branch 23
+ 25: Label
+ Branch 29
+ 29: Label
+ LoopMerge 31 32 None
+ Branch 33
+ 33: Label
+ BranchConditional 28 30 31
+ 30: Label
+ Branch 32
+ 32: Label
+ Branch 29
+ 31: Label
+ Branch 34
+ 34: Label
+ LoopMerge 36 37 None
+ Branch 38
+ 38: Label
+ BranchConditional 28 35 36
+ 35: Label
+ Branch 37
+ 37: Label
+ Branch 34
+ 36: Label
+ Return
+ FunctionEnd
--- /dev/null
+float4 PixelShaderFunction(float4 input) : COLOR0
+{
+ [unroll] do {} while (false);
+ [unroll] do {;} while (false);
+ do { return input; } while (input == input);
+}
--- /dev/null
+float4 PixelShaderFunction(float4 input) : COLOR0
+{
+ for (;;) ;
+ for (++input; ; ) ;
+ [unroll] for (; input != input; ) {}
+ for (; input != input; ) { return -input; }
+ for (--input; input != input; input += 2) { return -input; }
+}
--- /dev/null
+float4 PixelShaderFunction(float4 input) : COLOR0
+{
+ while (input != input) { return input; }
+ while (false) ;
+ [unroll] while (false) { }
+ while ((false)) { }
+}
}
//
-// Create loop nodes.
+// Create while and do-while loop nodes.
//
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
{
}
//
+// Create a for-loop sequence.
+//
+TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
+{
+ TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
+ node->setLoc(loc);
+
+ // make a sequence of the initializer and statement
+ TIntermAggregate* loopSequence = makeAggregate(initializer, loc);
+ loopSequence = growAggregate(loopSequence, node);
+ loopSequence->setOperator(EOpSequence);
+
+ return loopSequence;
+}
+
+//
// Add branches.
//
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc)
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
+ TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
{"hlsl.assoc.frag", "PixelShaderFunction"},
{"hlsl.attribute.frag", "PixelShaderFunction"},
{"hlsl.cast.frag", "PixelShaderFunction"},
+ {"hlsl.doLoop.frag", "PixelShaderFunction"},
{"hlsl.float1.frag", "PixelShaderFunction"},
{"hlsl.float4.frag", "PixelShaderFunction"},
+ {"hlsl.forLoop.frag", "PixelShaderFunction"},
{"hlsl.if.frag", "PixelShaderFunction"},
{"hlsl.intrinsics.frag", "PixelShaderFunction"},
{"hlsl.intrinsics.negative.frag", "PixelShaderFunction"},
{"hlsl.precedence.frag", "PixelShaderFunction"},
{"hlsl.precedence2.frag", "PixelShaderFunction"},
{"hlsl.sin.frag", "PixelShaderFunction"},
+ {"hlsl.whileLoop.frag", "PixelShaderFunction"},
}),
FileNameAsCustomTestSuffix
);
return false;
}
+// iteration_statement
+// : WHILE LEFT_PAREN condition RIGHT_PAREN statement
+// | DO LEFT_BRACE statement RIGHT_BRACE WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON
+// | FOR LEFT_PAREN for_init_statement for_rest_statement RIGHT_PAREN statement
+//
+// Non-speculative, only call if it needs to be found; WHILE or DO or FOR already seen.
bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement)
{
- return false;
+ TSourceLoc loc = token.loc;
+ TIntermTyped* condition = nullptr;
+
+ EHlslTokenClass loop = peek();
+ assert(loop == EHTokDo || loop == EHTokFor || loop == EHTokWhile);
+
+ // WHILE or DO or FOR
+ advanceToken();
+
+ switch (loop) {
+ case EHTokWhile:
+ // so that something declared in the condition is scoped to the lifetime
+ // of the while sub-statement
+ parseContext.pushScope();
+ parseContext.nestLooping();
+
+ // LEFT_PAREN condition RIGHT_PAREN
+ if (! acceptParenExpression(condition))
+ return false;
+
+ // statement
+ if (! acceptScopedStatement(statement)) {
+ expected("while sub-statement");
+ return false;
+ }
+
+ parseContext.unnestLooping();
+ parseContext.popScope();
+
+ statement = intermediate.addLoop(statement, condition, nullptr, true, loc);
+
+ return true;
+
+ case EHTokDo:
+ parseContext.nestLooping();
+
+ if (! acceptTokenClass(EHTokLeftBrace))
+ expected("{");
+
+ // statement
+ if (! peekTokenClass(EHTokRightBrace) && ! acceptScopedStatement(statement)) {
+ expected("do sub-statement");
+ return false;
+ }
+
+ if (! acceptTokenClass(EHTokRightBrace))
+ expected("}");
+
+ // WHILE
+ if (! acceptTokenClass(EHTokWhile)) {
+ expected("while");
+ return false;
+ }
+
+ // LEFT_PAREN condition RIGHT_PAREN
+ TIntermTyped* condition;
+ if (! acceptParenExpression(condition))
+ return false;
+
+ if (! acceptTokenClass(EHTokSemicolon))
+ expected(";");
+
+ parseContext.unnestLooping();
+
+ statement = intermediate.addLoop(statement, condition, 0, false, loc);
+
+ return true;
+
+ case EHTokFor:
+ {
+ // LEFT_PAREN
+ if (! acceptTokenClass(EHTokLeftParen))
+ expected("(");
+
+ // so that something declared in the condition is scoped to the lifetime
+ // of the for sub-statement
+ parseContext.pushScope();
+
+ // initializer SEMI_COLON
+ TIntermTyped* initializer = nullptr; // TODO, "for (initializer" needs to support decl. statement
+ acceptExpression(initializer);
+ if (! acceptTokenClass(EHTokSemicolon))
+ expected(";");
+
+ parseContext.nestLooping();
+
+ // condition SEMI_COLON
+ acceptExpression(condition);
+ if (! acceptTokenClass(EHTokSemicolon))
+ expected(";");
+
+ // iterator SEMI_COLON
+ TIntermTyped* iterator = nullptr;
+ acceptExpression(iterator);
+ if (! acceptTokenClass(EHTokRightParen))
+ expected(")");
+
+ // statement
+ if (! acceptScopedStatement(statement)) {
+ expected("for sub-statement");
+ return false;
+ }
+
+ statement = intermediate.addForLoop(statement, initializer, condition, iterator, true, loc);
+
+ parseContext.popScope();
+ parseContext.unnestLooping();
+
+ return true;
+ }
+
+ default:
+ return false;
+ }
}
// jump_statement
void nestStatement() { ++statementNestingLevel; }
void unnestStatement() { --statementNestingLevel; }
+ void nestLooping() { ++loopNestingLevel; }
+ void unnestLooping() { --loopNestingLevel; }
void pushScope() { symbolTable.push(); }
void popScope() { symbolTable.pop(0); }