summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
diff options
context:
space:
mode:
authorAndrew Knight <andrew.knight@digia.com>2014-08-05 12:59:44 +0300
committerAndrew Knight <andrew.knight@digia.com>2014-08-05 16:43:22 +0200
commita6a12d8c0fc918972c15268f749ecc7c90b95d6c (patch)
treecb6d986d30ef97e932ab51768854d5d9b46729d3 /src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
parent14f9c09542bd6cc19430473da9ce4c68f239ec7d (diff)
ANGLE: upgrade to 2.1~07d49ef5350a
This version of ANGLE provides partial ES3 support, numerous bug fixes, and several potentially useful vendor extensions. All patches have been rebased. The following changes are noted: 0000-General-fixes-for-ANGLE-2.1.patch contains compile fixes for the new ANGLE 0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch has incorporated patch 0015. 0007-Make-DX9-DX11-mutually-exclusive.patch has been removed as it was fixed upstream. 0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch has been moved up to fill the patch number gap. 0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch now contains patch 0014 and 0017. 0013-ANGLE-Allow-for-universal-program-binaries.patch has been removed as it is no longer relevant. 0014-ANGLE-D3D11-Fix-internal-index-buffer-for-level-9-ha.patch has been merged with patch 0010. 0015-ANGLE-Don-t-export-DLLMain-functions-for-static-buil.patch has been merged with patch 0004. 0016-ANGLE-WinRT-Call-Trim-when-application-suspends.patch has been removed and will be replaced by a follow-up patch using a different technique. 0017-ANGLE-D3D11-Don-t-use-mipmaps-in-level-9-textures.patch has been merged with patch 0010. 0018-ANGLE-WinRT-Create-swap-chain-using-physical-resolut.patch has been removed and will be replaced by a follow-up patch extending the EGL_ANGLE_window_fixed_size extension. 0019-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch is now patch 0007. [ChangeLog][Third-party libraries] ANGLE has been upgraded to version 2.1, bringing partial support for OpenGL ES3 over Direct3D 11, numerous bug fixes, and several new vendor extensions. Change-Id: I6d95ce1480462d67228d83c1e5c74a1706b5b21c Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp1094
1 files changed, 641 insertions, 453 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
index f2f0a3d6be..7839c04852 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -11,7 +11,7 @@
namespace
{
-TString arrayBrackets(const TType& type)
+TString arrayBrackets(const TType &type)
{
ASSERT(type.isArray());
TInfoSinkBase out;
@@ -19,13 +19,14 @@ TString arrayBrackets(const TType& type)
return TString(out.c_str());
}
-bool isSingleStatement(TIntermNode* node) {
- if (const TIntermAggregate* aggregate = node->getAsAggregate())
+bool isSingleStatement(TIntermNode *node)
+{
+ if (const TIntermAggregate *aggregate = node->getAsAggregate())
{
return (aggregate->getOp() != EOpFunction) &&
(aggregate->getOp() != EOpSequence);
}
- else if (const TIntermSelection* selection = node->getAsSelectionNode())
+ else if (const TIntermSelection *selection = node->getAsSelectionNode())
{
// Ternary operators are usually part of an assignment operator.
// This handles those rare cases in which they are all by themselves.
@@ -39,49 +40,61 @@ bool isSingleStatement(TIntermNode* node) {
}
} // namespace
-TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink,
+TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
- NameMap& nameMap,
- TSymbolTable& symbolTable)
+ NameMap &nameMap,
+ TSymbolTable &symbolTable,
+ int shaderVersion)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
mDeclaringVariables(false),
mClampingStrategy(clampingStrategy),
mHashFunction(hashFunction),
mNameMap(nameMap),
- mSymbolTable(symbolTable)
+ mSymbolTable(symbolTable),
+ mShaderVersion(shaderVersion)
{
}
-void TOutputGLSLBase::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr)
+void TOutputGLSLBase::writeTriplet(
+ Visit visit, const char *preStr, const char *inStr, const char *postStr)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
if (visit == PreVisit && preStr)
- {
out << preStr;
- }
else if (visit == InVisit && inStr)
- {
out << inStr;
- }
else if (visit == PostVisit && postStr)
- {
out << postStr;
- }
}
-void TOutputGLSLBase::writeVariableType(const TType& type)
+void TOutputGLSLBase::writeBuiltInFunctionTriplet(
+ Visit visit, const char *preStr, bool useEmulatedFunction)
+{
+ TString preString = useEmulatedFunction ?
+ BuiltInFunctionEmulator::GetEmulatedFunctionName(preStr) : preStr;
+ writeTriplet(visit, preString.c_str(), ", ", ")");
+}
+
+void TOutputGLSLBase::writeVariableType(const TType &type)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
TQualifier qualifier = type.getQualifier();
// TODO(alokp): Validate qualifier for variable declarations.
- if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
+ if (qualifier != EvqTemporary && qualifier != EvqGlobal)
out << type.getQualifierString() << " ";
// Declare the struct if we have not done so already.
- if ((type.getBasicType() == EbtStruct) && !structDeclared(type.getStruct()))
+ if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
{
- declareStruct(type.getStruct());
+ TStructure *structure = type.getStruct();
+
+ declareStruct(structure);
+
+ if (!structure->name().empty())
+ {
+ mDeclaredStructs.insert(structure->uniqueId());
+ }
}
else
{
@@ -91,19 +104,19 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
}
}
-void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args)
+void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
for (TIntermSequence::const_iterator iter = args.begin();
iter != args.end(); ++iter)
{
- const TIntermSymbol* arg = (*iter)->getAsSymbolNode();
+ const TIntermSymbol *arg = (*iter)->getAsSymbolNode();
ASSERT(arg != NULL);
- const TType& type = arg->getType();
+ const TType &type = arg->getType();
writeVariableType(type);
- const TString& name = arg->getSymbol();
+ const TString &name = arg->getSymbol();
if (!name.empty())
out << " " << hashName(name);
if (type.isArray())
@@ -115,23 +128,24 @@ void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args)
}
}
-const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
- const ConstantUnion* pConstUnion)
+const ConstantUnion *TOutputGLSLBase::writeConstantUnion(
+ const TType &type, const ConstantUnion *pConstUnion)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
if (type.getBasicType() == EbtStruct)
{
- const TStructure* structure = type.getStruct();
+ const TStructure *structure = type.getStruct();
out << hashName(structure->name()) << "(";
- const TFieldList& fields = structure->fields();
+ const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
- const TType* fieldType = fields[i]->type();
+ const TType *fieldType = fields[i]->type();
ASSERT(fieldType != NULL);
pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
- if (i != fields.size() - 1) out << ", ";
+ if (i != fields.size() - 1)
+ out << ", ";
}
out << ")";
}
@@ -139,28 +153,37 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
{
size_t size = type.getObjectSize();
bool writeType = size > 1;
- if (writeType) out << getTypeName(type) << "(";
+ if (writeType)
+ out << getTypeName(type) << "(";
for (size_t i = 0; i < size; ++i, ++pConstUnion)
{
switch (pConstUnion->getType())
{
- case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion->getFConst())); break;
- case EbtInt: out << pConstUnion->getIConst(); break;
- case EbtBool: out << pConstUnion->getBConst(); break;
- default: UNREACHABLE();
+ case EbtFloat:
+ out << std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion->getFConst()));
+ break;
+ case EbtInt:
+ out << pConstUnion->getIConst();
+ break;
+ case EbtBool:
+ out << pConstUnion->getBConst();
+ break;
+ default: UNREACHABLE();
}
- if (i != size - 1) out << ", ";
+ if (i != size - 1)
+ out << ", ";
}
- if (writeType) out << ")";
+ if (writeType)
+ out << ")";
}
return pConstUnion;
}
-void TOutputGLSLBase::visitSymbol(TIntermSymbol* node)
+void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
{
- TInfoSinkBase& out = objSink();
- if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
- out << mLoopUnroll.GetLoopIndexValue(node);
+ TInfoSinkBase &out = objSink();
+ if (mLoopUnrollStack.needsToReplaceSymbolWithValue(node))
+ out << mLoopUnrollStack.getLoopIndexValue(node);
else
out << hashVariableName(node->getSymbol());
@@ -168,240 +191,303 @@ void TOutputGLSLBase::visitSymbol(TIntermSymbol* node)
out << arrayBrackets(node->getType());
}
-void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion* node)
+void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node)
{
writeConstantUnion(node->getType(), node->getUnionArrayPointer());
}
-bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
+bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
{
bool visitChildren = true;
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
switch (node->getOp())
{
- case EOpInitialize:
+ case EOpInitialize:
+ if (visit == InVisit)
+ {
+ out << " = ";
+ // RHS of initialize is not being declared.
+ mDeclaringVariables = false;
+ }
+ break;
+ case EOpAssign:
+ writeTriplet(visit, "(", " = ", ")");
+ break;
+ case EOpAddAssign:
+ writeTriplet(visit, "(", " += ", ")");
+ break;
+ case EOpSubAssign:
+ writeTriplet(visit, "(", " -= ", ")");
+ break;
+ case EOpDivAssign:
+ writeTriplet(visit, "(", " /= ", ")");
+ break;
+ // Notice the fall-through.
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ writeTriplet(visit, "(", " *= ", ")");
+ break;
+
+ case EOpIndexDirect:
+ writeTriplet(visit, NULL, "[", "]");
+ break;
+ case EOpIndexIndirect:
+ if (node->getAddIndexClamp())
+ {
if (visit == InVisit)
{
- out << " = ";
- // RHS of initialize is not being declared.
- mDeclaringVariables = false;
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
+ out << "[int(clamp(float(";
+ else
+ out << "[webgl_int_clamp(";
}
- break;
- case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break;
- case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break;
- case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break;
- case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break;
- // Notice the fall-through.
- case EOpMulAssign:
- case EOpVectorTimesMatrixAssign:
- case EOpVectorTimesScalarAssign:
- case EOpMatrixTimesScalarAssign:
- case EOpMatrixTimesMatrixAssign:
- writeTriplet(visit, "(", " *= ", ")");
- break;
-
- case EOpIndexDirect:
- writeTriplet(visit, NULL, "[", "]");
- break;
- case EOpIndexIndirect:
- if (node->getAddIndexClamp())
+ else if (visit == PostVisit)
{
- if (visit == InVisit)
+ int maxSize;
+ TIntermTyped *left = node->getLeft();
+ TType leftType = left->getType();
+
+ if (left->isArray())
{
- if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
- out << "[int(clamp(float(";
- } else {
- out << "[webgl_int_clamp(";
- }
+ // The shader will fail validation if the array length is not > 0.
+ maxSize = leftType.getArraySize() - 1;
}
- else if (visit == PostVisit)
+ else
{
- int maxSize;
- TIntermTyped *left = node->getLeft();
- TType leftType = left->getType();
-
- if (left->isArray())
- {
- // The shader will fail validation if the array length is not > 0.
- maxSize = leftType.getArraySize() - 1;
- }
- else
- {
- maxSize = leftType.getNominalSize() - 1;
- }
-
- if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
- out << "), 0.0, float(" << maxSize << ")))]";
- } else {
- out << ", 0, " << maxSize << ")]";
- }
+ maxSize = leftType.getNominalSize() - 1;
}
+
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
+ out << "), 0.0, float(" << maxSize << ")))]";
+ else
+ out << ", 0, " << maxSize << ")]";
}
- else
- {
- writeTriplet(visit, NULL, "[", "]");
- }
- break;
- case EOpIndexDirectStruct:
- if (visit == InVisit)
- {
- // Here we are writing out "foo.bar", where "foo" is struct
- // and "bar" is field. In AST, it is represented as a binary
- // node, where left child represents "foo" and right child "bar".
- // The node itself represents ".". The struct field "bar" is
- // actually stored as an index into TStructure::fields.
- out << ".";
- const TStructure* structure = node->getLeft()->getType().getStruct();
- const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
- const TField* field = structure->fields()[index->getIConst(0)];
-
- TString fieldName = field->name();
- if (!mSymbolTable.findBuiltIn(structure->name()))
- fieldName = hashName(fieldName);
-
- out << fieldName;
- visitChildren = false;
- }
- break;
- case EOpVectorSwizzle:
- if (visit == InVisit)
+ }
+ else
+ {
+ writeTriplet(visit, NULL, "[", "]");
+ }
+ break;
+ case EOpIndexDirectStruct:
+ if (visit == InVisit)
+ {
+ // Here we are writing out "foo.bar", where "foo" is struct
+ // and "bar" is field. In AST, it is represented as a binary
+ // node, where left child represents "foo" and right child "bar".
+ // The node itself represents ".". The struct field "bar" is
+ // actually stored as an index into TStructure::fields.
+ out << ".";
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+
+ TString fieldName = field->name();
+ if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion))
+ fieldName = hashName(fieldName);
+
+ out << fieldName;
+ visitChildren = false;
+ }
+ break;
+ case EOpVectorSwizzle:
+ if (visit == InVisit)
+ {
+ out << ".";
+ TIntermAggregate *rightChild = node->getRight()->getAsAggregate();
+ TIntermSequence *sequence = rightChild->getSequence();
+ for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); ++sit)
{
- out << ".";
- TIntermAggregate* rightChild = node->getRight()->getAsAggregate();
- TIntermSequence& sequence = rightChild->getSequence();
- for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
+ TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
+ ASSERT(element->getBasicType() == EbtInt);
+ ASSERT(element->getNominalSize() == 1);
+ const ConstantUnion& data = element->getUnionArrayPointer()[0];
+ ASSERT(data.getType() == EbtInt);
+ switch (data.getIConst())
{
- TIntermConstantUnion* element = (*sit)->getAsConstantUnion();
- ASSERT(element->getBasicType() == EbtInt);
- ASSERT(element->getNominalSize() == 1);
- const ConstantUnion& data = element->getUnionArrayPointer()[0];
- ASSERT(data.getType() == EbtInt);
- switch (data.getIConst())
- {
- case 0: out << "x"; break;
- case 1: out << "y"; break;
- case 2: out << "z"; break;
- case 3: out << "w"; break;
- default: UNREACHABLE(); break;
- }
+ case 0:
+ out << "x";
+ break;
+ case 1:
+ out << "y";
+ break;
+ case 2:
+ out << "z";
+ break;
+ case 3:
+ out << "w";
+ break;
+ default:
+ UNREACHABLE();
}
- visitChildren = false;
}
- break;
-
- case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break;
- case EOpSub: writeTriplet(visit, "(", " - ", ")"); break;
- case EOpMul: writeTriplet(visit, "(", " * ", ")"); break;
- case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break;
- case EOpMod: UNIMPLEMENTED(); break;
- case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break;
- case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break;
- case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break;
- case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break;
- case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break;
- case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break;
-
- // Notice the fall-through.
- case EOpVectorTimesScalar:
- case EOpVectorTimesMatrix:
- case EOpMatrixTimesVector:
- case EOpMatrixTimesScalar:
- case EOpMatrixTimesMatrix:
- writeTriplet(visit, "(", " * ", ")");
- break;
-
- case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break;
- case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break;
- case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break;
- default: UNREACHABLE(); break;
+ visitChildren = false;
+ }
+ break;
+
+ case EOpAdd:
+ writeTriplet(visit, "(", " + ", ")");
+ break;
+ case EOpSub:
+ writeTriplet(visit, "(", " - ", ")");
+ break;
+ case EOpMul:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
+ case EOpDiv:
+ writeTriplet(visit, "(", " / ", ")");
+ break;
+ case EOpMod:
+ UNIMPLEMENTED();
+ break;
+ case EOpEqual:
+ writeTriplet(visit, "(", " == ", ")");
+ break;
+ case EOpNotEqual:
+ writeTriplet(visit, "(", " != ", ")");
+ break;
+ case EOpLessThan:
+ writeTriplet(visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThan:
+ writeTriplet(visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqual:
+ writeTriplet(visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqual:
+ writeTriplet(visit, "(", " >= ", ")");
+ break;
+
+ // Notice the fall-through.
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
+
+ case EOpLogicalOr:
+ writeTriplet(visit, "(", " || ", ")");
+ break;
+ case EOpLogicalXor:
+ writeTriplet(visit, "(", " ^^ ", ")");
+ break;
+ case EOpLogicalAnd:
+ writeTriplet(visit, "(", " && ", ")");
+ break;
+ default:
+ UNREACHABLE();
}
return visitChildren;
}
-bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary* node)
+bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
{
TString preString;
TString postString = ")";
switch (node->getOp())
{
- case EOpNegative: preString = "(-"; break;
- case EOpVectorLogicalNot: preString = "not("; break;
- case EOpLogicalNot: preString = "(!"; break;
-
- case EOpPostIncrement: preString = "("; postString = "++)"; break;
- case EOpPostDecrement: preString = "("; postString = "--)"; break;
- case EOpPreIncrement: preString = "(++"; break;
- case EOpPreDecrement: preString = "(--"; break;
-
- case EOpConvIntToBool:
- case EOpConvFloatToBool:
- switch (node->getOperand()->getType().getNominalSize())
- {
- case 1: preString = "bool("; break;
- case 2: preString = "bvec2("; break;
- case 3: preString = "bvec3("; break;
- case 4: preString = "bvec4("; break;
- default: UNREACHABLE();
- }
- break;
- case EOpConvBoolToFloat:
- case EOpConvIntToFloat:
- switch (node->getOperand()->getType().getNominalSize())
- {
- case 1: preString = "float("; break;
- case 2: preString = "vec2("; break;
- case 3: preString = "vec3("; break;
- case 4: preString = "vec4("; break;
- default: UNREACHABLE();
- }
- break;
- case EOpConvFloatToInt:
- case EOpConvBoolToInt:
- switch (node->getOperand()->getType().getNominalSize())
- {
- case 1: preString = "int("; break;
- case 2: preString = "ivec2("; break;
- case 3: preString = "ivec3("; break;
- case 4: preString = "ivec4("; break;
- default: UNREACHABLE();
- }
- break;
-
- case EOpRadians: preString = "radians("; break;
- case EOpDegrees: preString = "degrees("; break;
- case EOpSin: preString = "sin("; break;
- case EOpCos: preString = "cos("; break;
- case EOpTan: preString = "tan("; break;
- case EOpAsin: preString = "asin("; break;
- case EOpAcos: preString = "acos("; break;
- case EOpAtan: preString = "atan("; break;
-
- case EOpExp: preString = "exp("; break;
- case EOpLog: preString = "log("; break;
- case EOpExp2: preString = "exp2("; break;
- case EOpLog2: preString = "log2("; break;
- case EOpSqrt: preString = "sqrt("; break;
- case EOpInverseSqrt: preString = "inversesqrt("; break;
-
- case EOpAbs: preString = "abs("; break;
- case EOpSign: preString = "sign("; break;
- case EOpFloor: preString = "floor("; break;
- case EOpCeil: preString = "ceil("; break;
- case EOpFract: preString = "fract("; break;
-
- case EOpLength: preString = "length("; break;
- case EOpNormalize: preString = "normalize("; break;
-
- case EOpDFdx: preString = "dFdx("; break;
- case EOpDFdy: preString = "dFdy("; break;
- case EOpFwidth: preString = "fwidth("; break;
-
- case EOpAny: preString = "any("; break;
- case EOpAll: preString = "all("; break;
-
- default: UNREACHABLE(); break;
+ case EOpNegative: preString = "(-"; break;
+ case EOpVectorLogicalNot: preString = "not("; break;
+ case EOpLogicalNot: preString = "(!"; break;
+
+ case EOpPostIncrement: preString = "("; postString = "++)"; break;
+ case EOpPostDecrement: preString = "("; postString = "--)"; break;
+ case EOpPreIncrement: preString = "(++"; break;
+ case EOpPreDecrement: preString = "(--"; break;
+
+ case EOpRadians:
+ preString = "radians(";
+ break;
+ case EOpDegrees:
+ preString = "degrees(";
+ break;
+ case EOpSin:
+ preString = "sin(";
+ break;
+ case EOpCos:
+ preString = "cos(";
+ break;
+ case EOpTan:
+ preString = "tan(";
+ break;
+ case EOpAsin:
+ preString = "asin(";
+ break;
+ case EOpAcos:
+ preString = "acos(";
+ break;
+ case EOpAtan:
+ preString = "atan(";
+ break;
+
+ case EOpExp:
+ preString = "exp(";
+ break;
+ case EOpLog:
+ preString = "log(";
+ break;
+ case EOpExp2:
+ preString = "exp2(";
+ break;
+ case EOpLog2:
+ preString = "log2(";
+ break;
+ case EOpSqrt:
+ preString = "sqrt(";
+ break;
+ case EOpInverseSqrt:
+ preString = "inversesqrt(";
+ break;
+
+ case EOpAbs:
+ preString = "abs(";
+ break;
+ case EOpSign:
+ preString = "sign(";
+ break;
+ case EOpFloor:
+ preString = "floor(";
+ break;
+ case EOpCeil:
+ preString = "ceil(";
+ break;
+ case EOpFract:
+ preString = "fract(";
+ break;
+
+ case EOpLength:
+ preString = "length(";
+ break;
+ case EOpNormalize:
+ preString = "normalize(";
+ break;
+
+ case EOpDFdx:
+ preString = "dFdx(";
+ break;
+ case EOpDFdy:
+ preString = "dFdy(";
+ break;
+ case EOpFwidth:
+ preString = "fwidth(";
+ break;
+
+ case EOpAny:
+ preString = "any(";
+ break;
+ case EOpAll:
+ preString = "all(";
+ break;
+
+ default:
+ UNREACHABLE();
}
if (visit == PreVisit && node->getUseEmulatedFunction())
@@ -411,9 +497,9 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary* node)
return true;
}
-bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node)
+bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection *node)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
if (node->usesTernaryOperator())
{
@@ -448,202 +534,270 @@ bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node)
return false;
}
-bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
+bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = true;
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
TString preString;
- bool delayedWrite = false;
+ bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction());
switch (node->getOp())
{
- case EOpSequence: {
- // Scope the sequences except when at the global scope.
- if (depth > 0) out << "{\n";
-
- incrementDepth(node);
- const TIntermSequence& sequence = node->getSequence();
- for (TIntermSequence::const_iterator iter = sequence.begin();
- iter != sequence.end(); ++iter)
- {
- TIntermNode* node = *iter;
- ASSERT(node != NULL);
- node->traverse(this);
+ case EOpSequence:
+ // Scope the sequences except when at the global scope.
+ if (mDepth > 0)
+ {
+ out << "{\n";
+ }
- if (isSingleStatement(node))
- out << ";\n";
- }
- decrementDepth();
+ incrementDepth(node);
+ for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+ iter != node->getSequence()->end(); ++iter)
+ {
+ TIntermNode *node = *iter;
+ ASSERT(node != NULL);
+ node->traverse(this);
- // Scope the sequences except when at the global scope.
- if (depth > 0) out << "}\n";
- visitChildren = false;
- break;
+ if (isSingleStatement(node))
+ out << ";\n";
}
- case EOpPrototype: {
- // Function declaration.
- ASSERT(visit == PreVisit);
- writeVariableType(node->getType());
- out << " " << hashName(node->getName());
-
- out << "(";
- writeFunctionParameters(node->getSequence());
- out << ")";
+ decrementDepth();
- visitChildren = false;
- break;
- }
- case EOpFunction: {
- // Function definition.
- ASSERT(visit == PreVisit);
- writeVariableType(node->getType());
- out << " " << hashFunctionName(node->getName());
-
- incrementDepth(node);
- // Function definition node contains one or two children nodes
- // representing function parameters and function body. The latter
- // is not present in case of empty function bodies.
- const TIntermSequence& sequence = node->getSequence();
- ASSERT((sequence.size() == 1) || (sequence.size() == 2));
- TIntermSequence::const_iterator seqIter = sequence.begin();
-
- // Traverse function parameters.
- TIntermAggregate* params = (*seqIter)->getAsAggregate();
- ASSERT(params != NULL);
- ASSERT(params->getOp() == EOpParameters);
- params->traverse(this);
-
- // Traverse function body.
- TIntermAggregate* body = ++seqIter != sequence.end() ?
- (*seqIter)->getAsAggregate() : NULL;
- visitCodeBlock(body);
- decrementDepth();
-
- // Fully processed; no need to visit children.
- visitChildren = false;
- break;
+ // Scope the sequences except when at the global scope.
+ if (mDepth > 0)
+ {
+ out << "}\n";
}
- case EOpFunctionCall:
- // Function call.
- if (visit == PreVisit)
- {
- out << hashFunctionName(node->getName()) << "(";
- }
- else if (visit == InVisit)
- {
- out << ", ";
- }
- else
- {
- out << ")";
- }
- break;
- case EOpParameters: {
- // Function parameters.
- ASSERT(visit == PreVisit);
- out << "(";
- writeFunctionParameters(node->getSequence());
+ visitChildren = false;
+ break;
+ case EOpPrototype:
+ // Function declaration.
+ ASSERT(visit == PreVisit);
+ writeVariableType(node->getType());
+ out << " " << hashName(node->getName());
+
+ out << "(";
+ writeFunctionParameters(*(node->getSequence()));
+ out << ")";
+
+ visitChildren = false;
+ break;
+ case EOpFunction: {
+ // Function definition.
+ ASSERT(visit == PreVisit);
+ writeVariableType(node->getType());
+ out << " " << hashFunctionName(node->getName());
+
+ incrementDepth(node);
+ // Function definition node contains one or two children nodes
+ // representing function parameters and function body. The latter
+ // is not present in case of empty function bodies.
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT((sequence.size() == 1) || (sequence.size() == 2));
+ TIntermSequence::const_iterator seqIter = sequence.begin();
+
+ // Traverse function parameters.
+ TIntermAggregate *params = (*seqIter)->getAsAggregate();
+ ASSERT(params != NULL);
+ ASSERT(params->getOp() == EOpParameters);
+ params->traverse(this);
+
+ // Traverse function body.
+ TIntermAggregate *body = ++seqIter != sequence.end() ?
+ (*seqIter)->getAsAggregate() : NULL;
+ visitCodeBlock(body);
+ decrementDepth();
+
+ // Fully processed; no need to visit children.
+ visitChildren = false;
+ break;
+ }
+ case EOpFunctionCall:
+ // Function call.
+ if (visit == PreVisit)
+ out << hashFunctionName(node->getName()) << "(";
+ else if (visit == InVisit)
+ out << ", ";
+ else
out << ")";
- visitChildren = false;
- break;
+ break;
+ case EOpParameters:
+ // Function parameters.
+ ASSERT(visit == PreVisit);
+ out << "(";
+ writeFunctionParameters(*(node->getSequence()));
+ out << ")";
+ visitChildren = false;
+ break;
+ case EOpDeclaration:
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ const TIntermTyped *variable = sequence.front()->getAsTyped();
+ writeVariableType(variable->getType());
+ out << " ";
+ mDeclaringVariables = true;
}
- case EOpDeclaration: {
- // Variable declaration.
- if (visit == PreVisit)
- {
- const TIntermSequence& sequence = node->getSequence();
- const TIntermTyped* variable = sequence.front()->getAsTyped();
- writeVariableType(variable->getType());
- out << " ";
- mDeclaringVariables = true;
- }
- else if (visit == InVisit)
- {
- out << ", ";
- mDeclaringVariables = true;
- }
- else
- {
- mDeclaringVariables = false;
- }
- break;
+ else if (visit == InVisit)
+ {
+ out << ", ";
+ mDeclaringVariables = true;
}
- case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break;
- case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break;
- case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break;
- case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break;
- case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break;
- case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break;
- case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break;
- case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break;
- case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break;
- case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break;
- case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break;
- case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break;
- case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break;
- case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break;
- case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break;
- case EOpConstructStruct:
- if (visit == PreVisit)
- {
- const TType& type = node->getType();
- ASSERT(type.getBasicType() == EbtStruct);
- out << hashName(type.getStruct()->name()) << "(";
- }
- else if (visit == InVisit)
- {
- out << ", ";
- }
- else
- {
- out << ")";
- }
- break;
-
- case EOpLessThan: preString = "lessThan("; delayedWrite = true; break;
- case EOpGreaterThan: preString = "greaterThan("; delayedWrite = true; break;
- case EOpLessThanEqual: preString = "lessThanEqual("; delayedWrite = true; break;
- case EOpGreaterThanEqual: preString = "greaterThanEqual("; delayedWrite = true; break;
- case EOpVectorEqual: preString = "equal("; delayedWrite = true; break;
- case EOpVectorNotEqual: preString = "notEqual("; delayedWrite = true; break;
- case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break;
-
- case EOpMod: preString = "mod("; delayedWrite = true; break;
- case EOpPow: preString = "pow("; delayedWrite = true; break;
- case EOpAtan: preString = "atan("; delayedWrite = true; break;
- case EOpMin: preString = "min("; delayedWrite = true; break;
- case EOpMax: preString = "max("; delayedWrite = true; break;
- case EOpClamp: preString = "clamp("; delayedWrite = true; break;
- case EOpMix: preString = "mix("; delayedWrite = true; break;
- case EOpStep: preString = "step("; delayedWrite = true; break;
- case EOpSmoothStep: preString = "smoothstep("; delayedWrite = true; break;
-
- case EOpDistance: preString = "distance("; delayedWrite = true; break;
- case EOpDot: preString = "dot("; delayedWrite = true; break;
- case EOpCross: preString = "cross("; delayedWrite = true; break;
- case EOpFaceForward: preString = "faceforward("; delayedWrite = true; break;
- case EOpReflect: preString = "reflect("; delayedWrite = true; break;
- case EOpRefract: preString = "refract("; delayedWrite = true; break;
- case EOpMul: preString = "matrixCompMult("; delayedWrite = true; break;
-
- default: UNREACHABLE(); break;
+ else
+ {
+ mDeclaringVariables = false;
+ }
+ break;
+ case EOpConstructFloat:
+ writeTriplet(visit, "float(", NULL, ")");
+ break;
+ case EOpConstructVec2:
+ writeBuiltInFunctionTriplet(visit, "vec2(", false);
+ break;
+ case EOpConstructVec3:
+ writeBuiltInFunctionTriplet(visit, "vec3(", false);
+ break;
+ case EOpConstructVec4:
+ writeBuiltInFunctionTriplet(visit, "vec4(", false);
+ break;
+ case EOpConstructBool:
+ writeTriplet(visit, "bool(", NULL, ")");
+ break;
+ case EOpConstructBVec2:
+ writeBuiltInFunctionTriplet(visit, "bvec2(", false);
+ break;
+ case EOpConstructBVec3:
+ writeBuiltInFunctionTriplet(visit, "bvec3(", false);
+ break;
+ case EOpConstructBVec4:
+ writeBuiltInFunctionTriplet(visit, "bvec4(", false);
+ break;
+ case EOpConstructInt:
+ writeTriplet(visit, "int(", NULL, ")");
+ break;
+ case EOpConstructIVec2:
+ writeBuiltInFunctionTriplet(visit, "ivec2(", false);
+ break;
+ case EOpConstructIVec3:
+ writeBuiltInFunctionTriplet(visit, "ivec3(", false);
+ break;
+ case EOpConstructIVec4:
+ writeBuiltInFunctionTriplet(visit, "ivec4(", false);
+ break;
+ case EOpConstructMat2:
+ writeBuiltInFunctionTriplet(visit, "mat2(", false);
+ break;
+ case EOpConstructMat3:
+ writeBuiltInFunctionTriplet(visit, "mat3(", false);
+ break;
+ case EOpConstructMat4:
+ writeBuiltInFunctionTriplet(visit, "mat4(", false);
+ break;
+ case EOpConstructStruct:
+ if (visit == PreVisit)
+ {
+ const TType &type = node->getType();
+ ASSERT(type.getBasicType() == EbtStruct);
+ out << hashName(type.getStruct()->name()) << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << ", ";
+ }
+ else
+ {
+ out << ")";
+ }
+ break;
+
+ case EOpLessThan:
+ writeBuiltInFunctionTriplet(visit, "lessThan(", useEmulatedFunction);
+ break;
+ case EOpGreaterThan:
+ writeBuiltInFunctionTriplet(visit, "greaterThan(", useEmulatedFunction);
+ break;
+ case EOpLessThanEqual:
+ writeBuiltInFunctionTriplet(visit, "lessThanEqual(", useEmulatedFunction);
+ break;
+ case EOpGreaterThanEqual:
+ writeBuiltInFunctionTriplet(visit, "greaterThanEqual(", useEmulatedFunction);
+ break;
+ case EOpVectorEqual:
+ writeBuiltInFunctionTriplet(visit, "equal(", useEmulatedFunction);
+ break;
+ case EOpVectorNotEqual:
+ writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
+ break;
+ case EOpComma:
+ writeTriplet(visit, NULL, ", ", NULL);
+ break;
+
+ case EOpMod:
+ writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction);
+ break;
+ case EOpPow:
+ writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction);
+ break;
+ case EOpAtan:
+ writeBuiltInFunctionTriplet(visit, "atan(", useEmulatedFunction);
+ break;
+ case EOpMin:
+ writeBuiltInFunctionTriplet(visit, "min(", useEmulatedFunction);
+ break;
+ case EOpMax:
+ writeBuiltInFunctionTriplet(visit, "max(", useEmulatedFunction);
+ break;
+ case EOpClamp:
+ writeBuiltInFunctionTriplet(visit, "clamp(", useEmulatedFunction);
+ break;
+ case EOpMix:
+ writeBuiltInFunctionTriplet(visit, "mix(", useEmulatedFunction);
+ break;
+ case EOpStep:
+ writeBuiltInFunctionTriplet(visit, "step(", useEmulatedFunction);
+ break;
+ case EOpSmoothStep:
+ writeBuiltInFunctionTriplet(visit, "smoothstep(", useEmulatedFunction);
+ break;
+ case EOpDistance:
+ writeBuiltInFunctionTriplet(visit, "distance(", useEmulatedFunction);
+ break;
+ case EOpDot:
+ writeBuiltInFunctionTriplet(visit, "dot(", useEmulatedFunction);
+ break;
+ case EOpCross:
+ writeBuiltInFunctionTriplet(visit, "cross(", useEmulatedFunction);
+ break;
+ case EOpFaceForward:
+ writeBuiltInFunctionTriplet(visit, "faceforward(", useEmulatedFunction);
+ break;
+ case EOpReflect:
+ writeBuiltInFunctionTriplet(visit, "reflect(", useEmulatedFunction);
+ break;
+ case EOpRefract:
+ writeBuiltInFunctionTriplet(visit, "refract(", useEmulatedFunction);
+ break;
+ case EOpMul:
+ writeBuiltInFunctionTriplet(visit, "matrixCompMult(", useEmulatedFunction);
+ break;
+
+ default:
+ UNREACHABLE();
}
- if (delayedWrite && visit == PreVisit && node->getUseEmulatedFunction())
- preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
- if (delayedWrite)
- writeTriplet(visit, preString.c_str(), ", ", ")");
return visitChildren;
}
-bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node)
+bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
incrementDepth(node);
// Loop header.
TLoopType loopType = node->getType();
if (loopType == ELoopFor) // for loop
{
- if (!node->getUnrollFlag()) {
+ if (!node->getUnrollFlag())
+ {
out << "for (";
if (node->getInit())
node->getInit()->traverse(this);
@@ -657,6 +811,18 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node)
node->getExpression()->traverse(this);
out << ")\n";
}
+ else
+ {
+ // Need to put a one-iteration loop here to handle break.
+ TIntermSequence *declSeq =
+ node->getInit()->getAsAggregate()->getSequence();
+ TIntermSymbol *indexSymbol =
+ (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
+ TString name = hashVariableName(indexSymbol->getSymbol());
+ out << "for (int " << name << " = 0; "
+ << name << " < 1; "
+ << "++" << name << ")\n";
+ }
}
else if (loopType == ELoopWhile) // while loop
{
@@ -674,15 +840,15 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node)
// Loop body.
if (node->getUnrollFlag())
{
- TLoopIndexInfo indexInfo;
- mLoopUnroll.FillLoopIndexInfo(node, indexInfo);
- mLoopUnroll.Push(indexInfo);
- while (mLoopUnroll.SatisfiesLoopCondition())
+ out << "{\n";
+ mLoopUnrollStack.push(node);
+ while (mLoopUnrollStack.satisfiesLoopCondition())
{
visitCodeBlock(node->getBody());
- mLoopUnroll.Step();
+ mLoopUnrollStack.step();
}
- mLoopUnroll.Pop();
+ mLoopUnrollStack.pop();
+ out << "}\n";
}
else
{
@@ -704,21 +870,31 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node)
return false;
}
-bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch* node)
+bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch *node)
{
switch (node->getFlowOp())
{
- case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break;
- case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break;
- case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break;
- case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break;
- default: UNREACHABLE(); break;
+ case EOpKill:
+ writeTriplet(visit, "discard", NULL, NULL);
+ break;
+ case EOpBreak:
+ writeTriplet(visit, "break", NULL, NULL);
+ break;
+ case EOpContinue:
+ writeTriplet(visit, "continue", NULL, NULL);
+ break;
+ case EOpReturn:
+ writeTriplet(visit, "return ", NULL, NULL);
+ break;
+ default:
+ UNREACHABLE();
}
return true;
}
-void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) {
+void TOutputGLSLBase::visitCodeBlock(TIntermNode *node)
+{
TInfoSinkBase &out = objSink();
if (node != NULL)
{
@@ -734,7 +910,7 @@ void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) {
}
}
-TString TOutputGLSLBase::getTypeName(const TType& type)
+TString TOutputGLSLBase::getTypeName(const TType &type)
{
TInfoSinkBase out;
if (type.isMatrix())
@@ -746,10 +922,17 @@ TString TOutputGLSLBase::getTypeName(const TType& type)
{
switch (type.getBasicType())
{
- case EbtFloat: out << "vec"; break;
- case EbtInt: out << "ivec"; break;
- case EbtBool: out << "bvec"; break;
- default: UNREACHABLE(); break;
+ case EbtFloat:
+ out << "vec";
+ break;
+ case EbtInt:
+ out << "ivec";
+ break;
+ case EbtBool:
+ out << "bvec";
+ break;
+ default:
+ UNREACHABLE();
}
out << type.getNominalSize();
}
@@ -763,7 +946,7 @@ TString TOutputGLSLBase::getTypeName(const TType& type)
return TString(out.c_str());
}
-TString TOutputGLSLBase::hashName(const TString& name)
+TString TOutputGLSLBase::hashName(const TString &name)
{
if (mHashFunction == NULL || name.empty())
return name;
@@ -775,35 +958,41 @@ TString TOutputGLSLBase::hashName(const TString& name)
return hashedName;
}
-TString TOutputGLSLBase::hashVariableName(const TString& name)
+TString TOutputGLSLBase::hashVariableName(const TString &name)
{
- if (mSymbolTable.findBuiltIn(name) != NULL)
+ if (mSymbolTable.findBuiltIn(name, mShaderVersion) != NULL)
return name;
return hashName(name);
}
-TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
+TString TOutputGLSLBase::hashFunctionName(const TString &mangled_name)
{
TString name = TFunction::unmangleName(mangled_name);
- if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main")
- return name;
+ if (mSymbolTable.findBuiltIn(mangled_name, mShaderVersion) != NULL || name == "main")
+ return translateTextureFunction(name);
return hashName(name);
}
-bool TOutputGLSLBase::structDeclared(const TStructure* structure) const
+bool TOutputGLSLBase::structDeclared(const TStructure *structure) const
{
- return mDeclaredStructs.find(structure->name()) != mDeclaredStructs.end();
+ ASSERT(structure);
+ if (structure->name().empty())
+ {
+ return false;
+ }
+
+ return (mDeclaredStructs.count(structure->uniqueId()) > 0);
}
-void TOutputGLSLBase::declareStruct(const TStructure* structure)
+void TOutputGLSLBase::declareStruct(const TStructure *structure)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
out << "struct " << hashName(structure->name()) << "{\n";
- const TFieldList& fields = structure->fields();
+ const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
- const TField* field = fields[i];
+ const TField *field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
out << getTypeName(*field->type()) << " " << hashName(field->name());
@@ -812,6 +1001,5 @@ void TOutputGLSLBase::declareStruct(const TStructure* structure)
out << ";\n";
}
out << "}";
-
- mDeclaredStructs.insert(structure->name());
}
+