Commit 7c0ec1ef by Nicolas Capens Committed by Nicolas Capens

Produce constructors instead of conversions.

GLSL only supports explicit conversion through constructors. Therefore the conversion nodes are redundant. BUG=15415045 Change-Id: Ia6bd93c9c4a69d013a4ec82f81826e6ff5c18eb2 Reviewed-on: https://swiftshader-review.googlesource.com/1113Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent c3bfb403
...@@ -176,24 +176,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -176,24 +176,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
default: break; default: break;
} }
// if (left->getBasicType() != right->getBasicType())
// First try converting the children to compatible types. {
//
if (left->getType().getStruct() && right->getType().getStruct()) {
if (left->getType() != right->getType())
return 0;
} else {
TIntermTyped* child = addConversion(op, left->getType(), right);
if (child)
right = child;
else {
child = addConversion(op, right->getType(), left);
if (child)
left = child;
else
return 0; return 0;
} }
}
// //
// Need a new node holding things together then. Make // Need a new node holding things together then. Make
...@@ -212,11 +198,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -212,11 +198,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
// //
// See if we can fold constants. // See if we can fold constants.
// //
TIntermTyped* typedReturnNode = 0;
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
if (leftTempConstant && rightTempConstant) { if (leftTempConstant && rightTempConstant) {
typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink); TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
if (typedReturnNode) if (typedReturnNode)
return typedReturnNode; return typedReturnNode;
...@@ -232,21 +217,21 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -232,21 +217,21 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
// //
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line) TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
{ {
// if (left->getType().getStruct() || right->getType().getStruct())
// Like adding binary math, except the conversion can only go {
// from right to left. if (left->getType() != right->getType())
// {
return 0;
}
}
TIntermBinary* node = new TIntermBinary(op); TIntermBinary* node = new TIntermBinary(op);
if (line == 0) if(line == 0)
line = left->getLine(); line = left->getLine();
node->setLine(line); node->setLine(line);
TIntermTyped* child = addConversion(op, left->getType(), right);
if (child == 0)
return 0;
node->setLeft(left); node->setLeft(left);
node->setRight(child); node->setRight(right);
if (! node->promote(infoSink)) if (! node->promote(infoSink))
return 0; return 0;
...@@ -306,40 +291,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, ...@@ -306,40 +291,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
default: break; default: break;
} }
//
// Do we need to promote the operand?
//
// Note: Implicit promotions were removed from the language.
//
TBasicType newType = EbtVoid;
switch (op) {
case EOpConstructInt: newType = EbtInt; break;
case EOpConstructBool: newType = EbtBool; break;
case EOpConstructFloat: newType = EbtFloat; break;
default: break;
}
if (newType != EbtVoid) {
child = addConversion(op, TType(newType, child->getPrecision(), EvqTemporary,
child->getNominalSize(),
child->isMatrix(),
child->isArray()),
child);
if (child == 0)
return 0;
}
//
// For constructors, we are now done, it's all in the conversion.
//
switch (op) {
case EOpConstructInt:
case EOpConstructBool:
case EOpConstructFloat:
return child;
default: break;
}
TIntermConstantUnion *childTempConstant = 0; TIntermConstantUnion *childTempConstant = 0;
if (child->getAsConstantUnion()) if (child->getAsConstantUnion())
childTempConstant = child->getAsConstantUnion(); childTempConstant = child->getAsConstantUnion();
...@@ -625,17 +576,8 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T ...@@ -625,17 +576,8 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
// //
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line) TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
{ {
// if (trueBlock->getType() != falseBlock->getType())
// Get compatible types. {
//
TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
if (child)
falseBlock = child;
else {
child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
if (child)
trueBlock = child;
else
return 0; return 0;
} }
...@@ -809,6 +751,7 @@ bool TIntermOperator::isConstructor() const ...@@ -809,6 +751,7 @@ bool TIntermOperator::isConstructor() const
return false; return false;
} }
} }
// //
// Make sure the type of a unary operator is appropriate for its // Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type. // combination of operation and operand type.
...@@ -869,7 +812,9 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -869,7 +812,9 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
// GLSL ES 2.0 does not support implicit type casting. // GLSL ES 2.0 does not support implicit type casting.
// So the basic type should always match. // So the basic type should always match.
if (left->getBasicType() != right->getBasicType()) if (left->getBasicType() != right->getBasicType())
{
return false; return false;
}
// //
// Base assumption: just make the type the same as the left // Base assumption: just make the type the same as the left
......
...@@ -74,7 +74,6 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV ...@@ -74,7 +74,6 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
fields.offsets[i] = 2; fields.offsets[i] = 2;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
case 'w': case 'w':
fields.offsets[i] = 3; fields.offsets[i] = 3;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
...@@ -1101,81 +1100,40 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode) ...@@ -1101,81 +1100,40 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
// //
// Returns 0 for an error or the constructed node (aggregate or typed) for no error. // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
// //
TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line) TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
{ {
if (node == 0) TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
return 0;
TIntermAggregate* aggrNode = node->getAsAggregate();
TTypeList::const_iterator memberTypes;
if (op == EOpConstructStruct)
memberTypes = type->getStruct()->begin();
TType elementType = *type;
if (type->isArray())
elementType.clearArrayness();
bool singleArg;
if (aggrNode) {
if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
singleArg = true;
else
singleArg = false;
} else
singleArg = true;
TIntermTyped *newNode;
if (singleArg) {
// If structure constructor or array constructor is being called
// for only one parameter inside the structure, we need to call constructStruct function once.
if (type->isArray())
newNode = constructStruct(node, &elementType, 1, node->getLine(), false);
else if (op == EOpConstructStruct)
newNode = constructStruct(node, (*memberTypes).type, 1, node->getLine(), false);
else
newNode = constructBuiltIn(type, op, node, node->getLine(), false);
if (newNode && newNode->getAsAggregate()) { if(!aggregateArguments)
TIntermTyped* constConstructor = foldConstConstructor(newNode->getAsAggregate(), *type); {
if (constConstructor) aggregateArguments = new TIntermAggregate;
return constConstructor; aggregateArguments->getSequence().push_back(arguments);
} }
return newNode; if(op == EOpConstructStruct)
} {
TTypeList &fields = *type->getStruct();
TIntermSequence &args = aggregateArguments->getSequence();
// for(size_t i = 0; i < fields.size(); i++)
// Handle list of arguments. {
// if(args[i]->getAsTyped()->getType() != *fields[i].type)
TIntermSequence &sequenceVector = aggrNode->getSequence() ; // Stores the information about the parameter to the constructor {
// if the structure constructor contains more than one parameter, then construct error(line, "Structure constructor arguments do not match structure fields", "Error");
// each parameter recover();
int paramCount = 0; // keeps a track of the constructor parameter number being checked
// for each parameter to the constructor call, check to see if the right type is passed or convert them
// to the right type if possible (and allowed).
// for structure constructors, just check if the right type is passed, no conversion is allowed.
for (TIntermSequence::iterator p = sequenceVector.begin();
p != sequenceVector.end(); p++, paramCount++) {
if (type->isArray())
newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
else if (op == EOpConstructStruct)
newNode = constructStruct(*p, (memberTypes[paramCount]).type, paramCount+1, node->getLine(), true);
else
newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
if (newNode) { return 0;
*p = newNode; }
} }
} }
TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, line); // Turn the argument list itself into a constructor
TIntermTyped* constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type); TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
if (constConstructor) TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
if(constConstructor)
{
return constConstructor; return constConstructor;
}
return constructor; return constructor;
} }
......
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