void TOutputGLSL::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(); TQualifier qualifier = type.getQualifier(); // TODO(alokp): Validate qualifier for function arguments. if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) out << type.getQualifierString() << " "; out << getTypeName(type); const TString& name = arg->getSymbol(); if (!name.empty()) out << " " << name; if (type.isArray()) out << arrayBrackets(type); // Put a comma if this is not the last argument. if (iter != args.end() - 1) out << ", "; } }
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) && (mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end())) { out << "struct " << type.getTypeName() << "{\n"; const TTypeList* structure = type.getStruct(); ASSERT(structure != NULL); for (size_t i = 0; i < structure->size(); ++i) { const TType* fieldType = (*structure)[i].type; ASSERT(fieldType != NULL); if (writeVariablePrecision(fieldType->getPrecision())) out << " "; out << getTypeName(*fieldType) << " " << fieldType->getFieldName(); if (fieldType->isArray()) out << arrayBrackets(*fieldType); out << ";\n"; } out << "}"; mDeclaredStructs.insert(type.getTypeName()); } else { if (writeVariablePrecision(type.getPrecision())) out << " "; out << getTypeName(type); } }
void TOutputGLSL::visitSymbol(TIntermSymbol* node) { TInfoSinkBase& out = objSink(); out << node->getSymbol(); if (mDeclaringVariables && node->getType().isArray()) out << arrayBrackets(node->getType()); }
void TOutputGLSLBase::visitSymbol(TIntermSymbol* node) { TInfoSinkBase& out = objSink(); if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node)) out << mLoopUnroll.GetLoopIndexValue(node); else out << node->getSymbol(); if (mDeclaringVariables && node->getType().isArray()) out << arrayBrackets(node->getType()); }
void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBlock) { TInfoSinkBase &out = objSink(); out << hashName(interfaceBlock->name()) << "{\n"; const TFieldList &fields = interfaceBlock->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 << "}"; }
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()); }
void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type, const char *constructorBaseType) { TInfoSinkBase &out = objSink(); if (visit == PreVisit) { if (type.isArray()) { out << constructorBaseType; out << arrayBrackets(type); out << "("; } else { out << constructorBaseType << "("; } } else { writeTriplet(visit, nullptr, ", ", ")"); } }
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 << " " << name; if (type.isArray()) out << arrayBrackets(type); // Put a comma if this is not the last argument. if (iter != args.end() - 1) out << ", "; } }
bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) { bool visitChildren = true; TInfoSinkBase &out = objSink(); bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction()); switch (node->getOp()) { case EOpSequence: // Scope the sequences except when at the global scope. if (mDepth > 0) { out << "{\n"; } incrementDepth(node); for (TIntermSequence::const_iterator iter = node->getSequence()->begin(); iter != node->getSequence()->end(); ++iter) { TIntermNode *curNode = *iter; ASSERT(curNode != NULL); curNode->traverse(this); if (isSingleStatement(curNode)) out << ";\n"; } decrementDepth(); // Scope the sequences except when at the global scope. if (mDepth > 0) { out << "}\n"; } visitChildren = false; break; case EOpPrototype: // Function declaration. ASSERT(visit == PreVisit); { const TType &type = node->getType(); writeVariableType(type); if (type.isArray()) out << arrayBrackets(type); } out << " " << hashFunctionNameIfNeeded(node->getNameObj()); out << "("; writeFunctionParameters(*(node->getSequence())); out << ")"; visitChildren = false; break; case EOpFunction: { // Function definition. ASSERT(visit == PreVisit); { const TType &type = node->getType(); writeVariableType(type); if (type.isArray()) out << arrayBrackets(type); } out << " " << hashFunctionNameIfNeeded(node->getNameObj()); 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 << hashFunctionNameIfNeeded(node->getNameObj()) << "("; 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 EOpInvariantDeclaration: // Invariant declaration. ASSERT(visit == PreVisit); { const TIntermSequence *sequence = node->getSequence(); ASSERT(sequence && sequence->size() == 1); const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode(); ASSERT(symbol); out << "invariant " << hashVariableName(symbol->getSymbol()); } visitChildren = false; break; case EOpConstructFloat: writeConstructorTriplet(visit, node->getType(), "float"); break; case EOpConstructVec2: writeConstructorTriplet(visit, node->getType(), "vec2"); break; case EOpConstructVec3: writeConstructorTriplet(visit, node->getType(), "vec3"); break; case EOpConstructVec4: writeConstructorTriplet(visit, node->getType(), "vec4"); break; case EOpConstructBool: writeConstructorTriplet(visit, node->getType(), "bool"); break; case EOpConstructBVec2: writeConstructorTriplet(visit, node->getType(), "bvec2"); break; case EOpConstructBVec3: writeConstructorTriplet(visit, node->getType(), "bvec3"); break; case EOpConstructBVec4: writeConstructorTriplet(visit, node->getType(), "bvec4"); break; case EOpConstructInt: writeConstructorTriplet(visit, node->getType(), "int"); break; case EOpConstructIVec2: writeConstructorTriplet(visit, node->getType(), "ivec2"); break; case EOpConstructIVec3: writeConstructorTriplet(visit, node->getType(), "ivec3"); break; case EOpConstructIVec4: writeConstructorTriplet(visit, node->getType(), "ivec4"); break; case EOpConstructUInt: writeConstructorTriplet(visit, node->getType(), "uint"); break; case EOpConstructUVec2: writeConstructorTriplet(visit, node->getType(), "uvec2"); break; case EOpConstructUVec3: writeConstructorTriplet(visit, node->getType(), "uvec3"); break; case EOpConstructUVec4: writeConstructorTriplet(visit, node->getType(), "uvec4"); break; case EOpConstructMat2: writeConstructorTriplet(visit, node->getType(), "mat2"); break; case EOpConstructMat2x3: writeConstructorTriplet(visit, node->getType(), "mat2x3"); break; case EOpConstructMat2x4: writeConstructorTriplet(visit, node->getType(), "mat2x4"); break; case EOpConstructMat3x2: writeConstructorTriplet(visit, node->getType(), "mat3x2"); break; case EOpConstructMat3: writeConstructorTriplet(visit, node->getType(), "mat3"); break; case EOpConstructMat3x4: writeConstructorTriplet(visit, node->getType(), "mat3x4"); break; case EOpConstructMat4x2: writeConstructorTriplet(visit, node->getType(), "mat4x2"); break; case EOpConstructMat4x3: writeConstructorTriplet(visit, node->getType(), "mat4x3"); break; case EOpConstructMat4: writeConstructorTriplet(visit, node->getType(), "mat4"); break; case EOpConstructStruct: { const TType &type = node->getType(); ASSERT(type.getBasicType() == EbtStruct); TString constructorName = hashName(type.getStruct()->name()); writeConstructorTriplet(visit, node->getType(), constructorName.c_str()); break; } case EOpOuterProduct: writeBuiltInFunctionTriplet(visit, "outerProduct(", useEmulatedFunction); 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, "(", ", ", ")"); break; case EOpMod: writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction); break; case EOpModf: writeBuiltInFunctionTriplet(visit, "modf(", 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(); } return visitChildren; }