GLenum GLVariableType(const TType &type) { if (type.getBasicType() == EbtFloat) { if (type.isScalar()) { return GL_FLOAT; } else if (type.isVector()) { switch (type.getNominalSize()) { case 2: return GL_FLOAT_VEC2; case 3: return GL_FLOAT_VEC3; case 4: return GL_FLOAT_VEC4; default: UNREACHABLE(); } } else if (type.isMatrix()) { switch (type.getCols()) { case 2: switch (type.getRows()) { case 2: return GL_FLOAT_MAT2; case 3: return GL_FLOAT_MAT2x3; case 4: return GL_FLOAT_MAT2x4; default: UNREACHABLE(); } case 3: switch (type.getRows()) { case 2: return GL_FLOAT_MAT3x2; case 3: return GL_FLOAT_MAT3; case 4: return GL_FLOAT_MAT3x4; default: UNREACHABLE(); } case 4: switch (type.getRows()) { case 2: return GL_FLOAT_MAT4x2; case 3: return GL_FLOAT_MAT4x3; case 4: return GL_FLOAT_MAT4; default: UNREACHABLE(); } default: UNREACHABLE(); } } else UNREACHABLE(); } else if (type.getBasicType() == EbtInt) { if (type.isScalar()) { return GL_INT; } else if (type.isVector()) { switch (type.getNominalSize()) { case 2: return GL_INT_VEC2; case 3: return GL_INT_VEC3; case 4: return GL_INT_VEC4; default: UNREACHABLE(); } } else UNREACHABLE(); } else if (type.getBasicType() == EbtUInt) { if (type.isScalar()) { return GL_UNSIGNED_INT; } else if (type.isVector()) { switch (type.getNominalSize()) { case 2: return GL_UNSIGNED_INT_VEC2; case 3: return GL_UNSIGNED_INT_VEC3; case 4: return GL_UNSIGNED_INT_VEC4; default: UNREACHABLE(); } } else UNREACHABLE(); } else if (type.getBasicType() == EbtBool) { if (type.isScalar()) { return GL_BOOL; } else if (type.isVector()) { switch (type.getNominalSize()) { case 2: return GL_BOOL_VEC2; case 3: return GL_BOOL_VEC3; case 4: return GL_BOOL_VEC4; default: UNREACHABLE(); } } else UNREACHABLE(); } switch (type.getBasicType()) { case EbtSampler2D: return GL_SAMPLER_2D; case EbtSampler3D: return GL_SAMPLER_3D; case EbtSamplerCube: return GL_SAMPLER_CUBE; case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES; case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB; case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY; case EbtISampler2D: return GL_INT_SAMPLER_2D; case EbtISampler3D: return GL_INT_SAMPLER_3D; case EbtISamplerCube: return GL_INT_SAMPLER_CUBE; case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY; case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D; case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D; case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE; case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY; case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW; case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW; case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW; default: UNREACHABLE(); } return GL_NONE; }
TString TypeString(const TType &type) { const TStructure *structure = type.getStruct(); if (structure) { if (structure->symbolType() != SymbolType::Empty) { return StructNameString(*structure); } else // Nameless structure, define in place { return StructureHLSL::defineNameless(*structure); } } else if (type.isMatrix()) { int cols = type.getCols(); int rows = type.getRows(); return "float" + str(cols) + "x" + str(rows); } else { switch (type.getBasicType()) { case EbtFloat: switch (type.getNominalSize()) { case 1: return "float"; case 2: return "float2"; case 3: return "float3"; case 4: return "float4"; } case EbtInt: switch (type.getNominalSize()) { case 1: return "int"; case 2: return "int2"; case 3: return "int3"; case 4: return "int4"; } case EbtUInt: switch (type.getNominalSize()) { case 1: return "uint"; case 2: return "uint2"; case 3: return "uint3"; case 4: return "uint4"; } case EbtBool: switch (type.getNominalSize()) { case 1: return "bool"; case 2: return "bool2"; case 3: return "bool3"; case 4: return "bool4"; } case EbtVoid: return "void"; case EbtSampler2D: case EbtISampler2D: case EbtUSampler2D: case EbtSampler2DArray: case EbtISampler2DArray: case EbtUSampler2DArray: return "sampler2D"; case EbtSamplerCube: case EbtISamplerCube: case EbtUSamplerCube: return "samplerCUBE"; case EbtSamplerExternalOES: return "sampler2D"; case EbtAtomicCounter: // Multiple atomic_uints will be implemented as a single RWByteAddressBuffer return "RWByteAddressBuffer"; default: break; } } UNREACHABLE(); return "<unknown type>"; }
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); }
TString TypeString(const TType &type) { const TStructure* structure = type.getStruct(); if (structure) { const TString& typeName = structure->name(); if (typeName != "") { return StructNameString(*structure); } else // Nameless structure, define in place { return StructureHLSL::defineNameless(*structure); } } else if (type.isMatrix()) { int cols = type.getCols(); int rows = type.getRows(); return "float" + str(cols) + "x" + str(rows); } else { switch (type.getBasicType()) { case EbtFloat: switch (type.getNominalSize()) { case 1: return "float"; case 2: return "float2"; case 3: return "float3"; case 4: return "float4"; } case EbtInt: switch (type.getNominalSize()) { case 1: return "int"; case 2: return "int2"; case 3: return "int3"; case 4: return "int4"; } case EbtUInt: switch (type.getNominalSize()) { case 1: return "uint"; case 2: return "uint2"; case 3: return "uint3"; case 4: return "uint4"; } case EbtBool: switch (type.getNominalSize()) { case 1: return "bool"; case 2: return "bool2"; case 3: return "bool3"; case 4: return "bool4"; } case EbtVoid: return "void"; case EbtSampler2D: case EbtISampler2D: case EbtUSampler2D: case EbtSampler2DArray: case EbtISampler2DArray: case EbtUSampler2DArray: return "sampler2D"; case EbtSamplerCube: case EbtISamplerCube: case EbtUSamplerCube: return "samplerCUBE"; case EbtSamplerExternalOES: return "sampler2D"; default: break; } } UNREACHABLE(); return "<unknown type>"; }
TOperator TypeToConstructorOperator(const TType &type) { switch (type.getBasicType()) { case EbtFloat: if (type.isMatrix()) { switch (type.getCols()) { case 2: switch (type.getRows()) { case 2: return EOpConstructMat2; case 3: return EOpConstructMat2x3; case 4: return EOpConstructMat2x4; default: break; } break; case 3: switch (type.getRows()) { case 2: return EOpConstructMat3x2; case 3: return EOpConstructMat3; case 4: return EOpConstructMat3x4; default: break; } break; case 4: switch (type.getRows()) { case 2: return EOpConstructMat4x2; case 3: return EOpConstructMat4x3; case 4: return EOpConstructMat4; default: break; } break; } } else { switch (type.getNominalSize()) { case 1: return EOpConstructFloat; case 2: return EOpConstructVec2; case 3: return EOpConstructVec3; case 4: return EOpConstructVec4; default: break; } } break; case EbtInt: switch (type.getNominalSize()) { case 1: return EOpConstructInt; case 2: return EOpConstructIVec2; case 3: return EOpConstructIVec3; case 4: return EOpConstructIVec4; default: break; } break; case EbtUInt: switch (type.getNominalSize()) { case 1: return EOpConstructUInt; case 2: return EOpConstructUVec2; case 3: return EOpConstructUVec3; case 4: return EOpConstructUVec4; default: break; } break; case EbtBool: switch (type.getNominalSize()) { case 1: return EOpConstructBool; case 2: return EOpConstructBVec2; case 3: return EOpConstructBVec3; case 4: return EOpConstructBVec4; default: break; } break; case EbtStruct: return EOpConstructStruct; default: break; } return EOpNull; }