// Determine the GLSL attribute semantic for a given HLSL semantic EAttribSemantic HlslLinker::parseAttributeSemantic( const std::string &semantic ) { std::string curSemantic = stripSemanticModifier (semantic, true); for (size_t i = 0; i < sizeof(kAttributeSemantic)/sizeof(kAttributeSemantic[0]); ++i) if (!_stricmp(curSemantic.c_str(), kAttributeSemantic[i].name)) return kAttributeSemantic[i].sem; return EAttrSemUnknown; }
bool HlslLinker::getArgumentData2( const std::string &name, const std::string &semantic, EGlslSymbolType type, EClassifier c, std::string &outName, std::string &ctor, int &pad, int semanticOffset) { int size; EGlslSymbolType base = EgstVoid; EAttribSemantic sem = parseAttributeSemantic( semantic ); // Offset the semantic for the case of an array sem = static_cast<EAttribSemantic>( (int)sem + semanticOffset ); //clear the return values outName = ""; ctor = ""; pad = 0; //compute the # of elements in the type switch (type) { case EgstBool: case EgstBool2: case EgstBool3: case EgstBool4: base = EgstBool; size = type - EgstBool + 1; break; case EgstInt: case EgstInt2: case EgstInt3: case EgstInt4: base = EgstInt; size = type - EgstInt + 1; break; case EgstFloat: case EgstFloat2: case EgstFloat3: case EgstFloat4: base = EgstFloat; size = type - EgstFloat + 1; break; default: return false; }; if ( c != EClassUniform) { ctor = getTypeString( (EGlslSymbolType)((int)base + size - 1)); //default constructor pad = 0; switch (c) { case EClassNone: return false; case EClassAttrib: // If the user has specified a user attrib name, use a user attribute if ( userAttribString[sem][0] != '\0') { outName = userAttribString[sem]; } // Otherwise, use the built-in attribute name else { outName = attribString[sem]; if (sem == EAttrSemNormal && size == 4) pad = 1; else if ( sem == EAttrSemUnknown || outName[0] == '\0' ) { //handle the blind data outName = "xlat_attrib_"; outName += semantic; } } break; case EClassVarOut: // If using user varyings, create a user varying name if ( (bUserVaryings && sem != EAttrSemPosition) || varOutString[sem][0] == 0 ) { outName = kUserVaryingPrefix; outName += semantic; // If an array element, add the semantic offset to the name if ( semanticOffset != 0 ) { outName += "_"; outName += ( semanticOffset + '0' ); } } else { // Use built-in varying name outName = varOutString[sem]; } break; case EClassVarIn: // If using user varyings, create a user varying name if ( (bUserVaryings && sem != EAttrSemVPos && sem != EAttrSemVFace) || varInString[sem][0] == 0 ) { outName = kUserVaryingPrefix; outName += stripSemanticModifier ( semantic, false ); // If an array element, add the semantic offset to the name if ( semanticOffset != 0 ) { outName += "_"; outName += ( semanticOffset + '0' ); } } else { // Use built-in varying name outName = varInString[sem]; } break; case EClassRes: outName = resultString[sem]; if ( sem != EAttrSemDepth) { pad = 4 - size; ctor = "vec4"; } else { ctor = "float"; } break; case EClassUniform: assert(0); // this should have been stripped return false; }; } else { //these should always match exactly outName = "xlu_"; outName += name; } return true; }
bool HlslLinker::getArgumentData2( GlslSymbolOrStructMemberBase const* symOrStructMember, EClassifier c, std::string &outName, std::string &ctor, int &pad, int semanticOffset) { int size; EGlslSymbolType base = EgstVoid; // Get the type before suppression because we may not want all of the elements. // note, suppressedBy should *never* be smaller than the suppressed. EGlslSymbolType type = symOrStructMember->type; GlslSymbolOrStructMemberBase const* suppressedBy = symOrStructMember->outputSuppressedBy(); if (suppressedBy) symOrStructMember = suppressedBy; EAttribSemantic sem = parseAttributeSemantic( symOrStructMember->semantic ); const std::string& semantic = symOrStructMember->semantic; // Offset the semantic for the case of an array if ( semanticOffset > 0 ) sem = static_cast<EAttribSemantic>( (int)sem + semanticOffset ); //clear the return values outName = ""; ctor = ""; pad = 0; //compute the # of elements in the type switch (type) { case EgstBool: case EgstBool2: case EgstBool3: case EgstBool4: base = EgstBool; size = type - EgstBool + 1; break; case EgstInt: case EgstInt2: case EgstInt3: case EgstInt4: base = EgstInt; size = type - EgstInt + 1; break; case EgstFloat: case EgstFloat2: case EgstFloat3: case EgstFloat4: base = EgstFloat; size = type - EgstFloat + 1; break; default: return false; }; if ( c != EClassUniform) { ctor = getTypeString( (EGlslSymbolType)((int)base + size - 1)); //default constructor pad = 0; switch (c) { case EClassNone: return false; case EClassAttrib: getAttributeName( symOrStructMember, outName, sem, semanticOffset ); if (outName == "gl_Normal" && size == 4) pad = 1; break; case EClassVarOut: // If using user varyings, create a user varying name // WHY ON EARTH such funny if if ( (bUserVaryings && sem != EAttrSemPosition && sem != EAttrSemPrimitiveID && sem != EAttrSemPSize) || varOutString[sem][0] == 0 ) { outName = kUserVaryingPrefix; outName += semantic; // If an array element, add the semantic offset to the name if ( semanticOffset > 0 ) { outName += "_"; outName += ( semanticOffset + '0' ); } } else { // Use built-in varying name outName = varOutString[sem]; // Always pad built-in varying outputs to 4 elements // exception: psize must be kept float1 if(sem != EAttrSemPSize) { pad = 4 - size; ctor = "vec4"; } } break; case EClassVarIn: // inout COLORn variables translate to framebuffer fetch for GLES if (IsArgumentForFramebufferFetch(symOrStructMember, sem, m_Target)) { int index = sem - EAttrSemColor0; outName = (m_Target == ETargetGLSL_ES_100 ? "gl_LastFragData" : "gl_FragData"); outName += '['; outName += char('0'+index); outName += ']'; m_Extensions.insert("GL_EXT_shader_framebuffer_fetch"); } // If using user varyings, create a user varying name else if ( (bUserVaryings && sem != EAttrSemVPos && sem != EAttrSemVFace && sem != EAttrSemPrimitiveID) || varInString[sem][0] == 0 ) { outName = kUserVaryingPrefix; outName += stripSemanticModifier (semantic, false); // If an array element, add the semantic offset to the name if ( semanticOffset > 0 ) { outName += "_"; outName += ( semanticOffset + '0' ); } } else { // Use built-in varying name outName = varInString[sem]; } break; case EClassRes: outName = resultString[sem]; if (sem == EAttrSemDepth) { if (m_Target == ETargetGLSL_ES_100) { outName = "gl_FragDepthEXT"; m_Extensions.insert("GL_EXT_frag_depth"); } ctor = "float"; } else if (sem == EAttrSemCoverage) ctor = "int"; else { pad = 4 - size; ctor = "vec4"; } break; case EClassUniform: assert(0); // this should have been stripped return false; }; } else { //these should always match exactly outName = "xlu_"; outName += symOrStructMember->name; } return true; }