Esempio n. 1
0
TIntermAggregate *EmulatePrecision::createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
                                                                             TIntermTyped *right,
                                                                             const char *opNameStr)
{
    std::stringstream strstr = sh::InitializeStream<std::stringstream>();
    if (left->getPrecision() == EbpMedium)
        strstr << "angle_compound_" << opNameStr << "_frm";
    else
        strstr << "angle_compound_" << opNameStr << "_frl";
    ImmutableString functionName = ImmutableString(strstr.str());
    TIntermSequence *arguments   = new TIntermSequence();
    arguments->push_back(left);
    arguments->push_back(right);

    TVector<const TVariable *> parameters;
    TType *leftParamType = new TType(left->getType());
    leftParamType->setPrecision(EbpHigh);
    leftParamType->setQualifier(EvqOut);
    parameters.push_back(new TVariable(mSymbolTable, kParamXName,
                                       static_cast<const TType *>(leftParamType),
                                       SymbolType::AngleInternal));
    TType *rightParamType = new TType(right->getType());
    rightParamType->setPrecision(EbpHigh);
    rightParamType->setQualifier(EvqIn);
    parameters.push_back(new TVariable(mSymbolTable, kParamYName,
                                       static_cast<const TType *>(rightParamType),
                                       SymbolType::AngleInternal));

    return TIntermAggregate::CreateRawFunctionCall(
        *getInternalFunction(functionName, left->getType(), arguments, parameters, false),
        arguments);
}
TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *original)
{
    TString tempVarName = "_webgl_tmp_";
    if (original->isScalar())
    {
        tempVarName += "scalar_";
    }
    else if (original->isVector())
    {
        tempVarName += "vec_";
    }
    else
    {
        ASSERT(original->isMatrix());
        tempVarName += "mat_";
    }
    tempVarName += Str(mTempVarCount).c_str();
    mTempVarCount++;

    ASSERT(original);
    TType type = original->getType();
    type.setQualifier(EvqTemporary);

    if (mShaderType == GL_FRAGMENT_SHADER &&
        type.getBasicType() == EbtFloat &&
        type.getPrecision() == EbpUndefined)
    {
        // We use the highest available precision for the temporary variable
        // to avoid computing the actual precision using the rules defined
        // in GLSL ES 1.0 Section 4.5.2.
        type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
    }

    TIntermBinary *init = new TIntermBinary(EOpInitialize);
    TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
    init->setLeft(symbolNode);
    init->setRight(original);
    init->setType(type);

    TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration);
    decl->getSequence()->push_back(init);

    ASSERT(mSequenceStack.size() > 0);
    TIntermSequence &sequence = mSequenceStack.back();
    sequence.push_back(decl);

    return tempVarName;
}
Esempio n. 3
0
TIntermAggregate *EmulatePrecision::createRoundingFunctionCallNode(TIntermTyped *roundedChild)
{
    const ImmutableString *roundFunctionName = &kAngleFrmString;
    if (roundedChild->getPrecision() == EbpLow)
        roundFunctionName = &kAngleFrlString;
    TIntermSequence *arguments = new TIntermSequence();
    arguments->push_back(roundedChild);

    TVector<const TVariable *> parameters;
    TType *paramType = new TType(roundedChild->getType());
    paramType->setPrecision(EbpHigh);
    paramType->setQualifier(EvqIn);
    parameters.push_back(new TVariable(mSymbolTable, kParamXName,
                                       static_cast<const TType *>(paramType),
                                       SymbolType::AngleInternal));

    return TIntermAggregate::CreateRawFunctionCall(
        *getInternalFunction(*roundFunctionName, roundedChild->getType(), arguments, parameters,
                             true),
        arguments);
}
Esempio n. 4
0
void StructureHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
{
    if (name == "")
    {
        return;   // Nameless structures don't have constructors
    }

    if (type.getStruct() && mStructNames.find(name) != mStructNames.end())
    {
        return;   // Already added
    }

    TType ctorType = type;
    ctorType.clearArrayness();
    ctorType.setPrecision(EbpHigh);
    ctorType.setQualifier(EvqTemporary);

    typedef std::vector<TType> ParameterArray;
    ParameterArray ctorParameters;

    const TStructure* structure = type.getStruct();
    if (structure)
    {
        mStructNames.insert(name);

        // Add element index
        storeStd140ElementIndex(*structure, false);
        storeStd140ElementIndex(*structure, true);

        const TString &structString = defineQualified(*structure, false, false);

        if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end())
        {
            // Add row-major packed struct for interface blocks
            TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
                defineQualified(*structure, true, false) +
                "#pragma pack_matrix(column_major)\n";

            TString std140String = defineQualified(*structure, false, true);
            TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
                defineQualified(*structure, true, true) +
                "#pragma pack_matrix(column_major)\n";

            mStructDeclarations.push_back(structString);
            mStructDeclarations.push_back(rowMajorString);
            mStructDeclarations.push_back(std140String);
            mStructDeclarations.push_back(std140RowMajorString);
        }

        const TFieldList &fields = structure->fields();
        for (unsigned int i = 0; i < fields.size(); i++)
        {
            ctorParameters.push_back(*fields[i]->type());
        }
    }
    else if (parameters)
    {
        for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++)
        {
            ctorParameters.push_back((*parameter)->getAsTyped()->getType());
        }
    }
    else UNREACHABLE();

    TString constructor;

    if (ctorType.getStruct())
    {
        constructor += name + " " + name + "_ctor(";
    }
    else   // Built-in type
    {
        constructor += TypeString(ctorType) + " " + name + "(";
    }

    for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
    {
        const TType &paramType = ctorParameters[parameter];

        constructor += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType);

        if (parameter < ctorParameters.size() - 1)
        {
            constructor += ", ";
        }
    }

    constructor += ")\n"
                   "{\n";

    if (ctorType.getStruct())
    {
        constructor += "    " + name + " structure = {";
    }
    else
    {
        constructor += "    return " + TypeString(ctorType) + "(";
    }

    if (ctorType.isMatrix() && ctorParameters.size() == 1)
    {
        int rows = ctorType.getRows();
        int cols = ctorType.getCols();
        const TType &parameter = ctorParameters[0];

        if (parameter.isScalar())
        {
            for (int col = 0; col < cols; col++)
            {
                for (int row = 0; row < rows; row++)
                {
                    constructor += TString((row == col) ? "x0" : "0.0");

                    if (row < rows - 1 || col < cols - 1)
                    {
                        constructor += ", ";
                    }
                }
            }
        }
        else if (parameter.isMatrix())
        {
            for (int col = 0; col < cols; col++)
            {
                for (int row = 0; row < rows; row++)
                {
                    if (row < parameter.getRows() && col < parameter.getCols())
                    {
                        constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]";
                    }
                    else
                    {
                        constructor += TString((row == col) ? "1.0" : "0.0");
                    }

                    if (row < rows - 1 || col < cols - 1)
                    {
                        constructor += ", ";
                    }
                }
            }
        }
        else
        {
            ASSERT(rows == 2 && cols == 2 && parameter.isVector() && parameter.getNominalSize() == 4);

            constructor += "x0";
        }
    }
    else
    {
        size_t remainingComponents = ctorType.getObjectSize();
        size_t parameterIndex = 0;

        while (remainingComponents > 0)
        {
            const TType &parameter = ctorParameters[parameterIndex];
            const size_t parameterSize = parameter.getObjectSize();
            bool moreParameters = parameterIndex + 1 < ctorParameters.size();

            constructor += "x" + str(parameterIndex);

            if (ctorType.getStruct())
            {
                ASSERT(remainingComponents == parameterSize || moreParameters);
                ASSERT(parameterSize <= remainingComponents);

                remainingComponents -= parameterSize;
            }
            else if (parameter.isScalar())
            {
                remainingComponents -= parameter.getObjectSize();
            }
            else if (parameter.isVector())
            {
                if (remainingComponents == parameterSize || moreParameters)
                {
                    ASSERT(parameterSize <= remainingComponents);
                    remainingComponents -= parameterSize;
                }
                else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
                {
                    switch (remainingComponents)
                    {
                      case 1: constructor += ".x";    break;
                      case 2: constructor += ".xy";   break;
                      case 3: constructor += ".xyz";  break;
                      case 4: constructor += ".xyzw"; break;
                      default: UNREACHABLE();
                    }

                    remainingComponents = 0;
                }
                else UNREACHABLE();
            }
            else if (parameter.isMatrix())
            {
                int column = 0;
                while (remainingComponents > 0 && column < parameter.getCols())
                {
                    constructor += "[" + str(column) + "]";

                    if (remainingComponents < static_cast<size_t>(parameter.getRows()))
                    {
                        switch (remainingComponents)
                        {
                          case 1:  constructor += ".x";    break;
                          case 2:  constructor += ".xy";   break;
                          case 3:  constructor += ".xyz";  break;
                          default: UNREACHABLE();
                        }

                        remainingComponents = 0;
                    }
                    else
                    {
                        remainingComponents -= parameter.getRows();

                        if (remainingComponents > 0)
                        {
                            constructor += ", x" + str(parameterIndex);
                        }
                    }

                    column++;
                }
            }
            else UNREACHABLE();

            if (moreParameters)
            {
                parameterIndex++;
            }

            if (remainingComponents)
            {
                constructor += ", ";
            }
        }
    }

    if (ctorType.getStruct())
    {
        constructor += "};\n"
                        "    return structure;\n"
                        "}\n";
    }
    else
    {
        constructor += ");\n"
                       "}\n";
    }

    mConstructors.insert(constructor);
}