Commit 75694fda by John Kessenich

Implement implicit conversions of function-call arguments (both in and out) as…

Implement implicit conversions of function-call arguments (both in and out) as explicit conversions in the AST, through handleArgumentConversions(). Also - uniformly handle EvqConstReadOnly as an input argument in a function, with isParamInput() and isParamOutput() queries in TQualifier. - provide a makeTemporary() in TQualifier, for erasing original qualification when making a temp - provide a makeInternalVariable() call to make a shader variable not seen in the shader source git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@25912 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent e5d92eb1
......@@ -58,15 +58,15 @@ float overloadA(float); // ERROR, different return value for same sig
float overloadA(out float f, int);
float overloadA(int i);
vec2 overloadB(float, float);
void overloadB(float, const in float) { }
vec2 overloadC(int, int);
vec2 overloadC(int, float);
vec2 overloadC(const in int, float);
vec2 overloadC(float, int);
vec2 overloadC(vec2, vec2);
vec3 overloadD(int, float);
vec3 overloadD(float, int);
vec3 overloadD(float, in int);
vec3 overloadE(float[2]);
vec3 overloadE(mat2 m);
......@@ -119,3 +119,21 @@ void foo()
}
varying vec4 gl_TexCoord[35]; // ERROR, size too big
// tests for output conversions
void outFun(in float, out ivec2, in int, out float);
int outFunRet(in float, out int, const in int, out ivec4);
ivec2 outFunRet(in float, out ivec4, in int, out ivec4);
void foo2()
{
vec2 v2;
vec4 v4;
float f;
int i;
outFun(i, v2, i, f);
outFunRet(i, f, i, v4);
float ret = outFunRet(i, f, i, v4);
vec2 ret2 = outFunRet(i, v4, i, v4);
}
......@@ -94,20 +94,25 @@ ERROR: node is still EOpNull!
0:43 'gl_PointSize' (invariant gl_PointSize float)
0:43 Constant:
0:43 3.800000
0:61 Function Definition: overloadB(f1;f1; (void)
0:61 Function Parameters:
0:61 '' (in float)
0:61 '' (const (read only) float)
0:78 Function Definition: foo( (void)
0:78 Function Parameters:
0:? Sequence
0:83 Function Call: overloadB(f1;f1; (2-component vector of float)
0:83 Function Call: overloadB(f1;f1; (void)
0:83 'f' (float)
0:83 'f' (float)
0:84 Function Call: overloadB(f1;f1; (2-component vector of float)
0:84 Function Call: overloadB(f1;f1; (void)
0:84 'f' (float)
0:84 Constant:
0:84 2 (const int)
0:85 Function Call: overloadB(f1;f1; (2-component vector of float)
0:84 2.000000
0:85 Function Call: overloadB(f1;f1; (void)
0:85 Constant:
0:85 1 (const int)
0:85 'i' (int)
0:85 1.000000
0:85 Convert int to float (float)
0:85 'i' (int)
0:87 Constant:
0:87 0.000000
0:88 Function Call: overloadC(i1;i1; (2-component vector of float)
......@@ -125,8 +130,8 @@ ERROR: node is still EOpNull!
0:90 0.000000
0:91 Function Call: overloadC(vf2;vf2; (2-component vector of float)
0:91 Constant:
0:91 1 (const int)
0:91 1 (const int)
0:91 1.000000
0:91 1.000000
0:91 Constant:
0:91 2.000000
0:91 2.000000
......@@ -137,7 +142,8 @@ ERROR: node is still EOpNull!
0:94 'f' (float)
0:94 'i' (int)
0:95 Function Call: overloadD(f1;i1; (3-component vector of float)
0:95 'i' (int)
0:95 Convert int to float (float)
0:95 'i' (int)
0:95 'i' (int)
0:98 Constant:
0:98 0.000000
......@@ -146,8 +152,8 @@ ERROR: node is still EOpNull!
0:101 Function Call: texture2D(s21;vf2; (4-component vector of float)
0:101 's2D' (uniform sampler2D)
0:101 Constant:
0:101 0 (const int)
0:101 0 (const int)
0:101 0.000000
0:101 0.000000
0:102 clamp (4-component vector of float)
0:102 'attv4' (in 4-component vector of float)
0:102 Constant:
......@@ -181,8 +187,8 @@ ERROR: node is still EOpNull!
0:111 0.000000
0:112 Function Call: overloadE(vf2; (3-component vector of float)
0:112 Constant:
0:112 1 (const int)
0:112 1 (const int)
0:112 1.000000
0:112 1.000000
0:115 Function Call: overloadE(f1[2]; (3-component vector of float)
0:115 'b' (2-element array of float)
0:117 Constant:
......@@ -190,6 +196,82 @@ ERROR: node is still EOpNull!
0:118 Function Call: overloadF(i1; (3-component vector of float)
0:118 Constant:
0:118 1 (const int)
0:128 Function Definition: foo2( (void)
0:128 Function Parameters:
0:? Sequence
0:135 Comma (void)
0:135 Function Call: outFun(f1;vi2;i1;f1; (void)
0:135 Convert int to float (float)
0:135 'i' (int)
0:135 'tempArg' (out 2-component vector of int)
0:135 'i' (int)
0:135 'f' (float)
0:135 move second child to first child (2-component vector of float)
0:135 'v2' (2-component vector of float)
0:135 Convert int to float (2-component vector of float)
0:135 'tempArg' (out 2-component vector of int)
0:136 Comma (int)
0:136 move second child to first child (int)
0:136 'tempReturn' (int)
0:136 Function Call: outFunRet(f1;i1;i1;vi4; (int)
0:136 Convert int to float (float)
0:136 'i' (int)
0:136 'tempArg' (out int)
0:136 'i' (int)
0:136 'tempArg' (out 4-component vector of int)
0:136 move second child to first child (float)
0:136 'f' (float)
0:136 Convert int to float (float)
0:136 'tempArg' (out int)
0:136 move second child to first child (4-component vector of float)
0:136 'v4' (4-component vector of float)
0:136 Convert int to float (4-component vector of float)
0:136 'tempArg' (out 4-component vector of int)
0:136 'tempReturn' (int)
0:137 Sequence
0:137 move second child to first child (float)
0:137 'ret' (float)
0:137 Convert int to float (float)
0:137 Comma (int)
0:137 move second child to first child (int)
0:137 'tempReturn' (int)
0:137 Function Call: outFunRet(f1;i1;i1;vi4; (int)
0:137 Convert int to float (float)
0:137 'i' (int)
0:137 'tempArg' (out int)
0:137 'i' (int)
0:137 'tempArg' (out 4-component vector of int)
0:137 move second child to first child (float)
0:137 'f' (float)
0:137 Convert int to float (float)
0:137 'tempArg' (out int)
0:137 move second child to first child (4-component vector of float)
0:137 'v4' (4-component vector of float)
0:137 Convert int to float (4-component vector of float)
0:137 'tempArg' (out 4-component vector of int)
0:137 'tempReturn' (int)
0:138 Sequence
0:138 move second child to first child (2-component vector of float)
0:138 'ret2' (2-component vector of float)
0:138 Convert int to float (2-component vector of float)
0:138 Comma (2-component vector of int)
0:138 move second child to first child (2-component vector of int)
0:138 'tempReturn' (2-component vector of int)
0:138 Function Call: outFunRet(f1;vi4;i1;vi4; (2-component vector of int)
0:138 Convert int to float (float)
0:138 'i' (int)
0:138 'tempArg' (out 4-component vector of int)
0:138 'i' (int)
0:138 'tempArg' (out 4-component vector of int)
0:138 move second child to first child (4-component vector of float)
0:138 'v4' (4-component vector of float)
0:138 Convert int to float (4-component vector of float)
0:138 'tempArg' (out 4-component vector of int)
0:138 move second child to first child (4-component vector of float)
0:138 'v4' (4-component vector of float)
0:138 Convert int to float (4-component vector of float)
0:138 'tempArg' (out 4-component vector of int)
0:138 'tempReturn' (2-component vector of int)
0:? Linker Objects
0:? 'i' (in 4-component vector of float)
0:? 'o' (smooth out 4-component vector of float)
......
......@@ -74,8 +74,7 @@ enum TStorageQualifier {
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter
EvqInOut,
EvqConstReadOnly, // read-only types, not having a constant value or constant-value semantics
EvqConstReadOnly, // input; also other read-only types having neither a constant value nor constant-value semantics
// built-ins read by vertex shader
EvqVertexId,
......
......@@ -238,9 +238,15 @@ class TQualifier {
public:
void clear()
{
storage = EvqTemporary;
precision = EpqNone;
invariant = false;
makeTemporary();
}
// drop qualifiers that don't belong in a temporary variable
void makeTemporary()
{
storage = EvqTemporary;
centroid = false;
smooth = false;
flat = false;
......@@ -255,6 +261,7 @@ public:
writeonly = false;
clearLayout();
}
TStorageQualifier storage : 6;
TPrecisionQualifier precision : 3;
bool invariant : 1;
......@@ -314,6 +321,29 @@ public:
}
}
bool isParamInput() const
{
switch (storage) {
case EvqIn:
case EvqInOut:
case EvqConstReadOnly:
return true;
default:
return false;
}
}
bool isParamOutput() const
{
switch (storage) {
case EvqOut:
case EvqInOut:
return true;
default:
return false;
}
}
bool isUniform() const
{
switch (storage) {
......
......@@ -247,7 +247,7 @@ enum TOperator {
//
EOpConstructGuardStart,
EOpConstructInt,
EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
EOpConstructUint,
EOpConstructBool,
EOpConstructFloat,
......
......@@ -67,6 +67,11 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
return node;
}
TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, TSourceLoc loc)
{
return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), loc);
}
//
// Connect two nodes with a new parent that does a binary operation on the nodes.
//
......@@ -363,14 +368,16 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
}
//
// Convert one type to another.
// Convert the node's type to the given type, as allowed by the operation involved 'op'.
// For implicit conversions, 'op' is not the requested conversion, it is the explicit
// operation requiring the implicit conversion.
//
// Returns the node representing the conversion, which could be the same
// node passed in if no conversion was needed.
//
// Return 0 if a conversion can't be done.
//
TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node)
TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const
{
//
// Does the base type allow operation?
......@@ -490,88 +497,86 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
return 0;
}
if (node->getAsConstantUnion()) {
if (node->getAsConstantUnion())
return promoteConstantUnion(promoteTo, node->getAsConstantUnion());
} else {
//
// Add a new newNode for the conversion.
//
TIntermUnary* newNode = 0;
TOperator newOp = EOpNull;
//
// Add a new newNode for the conversion.
//
TIntermUnary* newNode = 0;
// This is 'mechanism' here, it does any conversion told. The policy comes
// from the shader or the above code.
switch (promoteTo) {
case EbtDouble:
//switch (node->getBasicType()) {
//case EbtInt: newOp = EOpConvIntToDouble; break;
//case EbtUint: newOp = EOpConvUintToDouble; break;
//case EbtBool: newOp = EOpConvBoolToDouble; break;
//case EbtFloat: newOp = EOpConvFloatToDouble; break;
//default:
return 0;
//}
break;
case EbtFloat:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtUint: newOp = EOpConvUintToFloat; break;
case EbtBool: newOp = EOpConvBoolToFloat; break;
case EbtDouble: newOp = EOpConvDoubleToFloat; break;
default:
return 0;
}
break;
case EbtBool:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToBool; break;
case EbtUint: newOp = EOpConvUintToBool; break;
case EbtFloat: newOp = EOpConvFloatToBool; break;
case EbtDouble: newOp = EOpConvDoubleToBool; break;
default:
return 0;
}
break;
case EbtInt:
switch (node->getBasicType()) {
case EbtUint: newOp = EOpConvUintToInt; break;
case EbtBool: newOp = EOpConvBoolToInt; break;
case EbtFloat: newOp = EOpConvFloatToInt; break;
case EbtDouble: newOp = EOpConvDoubleToInt; break;
default:
return 0;
}
break;
case EbtUint:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToUint; break;
case EbtBool: newOp = EOpConvBoolToUint; break;
case EbtFloat: newOp = EOpConvFloatToUint; break;
case EbtDouble: newOp = EOpConvDoubleToUint; break;
default:
return 0;
}
break;
default:
TOperator newOp = EOpNull;
// This is 'mechanism' here, it does any conversion told. The policy comes
// from the shader or the above code.
switch (promoteTo) {
case EbtDouble:
//switch (node->getBasicType()) {
//case EbtInt: newOp = EOpConvIntToDouble; break;
//case EbtUint: newOp = EOpConvUintToDouble; break;
//case EbtBool: newOp = EOpConvBoolToDouble; break;
//case EbtFloat: newOp = EOpConvFloatToDouble; break;
//default:
return 0;
//}
break;
case EbtFloat:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtUint: newOp = EOpConvUintToFloat; break;
case EbtBool: newOp = EOpConvBoolToFloat; break;
case EbtDouble: newOp = EOpConvDoubleToFloat; break;
default:
return 0;
}
break;
case EbtBool:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToBool; break;
case EbtUint: newOp = EOpConvUintToBool; break;
case EbtFloat: newOp = EOpConvFloatToBool; break;
case EbtDouble: newOp = EOpConvDoubleToBool; break;
default:
return 0;
}
break;
case EbtInt:
switch (node->getBasicType()) {
case EbtUint: newOp = EOpConvUintToInt; break;
case EbtBool: newOp = EOpConvBoolToInt; break;
case EbtFloat: newOp = EOpConvFloatToInt; break;
case EbtDouble: newOp = EOpConvDoubleToInt; break;
default:
return 0;
}
break;
case EbtUint:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToUint; break;
case EbtBool: newOp = EOpConvBoolToUint; break;
case EbtFloat: newOp = EOpConvFloatToUint; break;
case EbtDouble: newOp = EOpConvDoubleToUint; break;
default:
return 0;
}
break;
default:
return 0;
}
TType type(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
newNode = new TIntermUnary(newOp, type);
newNode->setLoc(node->getLoc());
newNode->setOperand(node);
TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
newNode = new TIntermUnary(newOp, newType);
newNode->setLoc(node->getLoc());
newNode->setOperand(node);
return newNode;
}
return newNode;
}
//
// See if the 'from' type is allowed to be implicitly converted to the
// 'to' type. This is not about vector/array/struct, only about basic type.
//
bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to)
bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to) const
{
if (profile == EEsProfile || version == 110)
return false;
......@@ -713,8 +718,7 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
TIntermTyped *commaAggregate = growAggregate(left, right, loc);
commaAggregate->getAsAggregate()->setOperator(EOpComma);
commaAggregate->setType(right->getType());
commaAggregate->getWritableType().getQualifier().storage = EvqTemporary;
commaAggregate->getWritableType().getQualifier().precision = right->getType().getQualifier().precision;
commaAggregate->getWritableType().getQualifier().makeTemporary();
return commaAggregate;
}
......@@ -782,7 +786,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Returns the constant union node created.
//
TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, TSourceLoc loc, bool literal)
TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, TSourceLoc loc, bool literal) const
{
TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
node->setLoc(loc);
......@@ -1028,7 +1032,7 @@ bool TIntermUnary::promote()
}
setType(operand->getType());
getWritableType().getQualifier().storage = EvqTemporary;
getWritableType().getQualifier().makeTemporary();
return true;
}
......@@ -1412,7 +1416,7 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
}
}
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const
{
const TConstUnionArray& rightUnionArray = node->getConstArray();
int size = node->getType().computeNumComponents();
......
......@@ -98,8 +98,9 @@ public:
TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&);
TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*);
TIntermTyped* handleLengthMethod(TSourceLoc, TFunction*, TIntermNode*);
TIntermTyped* handleArgumentConversions(const TFunction&, TIntermAggregate&) const;
void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate&);
TFunction* handleConstructorCall(TSourceLoc, TPublicType&);
TFunction* handleConstructorCall(TSourceLoc, const TPublicType&);
bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&);
void assignError(TSourceLoc, const char* op, TString left, TString right);
......@@ -205,11 +206,12 @@ public:
protected:
void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type);
void inheritGlobalDefaults(TQualifier& dst) const;
TVariable* makeInternalVariable(const char* name, const TType&) const;
TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration);
void declareArray(TSourceLoc, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration);
TIntermNode* executeInitializer(TSourceLoc, TString& identifier, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(TSourceLoc, const TType&, TIntermTyped* initializer);
TOperator mapTypeToConstructorOp(const TType&);
TOperator mapTypeToConstructorOp(const TType&) const;
void finalErrorCheck();
public:
......
......@@ -502,6 +502,12 @@ public:
table.pop_back();
}
//
// Insert a visible symbol into the symbol table so it can
// be found later by name.
//
// Returns false if the was a name collision.
//
bool insert(TSymbol& symbol)
{
symbol.setUniqueId(++uniqueId);
......@@ -524,6 +530,17 @@ public:
}
//
// To allocate an internal temporary, which will need to be uniquely
// identified by the consumer of the AST, but never need to
// found by doing a symbol table search by name, hence allowed an
// arbitrary name in the symbol with no worry of collision.
//
void makeInternalVariable(TSymbol& symbol)
{
symbol.setUniqueId(++uniqueId);
}
//
// Copy a variable or anonymous member's structure from a shared level up
// to the current level, so it can be modified without impacting other users
// of the shared table.
......
......@@ -102,6 +102,7 @@ struct TXfbBuffer {
class TSymbolTable;
class TSymbol;
class TVariable;
//
// Set of helper functions to help parse and build the tree.
......@@ -133,13 +134,14 @@ public:
bool isRecursive() const { return recursive; }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
TIntermSymbol* addSymbol(const TVariable&, TSourceLoc);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
TIntermTyped* addUnaryMath(TOperator, TIntermNode* child, TSourceLoc);
TIntermTyped* addBuiltInFunctionCall(TSourceLoc line, TOperator, bool unary, TIntermNode*, const TType& returnType);
bool canImplicitlyPromote(TBasicType from, TBasicType to);
bool canImplicitlyPromote(TBasicType from, TBasicType to) const;
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc);
TIntermAggregate* makeAggregate(TIntermNode* node);
......@@ -150,8 +152,8 @@ public:
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, TSourceLoc);
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc, bool literal = false);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc, bool literal = false) const;
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
TIntermBranch* addBranch(TOperator, TSourceLoc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment