HLSL: Accept basic funtion definitions. (Not yet mapping input/output for entry point.)

This commit is contained in:
John Kessenich
2016-03-13 17:58:25 -06:00
parent 48882ef5a8
commit 5f934b039a
4 changed files with 240 additions and 76 deletions

View File

@@ -2,23 +2,23 @@ hlsl.frag
Shader version: 100 Shader version: 100
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:5 move second child to first child (temp 4-component vector of float) 0:1 move second child to first child (temp 4-component vector of float)
0:5 'AmbientColor' (temp 4-component vector of float) 0:1 'AmbientColor' (temp 4-component vector of float)
0:? Constant: 0:? Constant:
0:? 1.000000 0:? 1.000000
0:? 0.500000 0:? 0.500000
0:? 0.000000 0:? 0.000000
0:? 1.000000 0:? 1.000000
0:6 move second child to first child (temp float) 0:8 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
0:6 'AmbientIntensity' (temp float) 0:5 Function Parameters:
0:6 Constant: 0:5 'input' (temp 4-component vector of float)
0:6 0.100000 0:? Sequence
0:6 Branch: Return with expression
0:6 add (temp 4-component vector of float)
0:6 'input' (temp 4-component vector of float)
0:6 'AmbientColor' (temp 4-component vector of float)
0:? Linker Objects 0:? Linker Objects
0:? 'World' (temp 4X4 matrix of float)
0:? 'View' (temp 4X4 matrix of float)
0:? 'Projection' (temp 4X4 matrix of float)
0:? 'AmbientColor' (temp 4-component vector of float) 0:? 'AmbientColor' (temp 4-component vector of float)
0:? 'AmbientIntensity' (temp float)
Linked fragment stage: Linked fragment stage:
@@ -27,27 +27,27 @@ Linked fragment stage:
Shader version: 100 Shader version: 100
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:5 move second child to first child (temp 4-component vector of float) 0:1 move second child to first child (temp 4-component vector of float)
0:5 'AmbientColor' (temp 4-component vector of float) 0:1 'AmbientColor' (temp 4-component vector of float)
0:? Constant: 0:? Constant:
0:? 1.000000 0:? 1.000000
0:? 0.500000 0:? 0.500000
0:? 0.000000 0:? 0.000000
0:? 1.000000 0:? 1.000000
0:6 move second child to first child (temp float) 0:8 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
0:6 'AmbientIntensity' (temp float) 0:5 Function Parameters:
0:6 Constant: 0:5 'input' (temp 4-component vector of float)
0:6 0.100000 0:? Sequence
0:6 Branch: Return with expression
0:6 add (temp 4-component vector of float)
0:6 'input' (temp 4-component vector of float)
0:6 'AmbientColor' (temp 4-component vector of float)
0:? Linker Objects 0:? Linker Objects
0:? 'World' (temp 4X4 matrix of float)
0:? 'View' (temp 4X4 matrix of float)
0:? 'Projection' (temp 4X4 matrix of float)
0:? 'AmbientColor' (temp 4-component vector of float) 0:? 'AmbientColor' (temp 4-component vector of float)
0:? 'AmbientIntensity' (temp float)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 17 // Id's are bound by 15
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
@@ -56,24 +56,19 @@ gl_FragCoord origin is upper left
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
Source HLSL 100 Source HLSL 100
Name 4 "PixelShaderFunction" Name 4 "PixelShaderFunction"
Name 10 "World" Name 9 "input"
Name 11 "View" Name 11 "AmbientColor"
Name 12 "Projection"
Name 14 "AmbientColor"
Name 16 "AmbientIntensity"
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
7: TypeVector 6(float) 4 7: TypeVector 6(float) 4
8: TypeMatrix 7(fvec4) 4 8: TypePointer Function 7(fvec4)
9: TypePointer Function 8
13: TypePointer Function 7(fvec4)
15: TypePointer Function 6(float)
4(PixelShaderFunction): 2 Function None 3 4(PixelShaderFunction): 2 Function None 3
5: Label 5: Label
10(World): 9(ptr) Variable Function 9(input): 8(ptr) Variable Function
11(View): 9(ptr) Variable Function 11(AmbientColor): 8(ptr) Variable Function
12(Projection): 9(ptr) Variable Function 10: 7(fvec4) Load 9(input)
14(AmbientColor): 13(ptr) Variable Function 12: 7(fvec4) Load 11(AmbientColor)
16(AmbientIntensity): 15(ptr) Variable Function 13: 7(fvec4) FAdd 10 12
ReturnValue 13
FunctionEnd FunctionEnd

View File

