diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp')
-rw-r--r-- | Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp | 817 |
1 files changed, 0 insertions, 817 deletions
diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp deleted file mode 100644 index b90bd67ec..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp +++ /dev/null @@ -1,817 +0,0 @@ -// -// Copyright (c) 2002-2011 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. -// - -#include "compiler/OutputGLSLBase.h" -#include "compiler/debug.h" - -#include <cfloat> - -namespace -{ -TString arrayBrackets(const TType& type) -{ - ASSERT(type.isArray()); - TInfoSinkBase out; - out << "[" << type.getArraySize() << "]"; - return TString(out.c_str()); -} - -bool isSingleStatement(TIntermNode* node) { - if (const TIntermAggregate* aggregate = node->getAsAggregate()) - { - return (aggregate->getOp() != EOpFunction) && - (aggregate->getOp() != EOpSequence); - } - 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. - return selection->usesTernaryOperator(); - } - else if (node->getAsLoopNode()) - { - return false; - } - return true; -} -} // namespace - -TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink, - ShArrayIndexClampingStrategy clampingStrategy, - ShHashFunction64 hashFunction, - NameMap& nameMap, - TSymbolTable& symbolTable) - : TIntermTraverser(true, true, true), - mObjSink(objSink), - mDeclaringVariables(false), - mClampingStrategy(clampingStrategy), - mHashFunction(hashFunction), - mNameMap(nameMap), - mSymbolTable(symbolTable) -{ -} - -void TOutputGLSLBase::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr) -{ - 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) -{ - TInfoSinkBase& out = objSink(); - TQualifier qualifier = type.getQualifier(); - // TODO(alokp): Validate qualifier for variable declarations. - 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())) - { - declareStruct(type.getStruct()); - } - else - { - if (writeVariablePrecision(type.getPrecision())) - out << " "; - out << getTypeName(type); - } -} - -void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args) -{ - TInfoSinkBase& out = objSink(); - for (TIntermSequence::const_iterator iter = args.begin(); - iter != args.end(); ++iter) - { - const TIntermSymbol* arg = (*iter)->getAsSymbolNode(); - ASSERT(arg != NULL); - - const TType& type = arg->getType(); - writeVariableType(type); - - const TString& name = arg->getSymbol(); - if (!name.empty()) - out << " " << hashName(name); - if (type.isArray()) - out << arrayBrackets(type); - - // Put a comma if this is not the last argument. - if (iter != args.end() - 1) - out << ", "; - } -} - -const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type, - const ConstantUnion* pConstUnion) -{ - TInfoSinkBase& out = objSink(); - - if (type.getBasicType() == EbtStruct) - { - const TStructure* structure = type.getStruct(); - out << hashName(structure->name()) << "("; - - const TFieldList& fields = structure->fields(); - for (size_t i = 0; i < fields.size(); ++i) - { - const TType* fieldType = fields[i]->type(); - ASSERT(fieldType != NULL); - pConstUnion = writeConstantUnion(*fieldType, pConstUnion); - if (i != fields.size() - 1) out << ", "; - } - out << ")"; - } - else - { - size_t size = type.getObjectSize(); - bool writeType = size > 1; - 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(); - } - if (i != size - 1) out << ", "; - } - if (writeType) out << ")"; - } - return pConstUnion; -} - -void TOutputGLSLBase::visitSymbol(TIntermSymbol* node) -{ - TInfoSinkBase& out = objSink(); - if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node)) - out << mLoopUnroll.GetLoopIndexValue(node); - else - out << hashVariableName(node->getSymbol()); - - if (mDeclaringVariables && node->getType().isArray()) - out << arrayBrackets(node->getType()); -} - -void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion* node) -{ - writeConstantUnion(node->getType(), node->getUnionArrayPointer()); -} - -bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node) -{ - bool visitChildren = true; - TInfoSinkBase& out = objSink(); - switch (node->getOp()) - { - 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) - { - if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) { - out << "[int(clamp(float("; - } else { - out << "[webgl_int_clamp("; - } - } - else if (visit == PostVisit) - { - 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 << ")]"; - } - } - } - 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) - { - 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()) - { - case 0: out << "x"; break; - case 1: out << "y"; break; - case 2: out << "z"; break; - case 3: out << "w"; 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(); break; - } - - return visitChildren; -} - -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; - } - - if (visit == PreVisit && node->getUseEmulatedFunction()) - preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString); - writeTriplet(visit, preString.c_str(), NULL, postString.c_str()); - - return true; -} - -bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node) -{ - TInfoSinkBase& out = objSink(); - - if (node->usesTernaryOperator()) - { - // Notice two brackets at the beginning and end. The outer ones - // encapsulate the whole ternary expression. This preserves the - // order of precedence when ternary expressions are used in a - // compound expression, i.e., c = 2 * (a < b ? 1 : 2). - out << "(("; - node->getCondition()->traverse(this); - out << ") ? ("; - node->getTrueBlock()->traverse(this); - out << ") : ("; - node->getFalseBlock()->traverse(this); - out << "))"; - } - else - { - out << "if ("; - node->getCondition()->traverse(this); - out << ")\n"; - - incrementDepth(node); - visitCodeBlock(node->getTrueBlock()); - - if (node->getFalseBlock()) - { - out << "else\n"; - visitCodeBlock(node->getFalseBlock()); - } - decrementDepth(); - } - return false; -} - -bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node) -{ - bool visitChildren = true; - TInfoSinkBase& out = objSink(); - TString preString; - bool delayedWrite = false; - 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); - - if (isSingleStatement(node)) - out << ";\n"; - } - decrementDepth(); - - // Scope the sequences except when at the global scope. - if (depth > 0) out << "}\n"; - 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 << ")"; - } - 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; - } - else if (visit == InVisit) - { - out << ", "; - mDeclaringVariables = true; - } - else - { - mDeclaringVariables = false; - } - break; - } - 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; - } - 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) -{ - TInfoSinkBase& out = objSink(); - - incrementDepth(node); - // Loop header. - TLoopType loopType = node->getType(); - if (loopType == ELoopFor) // for loop - { - if (!node->getUnrollFlag()) { - out << "for ("; - if (node->getInit()) - node->getInit()->traverse(this); - out << "; "; - - if (node->getCondition()) - node->getCondition()->traverse(this); - out << "; "; - - if (node->getExpression()) - node->getExpression()->traverse(this); - out << ")\n"; - } - } - else if (loopType == ELoopWhile) // while loop - { - out << "while ("; - ASSERT(node->getCondition() != NULL); - node->getCondition()->traverse(this); - out << ")\n"; - } - else // do-while loop - { - ASSERT(loopType == ELoopDoWhile); - out << "do\n"; - } - - // Loop body. - if (node->getUnrollFlag()) - { - TLoopIndexInfo indexInfo; - mLoopUnroll.FillLoopIndexInfo(node, indexInfo); - mLoopUnroll.Push(indexInfo); - while (mLoopUnroll.SatisfiesLoopCondition()) - { - visitCodeBlock(node->getBody()); - mLoopUnroll.Step(); - } - mLoopUnroll.Pop(); - } - else - { - visitCodeBlock(node->getBody()); - } - - // Loop footer. - if (loopType == ELoopDoWhile) // do-while loop - { - out << "while ("; - ASSERT(node->getCondition() != NULL); - node->getCondition()->traverse(this); - out << ");\n"; - } - decrementDepth(); - - // No need to visit children. They have been already processed in - // this function. - return false; -} - -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; - } - - return true; -} - -void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) { - TInfoSinkBase &out = objSink(); - if (node != NULL) - { - node->traverse(this); - // Single statements not part of a sequence need to be terminated - // with semi-colon. - if (isSingleStatement(node)) - out << ";\n"; - } - else - { - out << "{\n}\n"; // Empty code block. - } -} - -TString TOutputGLSLBase::getTypeName(const TType& type) -{ - TInfoSinkBase out; - if (type.isMatrix()) - { - out << "mat"; - out << type.getNominalSize(); - } - else if (type.isVector()) - { - switch (type.getBasicType()) - { - case EbtFloat: out << "vec"; break; - case EbtInt: out << "ivec"; break; - case EbtBool: out << "bvec"; break; - default: UNREACHABLE(); break; - } - out << type.getNominalSize(); - } - else - { - if (type.getBasicType() == EbtStruct) - out << hashName(type.getStruct()->name()); - else - out << type.getBasicString(); - } - return TString(out.c_str()); -} - -TString TOutputGLSLBase::hashName(const TString& name) -{ - if (mHashFunction == NULL || name.empty()) - return name; - NameMap::const_iterator it = mNameMap.find(name.c_str()); - if (it != mNameMap.end()) - return it->second.c_str(); - TString hashedName = TIntermTraverser::hash(name, mHashFunction); - mNameMap[name.c_str()] = hashedName.c_str(); - return hashedName; -} - -TString TOutputGLSLBase::hashVariableName(const TString& name) -{ - if (mSymbolTable.findBuiltIn(name) != NULL) - return name; - return hashName(name); -} - -TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name) -{ - TString name = TFunction::unmangleName(mangled_name); - if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main") - return name; - return hashName(name); -} - -bool TOutputGLSLBase::structDeclared(const TStructure* structure) const -{ - return mDeclaredStructs.find(structure->name()) != mDeclaredStructs.end(); -} - -void TOutputGLSLBase::declareStruct(const TStructure* structure) -{ - TInfoSinkBase& out = objSink(); - - out << "struct " << hashName(structure->name()) << "{\n"; - const TFieldList& fields = structure->fields(); - for (size_t i = 0; i < fields.size(); ++i) - { - const TField* field = fields[i]; - if (writeVariablePrecision(field->type()->getPrecision())) - out << " "; - out << getTypeName(*field->type()) << " " << hashName(field->name()); - if (field->type()->isArray()) - out << arrayBrackets(*field->type()); - out << ";\n"; - } - out << "}"; - - mDeclaredStructs.insert(structure->name()); -} |