Пример #1
0
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 << ", ";
    }
}
Пример #2
0
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);
    }
}
Пример #3
0
void TOutputGLSL::visitSymbol(TIntermSymbol* node)
{
    TInfoSinkBase& out = objSink();
    out << node->getSymbol();

    if (mDeclaringVariables && node->getType().isArray())
        out << arrayBrackets(node->getType());
}
Пример #4
0
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());
}
Пример #5
0
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 << "}";
}
Пример #6
0
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());
}
Пример #7
0
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, ", ", ")");
    }
}
Пример #8
0
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 << ", ";
    }
}
Пример #9
0
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;
}