Skip to content
This repository

Allow nested structures to be returned from vertex shader. #26

Merged
merged 1 commit into from about 1 year ago

2 participants

Ray Donnelly Aras Pranckevičius
Ray Donnelly

I've got a few patches to submit, so would a branch per patch be best for you? All my changes are fairly independent of each other.

Aras Pranckevičius aras-p merged commit f7e51db into from April 11, 2013
Aras Pranckevičius aras-p closed this April 11, 2013
Aras Pranckevičius aras-p referenced this pull request from a commit April 11, 2013
Aras Pranckevičius tests: update output after #26 merge eabf34b
Aras Pranckevičius aras-p referenced this pull request from a commit April 13, 2013
Aras Pranckevičius tests: update output after #26 merge 8578c5f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Mar 09, 2013
Ray Donnelly Allow nested structures to be returned from vertex shader. a99f147
This page is out of date. Refresh to see the latest.
113  hlslang/GLSLCodeGen/hlslLinker.cpp
@@ -1082,6 +1082,70 @@ void HlslLinker::emitMainStart(const HlslCrossCompiler* compiler, const EGlslSym
1082 1082
 	}
1083 1083
 }
1084 1084
 
  1085
+// This function calls itself recursively if it finds structs in structs.
  1086
+bool HlslLinker::emitReturnStruct(GlslStruct *retStruct, std::string parentName, EShLanguage lang, std::stringstream& varying, std::stringstream& postamble)
  1087
+{
  1088
+	const int elem = retStruct->memberCount();
  1089
+	for (int ii=0; ii<elem; ii++)
  1090
+	{
  1091
+		const GlslStruct::StructMember &current = retStruct->getMember(ii);
  1092
+		std::string name, ctor;
  1093
+		int pad;
  1094
+		int arraySize = 1;
  1095
+		bool isArray = false;
  1096
+
  1097
+		if (lang == EShLangVertex) // vertex shader
  1098
+		{
  1099
+			// If it is an array, loop over each member
  1100
+			if ( current.arraySize > 0 )
  1101
+			{
  1102
+				arraySize = current.arraySize;
  1103
+				isArray = true;
  1104
+			}
  1105
+		}
  1106
+
  1107
+		for (int idx = 0; idx < arraySize; ++idx)
  1108
+		{
  1109
+			if (!getArgumentData2( current.name, current.semantic, current.type, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad, idx))
  1110
+			{
  1111
+				GlslStruct *subStruct = current.structType;
  1112
+				if (subStruct)
  1113
+				{
  1114
+					if (!emitReturnStruct(current.structType, parentName+current.name+std::string("."), lang, varying, postamble))
  1115
+					{
  1116
+						return false;
  1117
+					}
  1118
+				}
  1119
+				else
  1120
+				{
  1121
+					infoSink.info << (lang==EShLangVertex ? "Unsupported element type in struct for shader return value (" : "Unsupported struct element type in return type for shader entry function (");
  1122
+					infoSink.info << getTypeString(current.type) << ")\n";
  1123
+					return false;
  1124
+				}
  1125
+			}
  1126
+			else
  1127
+			{
  1128
+				postamble << "    ";
  1129
+				postamble << name;
  1130
+				postamble << " = " << ctor;
  1131
+				postamble << "(" << parentName << current.name;
  1132
+				if (isArray)
  1133
+				{
  1134
+					postamble << "[" << idx << "]";
  1135
+				}
  1136
+				for (int ii = 0; ii<pad; ii++)
  1137
+					postamble << ", 0.0";
  1138
+
  1139
+				postamble << ");\n";
  1140
+
  1141
+				// In vertex shader, add to varyings
  1142
+				if (lang == EShLangVertex)
  1143
+					AddToVaryings (varying, current.precision, ctor, name);
  1144
+			}
  1145
+		}
  1146
+	}
  1147
+	return true;
  1148
+}
1085 1149
 
1086 1150
 bool HlslLinker::emitReturnValue(const EGlslSymbolType retType, GlslFunction* funcMain, EShLanguage lang, std::stringstream& varying, std::stringstream& postamble)
