HLSL: Hook up constructor expressions through the AST.
This commit is contained in:
parent
87142c71fb
commit
d016be19fb
@ -1,8 +1,50 @@
|
|||||||
hlsl.frag
|
hlsl.frag
|
||||||
|
Shader version: 100
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:? Sequence
|
||||||
|
0:5 move second child to first child (temp 4-component vector of float)
|
||||||
|
0:5 'AmbientColor' (temp 4-component vector of float)
|
||||||
|
0:? Constant:
|
||||||
|
0:? 1.000000
|
||||||
|
0:? 0.500000
|
||||||
|
0:? 0.000000
|
||||||
|
0:? 1.000000
|
||||||
|
0:6 move second child to first child (temp float)
|
||||||
|
0:6 'AmbientIntensity' (temp float)
|
||||||
|
0:6 Constant:
|
||||||
|
0:6 0.100000
|
||||||
|
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:? 'AmbientIntensity' (temp float)
|
||||||
|
|
||||||
|
|
||||||
Linked fragment stage:
|
Linked fragment stage:
|
||||||
|
|
||||||
|
|
||||||
|
Shader version: 100
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:? Sequence
|
||||||
|
0:5 move second child to first child (temp 4-component vector of float)
|
||||||
|
0:5 'AmbientColor' (temp 4-component vector of float)
|
||||||
|
0:? Constant:
|
||||||
|
0:? 1.000000
|
||||||
|
0:? 0.500000
|
||||||
|
0:? 0.000000
|
||||||
|
0:? 1.000000
|
||||||
|
0:6 move second child to first child (temp float)
|
||||||
|
0:6 'AmbientIntensity' (temp float)
|
||||||
|
0:6 Constant:
|
||||||
|
0:6 0.100000
|
||||||
|
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:? '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 17
|
||||||
|
|||||||
@ -2,7 +2,7 @@ float4x4 World;
|
|||||||
float4x4 View;
|
float4x4 View;
|
||||||
float4x4 Projection;
|
float4x4 Projection;
|
||||||
|
|
||||||
float4 AmbientColor = float4(1, 1, 1, 1);
|
float4 AmbientColor = float4(1, 0.5, 0, 1);
|
||||||
float AmbientIntensity = 0.1;
|
float AmbientIntensity = 0.1;
|
||||||
|
|
||||||
//float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
//float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
||||||
|
|||||||
@ -66,7 +66,7 @@ while read t; do
|
|||||||
*)
|
*)
|
||||||
echo Running HLSL-to-SPIR-V $t...
|
echo Running HLSL-to-SPIR-V $t...
|
||||||
b=`basename $t`
|
b=`basename $t`
|
||||||
$EXE -D -e PixelShaderFunction -H $t > $TARGETDIR/$b.out
|
$EXE -D -e PixelShaderFunction -H -i $t > $TARGETDIR/$b.out
|
||||||
diff -b $BASEDIR/$b.out $TARGETDIR/$b.out || HASERROR=1
|
diff -b $BASEDIR/$b.out $TARGETDIR/$b.out || HASERROR=1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@ -33,6 +33,23 @@
|
|||||||
//POSSIBILITY OF SUCH DAMAGE.
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is a set of mutually recursive methods implementing the HLSL grammar.
|
||||||
|
// Generally, each returns
|
||||||
|
// - through an argument: a type specifically appropriate to which rule it
|
||||||
|
// recognized
|
||||||
|
// - through the return value: true/false to indicate whether or not it
|
||||||
|
// recognized its rule
|
||||||
|
//
|
||||||
|
// As much as possible, only grammar recognition should happen in this file,
|
||||||
|
// with all other work being farmed out to hlslParseHelper.cpp, which it turn
|
||||||
|
// will build the AST.
|
||||||
|
//
|
||||||
|
// The next token, yet to be "accepted" is always sitting in 'token'.
|
||||||
|
// When a method says it accepts a rule, that means all tokens involved
|
||||||
|
// in the rule will have been consumed, and none left in 'token'.
|
||||||
|
//
|
||||||
|
|
||||||
#include "hlslTokens.h"
|
#include "hlslTokens.h"
|
||||||
#include "hlslGrammar.h"
|
#include "hlslGrammar.h"
|
||||||
|
|
||||||
@ -74,11 +91,21 @@ bool HlslGrammar::acceptTokenClass(EHlslTokenClass tokenClass)
|
|||||||
//
|
//
|
||||||
bool HlslGrammar::acceptCompilationUnit()
|
bool HlslGrammar::acceptCompilationUnit()
|
||||||
{
|
{
|
||||||
|
TIntermNode* unitNode = nullptr;
|
||||||
|
|
||||||
while (token.tokenClass != EHTokNone) {
|
while (token.tokenClass != EHTokNone) {
|
||||||
if (! acceptDeclaration())
|
// externalDeclaration
|
||||||
|
TIntermNode* declarationNode;
|
||||||
|
if (! acceptDeclaration(declarationNode))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// hook it up
|
||||||
|
unitNode = parseContext.intermediate.growAggregate(unitNode, declarationNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set root of AST
|
||||||
|
parseContext.intermediate.setTreeRoot(unitNode);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +117,13 @@ bool HlslGrammar::acceptCompilationUnit()
|
|||||||
// | 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 function_parameters compound_statement // function definition
|
||||||
//
|
//
|
||||||
bool HlslGrammar::acceptDeclaration()
|
// 'node' could get created if the declaration creates code, like an initializer
|
||||||
|
// or a function body.
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
||||||
{
|
{
|
||||||
|
node = nullptr;
|
||||||
|
|
||||||
// fully_specified_type
|
// fully_specified_type
|
||||||
TType type;
|
TType type;
|
||||||
if (! acceptFullySpecifiedType(type))
|
if (! acceptFullySpecifiedType(type))
|
||||||
@ -114,7 +146,7 @@ bool HlslGrammar::acceptDeclaration()
|
|||||||
|
|
||||||
// ;
|
// ;
|
||||||
if (acceptTokenClass(EHTokSemicolon)) {
|
if (acceptTokenClass(EHTokSemicolon)) {
|
||||||
parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode);
|
node = parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,9 +284,9 @@ bool HlslGrammar::acceptType(TType& type)
|
|||||||
// expression
|
// expression
|
||||||
// : identifier
|
// : identifier
|
||||||
// | ( expression )
|
// | ( expression )
|
||||||
// | type(...) // constructor
|
// | type(...) // constructor
|
||||||
// | literal
|
// | literal
|
||||||
// | identifier + identifier
|
// | identifier operator identifier // to be generalized to all expressions
|
||||||
//
|
//
|
||||||
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
||||||
{
|
{
|
||||||
@ -282,19 +314,11 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
|||||||
if (acceptLiteral(node))
|
if (acceptLiteral(node))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// type(...) // constructor
|
// type(...) // constructor
|
||||||
TType type;
|
if (acceptConstructor(node))
|
||||||
if (acceptType(type)) {
|
|
||||||
TIntermSequence* arguments;
|
|
||||||
if (! acceptArguments(arguments)) {
|
|
||||||
expected("constructor arguments");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// identifier + identifier
|
// identifier operator identifier
|
||||||
if (token.tokenClass == EHTokIdentifier) {
|
if (token.tokenClass == EHTokIdentifier) {
|
||||||
TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string);
|
TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string);
|
||||||
advanceToken();
|
advanceToken();
|
||||||
@ -318,22 +342,61 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
// : type arguments
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
|
||||||
|
{
|
||||||
|
// type
|
||||||
|
TType type;
|
||||||
|
if (acceptType(type)) {
|
||||||
|
TFunction* constructorFunction = parseContext.handleConstructorCall(token.loc, type);
|
||||||
|
if (constructorFunction == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// arguments
|
||||||
|
TIntermAggregate* arguments = nullptr;
|
||||||
|
if (! acceptArguments(constructorFunction, arguments)) {
|
||||||
|
expected("constructor arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hook it up
|
||||||
|
node = parseContext.handleFunctionCall(arguments->getLoc(), constructorFunction, arguments);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// arguments
|
// arguments
|
||||||
// : ( expression , expression, ... )
|
// : ( expression , expression, ... )
|
||||||
//
|
//
|
||||||
bool HlslGrammar::acceptArguments(TIntermSequence*& arguments)
|
// The arguments are pushed onto the 'function' argument list and
|
||||||
|
// onto the 'arguments' aggregate.
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptArguments(TFunction* function, TIntermAggregate*& arguments)
|
||||||
{
|
{
|
||||||
|
// (
|
||||||
if (! acceptTokenClass(EHTokLeftParen))
|
if (! acceptTokenClass(EHTokLeftParen))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
// expression
|
||||||
TIntermTyped* arg;
|
TIntermTyped* arg;
|
||||||
if (! acceptExpression(arg))
|
if (! acceptExpression(arg))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// hook it up
|
||||||
|
parseContext.handleFunctionArgument(function, arguments, arg);
|
||||||
|
|
||||||
|
// ,
|
||||||
if (! acceptTokenClass(EHTokComma))
|
if (! acceptTokenClass(EHTokComma))
|
||||||
break;
|
break;
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
|
// )
|
||||||
if (! acceptTokenClass(EHTokRightParen)) {
|
if (! acceptTokenClass(EHTokRightParen)) {
|
||||||
expected("right parenthesis");
|
expected("right parenthesis");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -55,13 +55,14 @@ namespace glslang {
|
|||||||
bool acceptTokenClass(EHlslTokenClass);
|
bool acceptTokenClass(EHlslTokenClass);
|
||||||
|
|
||||||
bool acceptCompilationUnit();
|
bool acceptCompilationUnit();
|
||||||
bool acceptDeclaration();
|
bool acceptDeclaration(TIntermNode*& node);
|
||||||
bool acceptFullySpecifiedType(TType&);
|
bool acceptFullySpecifiedType(TType&);
|
||||||
void acceptQualifier(TQualifier&);
|
void acceptQualifier(TQualifier&);
|
||||||
bool acceptType(TType&);
|
bool acceptType(TType&);
|
||||||
bool acceptCompoundStatement();
|
bool acceptCompoundStatement();
|
||||||
bool acceptExpression(TIntermTyped*&);
|
bool acceptExpression(TIntermTyped*&);
|
||||||
bool acceptArguments(TIntermSequence*&);
|
bool acceptConstructor(TIntermTyped*&);
|
||||||
|
bool acceptArguments(TFunction*, TIntermAggregate*&);
|
||||||
bool acceptLiteral(TIntermTyped*&);
|
bool acceptLiteral(TIntermTyped*&);
|
||||||
bool acceptOperator(TOperator& op);
|
bool acceptOperator(TOperator& op);
|
||||||
|
|
||||||
|
|||||||
@ -754,6 +754,14 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
|
|||||||
return paramNodes;
|
return paramNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HlslParseContext::handleFunctionArgument(TFunction* function, TIntermAggregate*& arguments, TIntermTyped* arg)
|
||||||
|
{
|
||||||
|
TParameter param = { 0, new TType };
|
||||||
|
param.type->shallowCopy(arg->getType());
|
||||||
|
function->addParameter(param);
|
||||||
|
arguments = intermediate.growAggregate(arguments, arg);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Handle seeing function call syntax in the grammar, which could be any of
|
// Handle seeing function call syntax in the grammar, which could be any of
|
||||||
// - .length() method
|
// - .length() method
|
||||||
@ -1182,18 +1190,13 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn
|
|||||||
//
|
//
|
||||||
// Handle seeing a built-in constructor in a grammar production.
|
// Handle seeing a built-in constructor in a grammar production.
|
||||||
//
|
//
|
||||||
TFunction* HlslParseContext::handleConstructorCall(const TSourceLoc& loc, const TPublicType& publicType)
|
TFunction* HlslParseContext::handleConstructorCall(const TSourceLoc& loc, const TType& type)
|
||||||
{
|
{
|
||||||
TType type(publicType);
|
|
||||||
type.getQualifier().precision = EpqNone;
|
|
||||||
|
|
||||||
TOperator op = mapTypeToConstructorOp(type);
|
TOperator op = mapTypeToConstructorOp(type);
|
||||||
|
|
||||||
if (op == EOpNull) {
|
if (op == EOpNull) {
|
||||||
error(loc, "cannot construct this type", type.getBasicString(), "");
|
error(loc, "cannot construct this type", type.getBasicString(), "");
|
||||||
op = EOpConstructFloat;
|
return nullptr;
|
||||||
TType errorType(EbtFloat);
|
|
||||||
type.shallowCopy(errorType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TString empty("");
|
TString empty("");
|
||||||
|
|||||||
@ -83,12 +83,13 @@ public:
|
|||||||
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||||
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||||
|
void handleFunctionArgument(TFunction*, TIntermAggregate*&, TIntermTyped*);
|
||||||
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
|
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
||||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
|
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
|
||||||
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
||||||
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
|
TFunction* handleConstructorCall(const TSourceLoc&, const TType&);
|
||||||
|
|
||||||
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
|
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
|
||||||
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user