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; }
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); }
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 ¶mType = 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 ¶meter = 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 ¶meter = 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); }