@@ -1,11 +1,7 @@
float4x4 World;
float4x4 View;
float4x4 Projection;
float4 AmbientColor = float4(1, 0.5, 0, 1); float4 AmbientColor = float4(1, 0.5, 0, 1);
float AmbientIntensity = 0.1; //float AmbientIntensity = 0.1;
//float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 float4 PixelShaderFunction(float4 input) : COLOR0
//{ {
// return AmbientColor * AmbientIntensity; return input /* * AmbientIntensity */ + AmbientColor;
//} }

View File

@@ -110,12 +110,12 @@ bool HlslGrammar::acceptCompilationUnit()
} }
// declaration // declaration
// : SEMICOLON // : ;
// : fully_specified_type ; // : fully_specified_type ;
// | fully_specified_type identifier ; // | fully_specified_type identifier ;
// | fully_specified_type identifier = expression ; // | fully_specified_type identifier = expression ;
// | fully_specified_type identifier function_parameters ; // function prototype // | fully_specified_type identifier function_parameters ; // function prototype
// | fully_specified_type function_parameters compound_statement // function definition // | fully_specified_type identifier function_parameters : semantic compound_statement // function definition
// //
// 'node' could get created if the declaration creates code, like an initializer // 'node' could get created if the declaration creates code, like an initializer
// or a function body. // or a function body.
@@ -149,9 +149,34 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
node = parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode); node = parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode);
return true; return true;
} }
// function_parameters
TFunction* function = new TFunction(declName, type);
if (acceptFunctionParameters(*function)) {
// :
if (acceptTokenClass(EHTokColon)) {
// semantic
if (token.tokenClass == EHTokIdentifier) {
TString* semantic = token.string;
advanceToken();
} else {
expected("semantic");
return false;
}
}
// compound_statement
if (token.tokenClass == EHTokLeftBrace)
return acceptFunctionDefinition(*function, node);
// ;
if (acceptTokenClass(EHTokSemicolon))
return true;
return false;
}
} }
// no identifier, just ; // ; [ no identifier, just ; ]
if (acceptTokenClass(EHTokSemicolon)) if (acceptTokenClass(EHTokSemicolon))
return true; return true;
@@ -281,19 +306,110 @@ bool HlslGrammar::acceptType(TType& type)
return true; return true;
} }
// function_parameters
// : ( parameter_declaration , parameter_declaration ... )
//
bool HlslGrammar::acceptFunctionParameters(TFunction& function)
{
// (
if (! acceptTokenClass(EHTokLeftParen))
return false;
do {
// parameter_declaration
if (! acceptParameterDeclaration(function))
break;
// ,
if (! acceptTokenClass(EHTokComma))
break;
} while (true);
// )
if (! acceptTokenClass(EHTokRightParen)) {
expected("right parenthesis");
return false;
}
return true;
}
// parameter_declaration
// : fully_specified_type
// | fully_specified_type identifier
//
bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
{
// fully_specified_type
TType* type = new TType;
if (! acceptFullySpecifiedType(*type))
return false;
// identifier
TString name;
if (token.tokenClass == EHTokIdentifier) {
name = *token.string;
advanceToken();
}
TParameter param = { token.string, type };
function.addParameter(param);
return true;
}
// Do the work to create the function definition in addition to
// parsing the body (compound_statement).
bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& node)
{
TFunction* functionDeclarator = parseContext.handleFunctionDeclarator(token.loc, function, false /* not prototype */);
// This does a symbol table push
node = parseContext.handleFunctionDefinition(token.loc, *functionDeclarator);
// compound_statement
TIntermAggregate* functionBody = nullptr;
if (acceptCompoundStatement(functionBody)) {
node = parseContext.intermediate.growAggregate(node, functionBody);
parseContext.intermediate.setAggregateOperator(node, EOpFunction, functionDeclarator->getType(), token.loc);
node->getAsAggregate()->setName(functionDeclarator->getMangledName().c_str());
parseContext.symbolTable.pop(nullptr);
return true;
}
return false;
}
// expression // expression
// : identifier // : identifier
// | identifier operator identifier // to be generalized to all expressions
// | ( expression ) // | ( expression )
// | type(...) // constructor // | type(...) // constructor
// | literal // | literal
// | identifier operator identifier // to be generalized to all expressions
// //
bool HlslGrammar::acceptExpression(TIntermTyped*& node) bool HlslGrammar::acceptExpression(TIntermTyped*& node)
{ {
// identifier // identifier
if (token.tokenClass == EHTokIdentifier) { if (token.tokenClass == EHTokIdentifier) {
node = parseContext.handleVariable(token.loc, token.symbol, token.string); TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string);
return true; advanceToken();
// operator?
TOperator op;
if (! acceptOperator(op))
return true;
TSourceLoc loc = token.loc;
// identifier
if (token.tokenClass == EHTokIdentifier) {
TIntermTyped* right = parseContext.handleVariable(token.loc, token.symbol, token.string);
advanceToken();
node = parseContext.intermediate.addBinaryMath(op, left, right, loc);
return true;
}
return false;
} }
// ( expression ) // ( expression )
@@ -318,28 +434,7 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
if (acceptConstructor(node)) if (acceptConstructor(node))
return true; return true;
// identifier operator identifier return false;
if (token.tokenClass == EHTokIdentifier) {
TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string);
advanceToken();
// operator
TOperator op;
if (! acceptOperator(op))
return false;
TSourceLoc loc = token.loc;
// right
if (token.tokenClass == EHTokIdentifier) {
TIntermTyped* right = parseContext.handleVariable(token.loc, token.symbol, token.string);
advanceToken();
node = parseContext.intermediate.addBinaryMath(op, left, right, loc);
} else
return false;
} else
return false;
return true;
} }
// constructor // constructor
@@ -430,12 +525,26 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
return true; return true;
} }
// operator
// : + | - | * | / | ...
bool HlslGrammar::acceptOperator(TOperator& op) bool HlslGrammar::acceptOperator(TOperator& op)
{ {
switch (token.tokenClass) { switch (token.tokenClass) {
case EHTokEqual:
op = EOpAssign;
break;
case EHTokPlus: case EHTokPlus:
op = EOpAdd; op = EOpAdd;
break; break;
case EHTokDash:
op = EOpSub;
break;
case EHTokStar:
op = EOpMul;
break;
case EHTokSlash:
op = EOpDiv;
break;
default: default:
return false; return false;
} }
@@ -445,9 +554,69 @@ bool HlslGrammar::acceptOperator(TOperator& op)
return true; return true;
} }
bool HlslGrammar::acceptCompoundStatement() // compound_statement
// : { statement statement ... }
//
bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
{ {
return false; // {
if (! acceptTokenClass(EHTokLeftBrace))
return false;
// statement statement ...
TIntermNode* statement = nullptr;
while (acceptStatement(statement)) {
// hook it up
compoundStatement = parseContext.intermediate.growAggregate(compoundStatement, statement);
}
compoundStatement->setOperator(EOpSequence);
// }
return acceptTokenClass(EHTokRightBrace);
}
// statement
// : compound_statement
// | return ;
// | return expression ;
// | expression ;
//
bool HlslGrammar::acceptStatement(TIntermNode*& statement)
{
// compound_statement
TIntermAggregate* compoundStatement = nullptr;
if (acceptCompoundStatement(compoundStatement)) {
statement = compoundStatement;
return true;
}
// return
if (acceptTokenClass(EHTokReturn)) {
// expression
TIntermTyped* node;
if (acceptExpression(node)) {
// hook it up
statement = parseContext.intermediate.addBranch(EOpReturn, node, token.loc);
} else
statement = parseContext.intermediate.addBranch(EOpReturn, token.loc);
// ;
if (! acceptTokenClass(EHTokSemicolon))
return false;
return true;
}
// expression
TIntermTyped* node;
if (acceptExpression(node))
statement = node;
// ;
if (! acceptTokenClass(EHTokSemicolon))
return false;
return true;
} }
} // end namespace glslang } // end namespace glslang

View File

@@ -59,12 +59,16 @@ namespace glslang {
bool acceptFullySpecifiedType(TType&); bool acceptFullySpecifiedType(TType&);
void acceptQualifier(TQualifier&); void acceptQualifier(TQualifier&);
bool acceptType(TType&); bool acceptType(TType&);
bool acceptCompoundStatement(); bool acceptFunctionParameters(TFunction&);
bool acceptParameterDeclaration(TFunction&);
bool acceptFunctionDefinition(TFunction&, TIntermNode*&);
bool acceptExpression(TIntermTyped*&); bool acceptExpression(TIntermTyped*&);
bool acceptConstructor(TIntermTyped*&); bool acceptConstructor(TIntermTyped*&);
bool acceptArguments(TFunction*, TIntermAggregate*&); bool acceptArguments(TFunction*, TIntermAggregate*&);
bool acceptLiteral(TIntermTyped*&); bool acceptLiteral(TIntermTyped*&);
bool acceptOperator(TOperator& op); bool acceptOperator(TOperator& op);
bool acceptCompoundStatement(TIntermAggregate*&);
bool acceptStatement(TIntermNode*&);
HlslScanContext& scanContext; HlslScanContext& scanContext;
HlslParseContext& parseContext; HlslParseContext& parseContext;