Răsfoiți Sursa

Merge pull request #1690 from NickWaanders/master

shaderc_spirv now emitting sampler uniforms
Бранимир Караџић 6 ani în urmă
părinte
comite
0404f94745
1 a modificat fișierele cu 61 adăugiri și 21 ștergeri
  1. 61 21
      tools/shaderc/shaderc_spirv.cpp

+ 61 - 21
tools/shaderc/shaderc_spirv.cpp

@@ -16,6 +16,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
 #include <SPIRV/GlslangToSpv.h>
 #define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
 #include <spirv_msl.hpp>
+#include <spirv_reflect.hpp>
 #include <spirv-tools/optimizer.hpp>
 BX_PRAGMA_DIAGNOSTIC_POP()
 
@@ -583,6 +584,39 @@ namespace bgfx { namespace spirv
 		return bgfx::Attrib::Count;
 	}
 
+	static uint16_t writeUniformArray(bx::WriterI* _writer, const UniformArray& uniforms, bool isFragmentShader)
+	{
+		uint16_t size = 0;
+
+		uint16_t count = static_cast<uint16_t>(uniforms.size());
+		bx::write(_writer, count);
+
+		uint32_t fragmentBit = isFragmentShader ? BGFX_UNIFORM_FRAGMENTBIT : 0;
+		for (uint16_t ii = 0; ii < count; ++ii)
+		{
+			const Uniform& un = uniforms[ii];
+
+			size += un.regCount*16;
+
+			uint8_t nameSize = (uint8_t)un.name.size();
+			bx::write(_writer, nameSize);
+			bx::write(_writer, un.name.c_str(), nameSize);
+			bx::write(_writer, uint8_t(un.type | fragmentBit));
+			bx::write(_writer, un.num);
+			bx::write(_writer, un.regIndex);
+			bx::write(_writer, un.regCount);
+
+			BX_TRACE("%s, %s, %d, %d, %d"
+				, un.name.c_str()
+				, getUniformTypeName(un.type)
+				, un.num
+				, un.regIndex
+				, un.regCount
+			);
+		}
+		return size;
+	}
+
 	static bool compile(const Options& _options, uint32_t _version, const std::string& _code, bx::WriterI* _writer, bool _firstPass)
 	{
 		BX_UNUSED(_version);
@@ -674,8 +708,6 @@ namespace bgfx { namespace spirv
 			}
 			else
 			{
-				uint16_t size = 0;
-
 				program->buildReflection();
 
 				if (_firstPass)
@@ -733,11 +765,11 @@ namespace bgfx { namespace spirv
 					return compile(_options, _version, output.c_str(), _writer, false);
 				}
 
+				UniformArray uniforms;
+
 				{
 					uint16_t count = (uint16_t)program->getNumLiveUniformVariables();
-					bx::write(_writer, count);
 
-					uint32_t fragmentBit = _options.shaderType == 'f' ? BGFX_UNIFORM_FRAGMENTBIT : 0;
 					for (uint16_t ii = 0; ii < count; ++ii)
 					{
 						Uniform un;
@@ -769,23 +801,7 @@ namespace bgfx { namespace spirv
 							break;
 						}
 
-						size += un.regCount*16;
-
-						uint8_t nameSize = (uint8_t)un.name.size();
-						bx::write(_writer, nameSize);
-						bx::write(_writer, un.name.c_str(), nameSize);
-						bx::write(_writer, uint8_t(un.type | fragmentBit));
-						bx::write(_writer, un.num);
-						bx::write(_writer, un.regIndex);
-						bx::write(_writer, un.regCount);
-
-						BX_TRACE("%s, %s, %d, %d, %d"
-							, un.name.c_str()
-							, getUniformTypeName(un.type)
-							, un.num
-							, un.regIndex
-							, un.regCount
-						);
+						uniforms.push_back(un);
 					}
 				}
 				if (g_verbose)
@@ -823,6 +839,30 @@ namespace bgfx { namespace spirv
 					bx::MemoryReader reader(spirv.data(), uint32_t(spirv.size()*4) );
 					disassemble(writer, &reader, &err);
 
+					spirv_cross::CompilerReflection refl(spirv);
+					spirv_cross::ShaderResources resourcesrefl = refl.get_shader_resources();
+
+					// Loop through the separate_images, and extract the uniform names:
+					for (auto &resource : resourcesrefl.separate_images)
+					{
+						std::string name = refl.get_name(resource.id);
+						if (name.size() > 7 && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") )
+						{
+							auto uniform_name = name.substr(0, name.length() - 7);
+
+							Uniform un;
+							un.name = uniform_name;
+							un.type = UniformType::Sampler;
+
+							un.num = 0;			// needed?
+							un.regIndex = 0;	// needed?
+							un.regCount = 0;	// needed?
+
+							uniforms.push_back(un);
+						}
+					}
+					uint16_t size = writeUniformArray( _writer, uniforms, _options.shaderType == 'f');
+
 					if (_version == BX_MAKEFOURCC('M', 'T', 'L', 0))
 					{
 						if (g_verbose)