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
default: break;
}
//
// 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
if (left->getBasicType() != right->getBasicType())
{
return 0;
}
}
//
// Need a new node holding things together then. Make
......@@ -212,11 +198,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
//
// See if we can fold constants.
//
TIntermTyped* typedReturnNode = 0;
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
if (leftTempConstant && rightTempConstant) {
typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
if (typedReturnNode)
return typedReturnNode;
......@@ -232,21 +217,21 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
//
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
{
//
// Like adding binary math, except the conversion can only go
// from right to left.
//
if (left->getType().getStruct() || right->getType().getStruct())
{
if (left->getType() != right->getType())
{
return 0;
}
}
TIntermBinary* node = new TIntermBinary(op);
if (line == 0)
if(line == 0)
line = left->getLine();
node->setLine(line);
TIntermTyped* child = addConversion(op, left->getType(), right);
if (child == 0)
return 0;
node->setLeft(left);
node->setRight(child);
node->setRight(right);
if (! node->promote(infoSink))
return 0;
......@@ -306,40 +291,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
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;
if (child->getAsConstantUnion())
childTempConstant = child->getAsConstantUnion();
......@@ -625,17 +576,8 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
//
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
{
//
// 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
if (trueBlock->getType() != falseBlock->getType())
{
return 0;
}
......@@ -809,6 +751,7 @@ bool TIntermOperator::isConstructor() const
return false;
}
}
//
// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
......@@ -869,7 +812,9 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
// GLSL ES 2.0 does not support implicit type casting.
// So the basic type should always match.
if (left->getBasicType() != right->getBasicType())
{
return false;
}
//
// Base assumption: just make the type the same as the left
......
......@@ -74,7 +74,6 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
fields.offsets[i] = 2;
fieldSet[i] = estpq;
break;
case 'w':
fields.offsets[i] = 3;
fieldSet[i] = exyzw;
......@@ -1101,81 +1100,40 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
//
// 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)
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);
TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
if (newNode && newNode->getAsAggregate()) {
TIntermTyped* constConstructor = foldConstConstructor(newNode->getAsAggregate(), *type);
if (constConstructor)
return constConstructor;
if(!aggregateArguments)
{
aggregateArguments = new TIntermAggregate;
aggregateArguments->getSequence().push_back(arguments);
}
return newNode;
}
if(op == EOpConstructStruct)
{
TTypeList &fields = *type->getStruct();
TIntermSequence &args = aggregateArguments->getSequence();
//
// Handle list of arguments.
//
TIntermSequence &sequenceVector = aggrNode->getSequence() ; // Stores the information about the parameter to the constructor
// if the structure constructor contains more than one parameter, then construct
// each parameter
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);
for(size_t i = 0; i < fields.size(); i++)
{
if(args[i]->getAsTyped()->getType() != *fields[i].type)
{
error(line, "Structure constructor arguments do not match structure fields", "Error");
recover();
if (newNode) {
*p = newNode;
return 0;
}
}
}
TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, line);
TIntermTyped* constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
if (constConstructor)
// Turn the argument list itself into a constructor
TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
if(constConstructor)
{
return constConstructor;
}
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