mirror of
https://github.com/libretro/glslang.git
synced 2025-03-04 13:17:53 +00:00
HLSL: Hook up constructor expressions through the AST.
This commit is contained in:
parent
87142c71fb
commit
d016be19fb
@ -1,8 +1,50 @@
|
||||
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:
|
||||
|
||||
|
||||
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
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 17
|
||||
|
@ -2,7 +2,7 @@ float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
|
||||
float4 AmbientColor = float4(1, 1, 1, 1);
|
||||
float4 AmbientColor = float4(1, 0.5, 0, 1);
|
||||
float AmbientIntensity = 0.1;
|
||||
|
||||
//float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
||||
|
@ -66,7 +66,7 @@ while read t; do
|
||||
*)
|
||||
echo Running HLSL-to-SPIR-V $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
|
||||
;;
|
||||
esac
|
||||
|
@ -33,6 +33,23 @@
|
||||
//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 "hlslGrammar.h"
|
||||
|
||||
@ -74,11 +91,21 @@ bool HlslGrammar::acceptTokenClass(EHlslTokenClass tokenClass)
|
||||
//
|
||||
bool HlslGrammar::acceptCompilationUnit()
|
||||
{
|
||||
TIntermNode* unitNode = nullptr;
|
||||
|
||||
while (token.tokenClass != EHTokNone) {
|
||||
if (! acceptDeclaration())
|
||||
// externalDeclaration
|
||||
TIntermNode* declarationNode;
|
||||
if (! acceptDeclaration(declarationNode))
|
||||
return false;
|
||||
|
||||
// hook it up
|
||||
unitNode = parseContext.intermediate.growAggregate(unitNode, declarationNode);
|
||||
}
|
||||
|
||||
// set root of AST
|
||||
parseContext.intermediate.setTreeRoot(unitNode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -90,8 +117,13 @@ bool HlslGrammar::acceptCompilationUnit()
|
||||
// | fully_specified_type identifier function_parameters ; // function prototype
|
||||
// | 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
|
||||
TType type;
|
||||
if (! acceptFullySpecifiedType(type))
|
||||
@ -114,7 +146,7 @@ bool HlslGrammar::acceptDeclaration()
|
||||
|
||||
// ;
|
||||
if (acceptTokenClass(EHTokSemicolon)) {
|
||||
parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode);
|
||||
node = parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -252,9 +284,9 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
// expression
|
||||
// : identifier
|
||||
// | ( expression )
|
||||
// | type(...) // constructor
|
||||
// | type(...) // constructor
|
||||
// | literal
|
||||
// | identifier + identifier
|
||||
// | identifier operator identifier // to be generalized to all expressions
|
||||
//
|
||||
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
||||
{
|
||||
@ -282,19 +314,11 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
||||
if (acceptLiteral(node))
|
||||
return true;
|
||||
|
||||
// type(...) // constructor
|
||||
TType type;
|
||||
if (acceptType(type)) {
|
||||
TIntermSequence* arguments;
|
||||
if (! acceptArguments(arguments)) {
|
||||
expected("constructor arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
// type(...) // constructor
|
||||
if (acceptConstructor(node))
|
||||
return true;
|
||||
}
|
||||
|
||||
// identifier + identifier
|
||||
// identifier operator identifier
|
||||
if (token.tokenClass == EHTokIdentifier) {
|
||||
TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string);
|
||||
advanceToken();
|
||||
@ -318,22 +342,61 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
||||
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
|
||||
// : ( 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))
|
||||
return false;
|
||||
|
||||
do {
|
||||
// expression
|
||||
TIntermTyped* arg;
|
||||
if (! acceptExpression(arg))
|
||||
break;
|
||||
|
||||
// hook it up
|
||||
parseContext.handleFunctionArgument(function, arguments, arg);
|
||||
|
||||
// ,
|
||||
if (! acceptTokenClass(EHTokComma))
|
||||
break;
|
||||
} while (true);
|
||||
|
||||
// )
|
||||
if (! acceptTokenClass(EHTokRightParen)) {
|
||||
expected("right parenthesis");
|
||||
return false;
|
||||
|
@ -55,13 +55,14 @@ namespace glslang {
|
||||
bool acceptTokenClass(EHlslTokenClass);
|
||||
|
||||
bool acceptCompilationUnit();
|
||||
bool acceptDeclaration();
|
||||
bool acceptDeclaration(TIntermNode*& node);
|
||||
bool acceptFullySpecifiedType(TType&);
|
||||
void acceptQualifier(TQualifier&);
|
||||
bool acceptType(TType&);
|
||||
bool acceptCompoundStatement();
|
||||
bool acceptExpression(TIntermTyped*&);
|
||||
bool acceptArguments(TIntermSequence*&);
|
||||
bool acceptConstructor(TIntermTyped*&);
|
||||
bool acceptArguments(TFunction*, TIntermAggregate*&);
|
||||
bool acceptLiteral(TIntermTyped*&);
|
||||
bool acceptOperator(TOperator& op);
|
||||
|
||||
|
@ -754,6 +754,14 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
|
||||
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
|
||||
// - .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.
|
||||
//
|
||||
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);
|
||||
|
||||
if (op == EOpNull) {
|
||||
error(loc, "cannot construct this type", type.getBasicString(), "");
|
||||
op = EOpConstructFloat;
|
||||
TType errorType(EbtFloat);
|
||||
type.shallowCopy(errorType);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TString empty("");
|
||||
|
@ -83,12 +83,13 @@ public:
|
||||
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||
void handleFunctionArgument(TFunction*, TIntermAggregate*&, TIntermTyped*);
|
||||
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
|
||||
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&);
|
||||
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||
|
Loading…
x
Reference in New Issue
Block a user