Skip to content
Browse files

Merge pull request #26 from mingwandroid/vertex-return-struct-in-struct

Allow nested structures to be returned from vertex shader.
  • Loading branch information...
2 parents 8bc1449 + a99f147 commit f7e51db5b8bddf8abc74af17ecaf4143b395b59b @aras-p committed Apr 11, 2013
View
113 hlslang/GLSLCodeGen/hlslLinker.cpp
@@ -1082,6 +1082,70 @@ void HlslLinker::emitMainStart(const HlslCrossCompiler* compiler, const EGlslSym
}
}
+// This function calls itself recursively if it finds structs in structs.
+bool HlslLinker::emitReturnStruct(GlslStruct *retStruct, std::string parentName, EShLanguage lang, std::stringstream& varying, std::stringstream& postamble)
+{
+ const int elem = retStruct->memberCount();
+ for (int ii=0; ii<elem; ii++)
+ {
+ const GlslStruct::StructMember &current = retStruct->getMember(ii);
+ std::string name, ctor;
+ int pad;
+ int arraySize = 1;
+ bool isArray = false;
+
+ if (lang == EShLangVertex) // vertex shader
+ {
+ // If it is an array, loop over each member
+ if ( current.arraySize > 0 )
+ {
+ arraySize = current.arraySize;
+ isArray = true;
+ }
+ }
+
+ for (int idx = 0; idx < arraySize; ++idx)
+ {
+ if (!getArgumentData2( current.name, current.semantic, current.type, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad, idx))
+ {
+ GlslStruct *subStruct = current.structType;
+ if (subStruct)
+ {
+ if (!emitReturnStruct(current.structType, parentName+current.name+std::string("."), lang, varying, postamble))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ infoSink.info << (lang==EShLangVertex ? "Unsupported element type in struct for shader return value (" : "Unsupported struct element type in return type for shader entry function (");
+ infoSink.info << getTypeString(current.type) << ")\n";
+ return false;
+ }
+ }
+ else
+ {
+ postamble << " ";
+ postamble << name;
+ postamble << " = " << ctor;
+ postamble << "(" << parentName << current.name;
+ if (isArray)
+ {
+ postamble << "[" << idx << "]";
+ }
+ for (int ii = 0; ii<pad; ii++)
+ postamble << ", 0.0";
+
+ postamble << ");\n";
+
+ // In vertex shader, add to varyings
+ if (lang == EShLangVertex)
+ AddToVaryings (varying, current.precision, ctor, name);
+ }
+ }
+ }
+ return true;
+}
bool HlslLinker::emitReturnValue(const EGlslSymbolType retType, GlslFunction* funcMain, EShLanguage lang, std::stringstream& varying, std::stringstream& postamble)
{
@@ -1128,54 +1192,7 @@ bool HlslLinker::emitReturnValue(const EGlslSymbolType retType, GlslFunction* fu
assert (retType == EgstStruct);
GlslStruct *retStruct = funcMain->getStruct();
assert (retStruct);
-
- const int elem = retStruct->memberCount();
- for (int ii=0; ii<elem; ii++)
- {
- const GlslStruct::StructMember &current = retStruct->getMember(ii);
- std::string name, ctor;
- int pad;
- int arraySize = 1;
- bool isArray = false;
-
- if (lang == EShLangVertex) // vertex shader
- {
- // If it is an array, loop over each member
- if ( current.arraySize > 0 )
- {
- arraySize = current.arraySize;
- isArray = true;
- }
- }
-
- for (int idx = 0; idx < arraySize; ++idx)
- {
- if (!getArgumentData2( current.name, current.semantic, current.type, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad, idx))
- {
- infoSink.info << (lang==EShLangVertex ? "Unsupported element type in struct for shader return value (" : "Unsupported struct element type in return type for shader entry function (");
- infoSink.info << getTypeString(current.type) << ")\n";
- return false;
- }
- postamble << " ";
- postamble << name;
- postamble << " = " << ctor;
- postamble << "( xl_retval." << current.name;
- if (isArray)
- {
- postamble << "[" << idx << "]";
- }
- for (int ii = 0; ii<pad; ii++)
- postamble << ", 0.0";
-
- postamble << ");\n";
-
- // In vertex shader, add to varyings
- if (lang == EShLangVertex)
- AddToVaryings (varying, current.precision, ctor, name);
- }
- }
-
- return true;
+ return emitReturnStruct(retStruct, std::string("xl_retval."), lang, varying, postamble);
}
View
1 hlslang/GLSLCodeGen/hlslLinker.h
@@ -77,6 +77,7 @@ class HlslLinker
void emitOutputStructParam(GlslSymbol* sym, EShLanguage lang, bool usePrecision, EAttribSemantic attrSem, std::stringstream& varying, std::stringstream& preamble, std::stringstream& postamble, std::stringstream& call);
void emitMainStart(const HlslCrossCompiler* compiler, const EGlslSymbolType retType, GlslFunction* funcMain, unsigned options, bool usePrecision, std::stringstream& preamble);
bool emitReturnValue(const EGlslSymbolType retType, GlslFunction* funcMain, EShLanguage lang, std::stringstream& varying, std::stringstream& postamble);
+ bool emitReturnStruct(GlslStruct* retStruct, std::string parentName, EShLanguage lang, std::stringstream& varying, std::stringstream& postamble);
private:
TInfoSink& infoSink;
View
15 tests/vertex/return-struct-of-struct-in.txt
@@ -0,0 +1,15 @@
+#line 1 "return-struct-of-struct-in.txt"
+struct v2f_sub {
+ float4 color : COLOR;
+};
+struct v2f {
+ float4 pos : TEXCOORD;
+ v2f_sub ss;
+};
+v2f main( in float4 pos : POSITION )
+{
+ v2f o;
+ o.pos = pos;
+ o.ss.color = pos;
+ return o;
+}
View
28 tests/vertex/return-struct-of-struct-out.txt
@@ -0,0 +1,28 @@
+
+#line 0
+struct v2f_sub {
+ vec4 color;
+};
+#line 4
+struct v2f {
+ vec4 pos;
+ v2f_sub ss;
+};
+#line 8
+v2f xlat_main( in vec4 pos );
+#line 8
+v2f xlat_main( in vec4 pos ) {
+ v2f o;
+ o.pos = pos;
+ #line 12
+ o.ss.color = pos;
+ return o;
+}
+varying vec4 xlv_TEXCOORD;
+varying vec4 xlv_COLOR;
+void main() {
+ v2f xl_retval;
+ xl_retval = xlat_main( vec4(gl_Vertex));
+ xlv_TEXCOORD = vec4(xl_retval.pos);
+ xlv_COLOR = vec4(xl_retval.ss.color);
+}

0 comments on commit f7e51db

Please sign in to comment.
Something went wrong with that request. Please try again.