Explorar o código

shaderc: Output Metal uniform reflection data.

Branimir Karadžić %!s(int64=9) %!d(string=hai) anos
pai
achega
1d0be51615
Modificáronse 2 ficheiros con 69 adicións e 8 borrados
  1. 9 8
      tools/shaderc/shaderc.cpp
  2. 60 0
      tools/shaderc/shaderc_glsl.cpp

+ 9 - 8
tools/shaderc/shaderc.cpp

@@ -113,14 +113,15 @@ namespace bgfx
 		NULL
 	};
 
-	const char* s_uniformTypeName[UniformType::Count] =
+	const char* s_uniformTypeName[] =
 	{
-		"int",
-		NULL,
-		"vec4",
-		"mat3",
-		"mat4",
+		"int",  "int",
+		NULL,   NULL,
+		"vec4", "float4",
+		"mat3", "float3x3",
+		"mat4", "float4x4",
 	};
+	BX_STATIC_ASSERT(BX_COUNTOF(s_uniformTypeName) == UniformType::Count*2);
 
 	const char* interpolationDx11(const char* _glsl)
 	{
@@ -149,12 +150,12 @@ namespace bgfx
 
 	UniformType::Enum nameToUniformTypeEnum(const char* _name)
 	{
-		for (uint32_t ii = 0; ii < UniformType::Count; ++ii)
+		for (uint32_t ii = 0; ii < UniformType::Count*2; ++ii)
 		{
 			if (NULL != s_uniformTypeName[ii]
 			&&  0 == strcmp(_name, s_uniformTypeName[ii]) )
 			{
-				return UniformType::Enum(ii);
+				return UniformType::Enum(ii/2);
 			}
 		}
 

+ 60 - 0
tools/shaderc/shaderc_glsl.cpp

@@ -91,6 +91,7 @@ namespace bgfx { namespace glsl
 
 		UniformArray uniforms;
 
+		if (target != kGlslTargetMetal)
 		{
 			const char* parse = optimizedShader;
 
@@ -181,6 +182,65 @@ namespace bgfx { namespace glsl
 				}
 			}
 		}
+		else
+		{
+			const char* parse = strstr(optimizedShader, "struct xlatMtlShaderUniform {");
+			const char* end   = parse;
+			if (NULL != parse)
+			{
+				parse += strlen("struct xlatMtlShaderUniform {");
+				end   = strstr(parse, "};");
+			}
+
+			while ( parse < end
+			&&     *parse != '\0')
+			{
+				parse = bx::strws(parse);
+				const char* eol = strchr(parse, ';');
+				if (NULL != eol)
+				{
+					const char* typen = parse;
+
+					char uniformType[256];
+					parse = bx::strword(parse);
+					bx::strlcpy(uniformType, typen, parse-typen+1);
+					const char* name = parse = bx::strws(parse);
+
+					char uniformName[256];
+					uint8_t num = 1;
+					const char* array = bx::strnstr(name, "[", eol-parse);
+					if (NULL != array)
+					{
+						bx::strlcpy(uniformName, name, array-name+1);
+
+						char arraySize[32];
+						const char* end = bx::strnstr(array, "]", eol-array);
+						bx::strlcpy(arraySize, array+1, end-array);
+						num = uint8_t(atoi(arraySize) );
+					}
+					else
+					{
+						bx::strlcpy(uniformName, name, eol-name+1);
+					}
+
+					Uniform un;
+					un.type = nameToUniformTypeEnum(uniformType);
+
+					if (UniformType::Count != un.type)
+					{
+						BX_TRACE("name: %s (type %d, num %d)", uniformName, un.type, num);
+
+						un.name = uniformName;
+						un.num = num;
+						un.regIndex = 0;
+						un.regCount = num;
+						uniforms.push_back(un);
+					}
+
+					parse = eol + 1;
+				}
+			}
+		}
 
 		uint16_t count = (uint16_t)uniforms.size();
 		bx::write(_writer, count);