1087 1151
 {
@@ -1128,54 +1192,7 @@ bool HlslLinker::emitReturnValue(const EGlslSymbolType retType, GlslFunction* fu
1128 1192
 	assert (retType == EgstStruct);
1129 1193
 	GlslStruct *retStruct = funcMain->getStruct();
1130 1194
 	assert (retStruct);
1131  
-	
1132  
-	const int elem = retStruct->memberCount();
1133  
-	for (int ii=0; ii<elem; ii++)
1134  
-	{
1135  
-		const GlslStruct::StructMember &current = retStruct->getMember(ii);
1136  
-		std::string name, ctor;
1137  
-		int pad;
1138  
-		int arraySize = 1;
1139  
-		bool isArray = false;
1140  
-		
1141  
-		if (lang == EShLangVertex) // vertex shader
1142  
-		{
1143  
-			// If it is an array, loop over each member
1144  
-			if ( current.arraySize > 0 )
1145  
-			{
1146  
-				arraySize = current.arraySize;
1147  
-				isArray = true;
1148  
-			}
1149  
-		}
1150  
-		
1151  
-		for (int idx = 0; idx < arraySize; ++idx)
1152  
-		{
1153  
-			if (!getArgumentData2( current.name, current.semantic, current.type, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad, idx))
1154  
-			{
1155  
-				infoSink.info << (lang==EShLangVertex ? "Unsupported element type in struct for shader return value (" : "Unsupported struct element type in return type for shader entry function (");
1156  
-				infoSink.info << getTypeString(current.type) << ")\n";
1157  
-				return false;
1158  
-			}
1159  
-			postamble << "    ";
1160  
-			postamble << name;                                                            
1161  
-			postamble << " = " << ctor;
1162  
-			postamble << "( xl_retval." << current.name;
1163  
-			if (isArray)
1164  
-			{
1165  
-				postamble << "[" << idx << "]";
1166  
-			}
1167  
-			for (int ii = 0; ii<pad; ii++)
1168  
-				postamble << ", 0.0";
1169  
-			
1170  
-			postamble << ");\n";
1171  
-			
1172  
-			// In vertex shader, add to varyings
1173  
-			if (lang == EShLangVertex)
1174  
-				AddToVaryings (varying, current.precision, ctor, name);
1175  
-		}
1176  
-	}
1177  
-	
1178  
-	return true;
  1195
+	return emitReturnStruct(retStruct, std::string("xl_retval."), lang, varying, postamble);
1179 1196
 }
1180 1197
 
1181 1198
 
1  hlslang/GLSLCodeGen/hlslLinker.h
@@ -77,6 +77,7 @@ class HlslLinker
77 77
 	void emitOutputStructParam(GlslSymbol* sym, EShLanguage lang, bool usePrecision, EAttribSemantic attrSem, std::stringstream& varying, std::stringstream& preamble, std::stringstream& postamble, std::stringstream& call);
78 78
 	void emitMainStart(const HlslCrossCompiler* compiler, const EGlslSymbolType retType, GlslFunction* funcMain, unsigned options, bool usePrecision, std::stringstream& preamble);
79 79
 	bool emitReturnValue(const EGlslSymbolType retType, GlslFunction* funcMain, EShLanguage lang, std::stringstream& varying, std::stringstream& postamble);
  80
+	bool emitReturnStruct(GlslStruct* retStruct, std::string parentName, EShLanguage lang, std::stringstream& varying, std::stringstream& postamble);
80 81
 	
81 82
 private:
82 83
 	TInfoSink& infoSink;
15  tests/vertex/return-struct-of-struct-in.txt
... ...
@@ -0,0 +1,15 @@
  1
+#line 1 "return-struct-of-struct-in.txt"
  2
+struct v2f_sub {
  3
+    float4 color : COLOR;
  4
+};
  5
+struct v2f {
  6
+    float4 pos : TEXCOORD;
  7
+    v2f_sub ss;
  8
+};
  9
+v2f main( in float4 pos : POSITION )
  10
+{
  11
+    v2f o;
  12
+    o.pos = pos;
  13
+    o.ss.color = pos;
  14
+    return o;
  15
+}
28  tests/vertex/return-struct-of-struct-out.txt
... ...
@@ -0,0 +1,28 @@
  1
+
  2
+#line 0
  3
+struct v2f_sub {
  4
+    vec4 color;
  5
+};
  6
+#line 4
  7
+struct v2f {
  8
+    vec4 pos;
  9
+    v2f_sub ss;
  10
+};
  11
+#line 8
  12
+v2f xlat_main( in vec4 pos );
  13
+#line 8
  14
+v2f xlat_main( in vec4 pos ) {
  15
+    v2f o;
  16
+    o.pos = pos;
  17
+    #line 12
  18
+    o.ss.color = pos;
  19
+    return o;
  20
+}
  21
+varying vec4 xlv_TEXCOORD;
  22
+varying vec4 xlv_COLOR;
  23
+void main() {
  24
+    v2f xl_retval;
  25
+    xl_retval = xlat_main( vec4(gl_Vertex));
  26
+    xlv_TEXCOORD = vec4(xl_retval.pos);
  27
+    xlv_COLOR = vec4(xl_retval.ss.color);
  28
+}
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.