Browse Source

Choose what shaders would reflect

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
8f3fd99c47

+ 21 - 5
AnKi/ShaderCompiler/ShaderProgramCompiler.cpp

@@ -320,6 +320,7 @@ class Refl final : public ShaderReflectionVisitorInterface
 {
 public:
 	GenericMemoryPoolAllocator<U8> m_alloc;
+	const StringList* m_symbolsToReflect = nullptr;
 
 	/// Will be stored in the binary
 	/// @{
@@ -348,8 +349,9 @@ public:
 	Array<U32, 3> m_workgroupSizesConstants = {MAX_U32, MAX_U32, MAX_U32};
 	/// @}
 
-	Refl(const GenericMemoryPoolAllocator<U8>& alloc)
+	Refl(const GenericMemoryPoolAllocator<U8>& alloc, const StringList* symbolsToReflect)
 		: m_alloc(alloc)
+		, m_symbolsToReflect(symbolsToReflect)
 	{
 	}
 
@@ -477,6 +479,20 @@ public:
 		return Error::NONE;
 	}
 
+	Bool skipSymbol(CString symbol) const final
+	{
+		Bool skip = true;
+		for(const String& s : *m_symbolsToReflect)
+		{
+			if(symbol == s)
+			{
+				skip = false;
+				break;
+			}
+		}
+		return skip;
+	}
+
 	Error visitConstant(U32 instanceIdx, CString name, ShaderVariableDataType type, U32 constantId) final
 	{
 		// Find const
@@ -632,12 +648,12 @@ public:
 	}
 };
 
-static Error doReflection(ShaderProgramBinary& binary, GenericMemoryPoolAllocator<U8>& tmpAlloc,
-						  GenericMemoryPoolAllocator<U8>& binaryAlloc)
+static Error doReflection(const StringList& symbolsToReflect, ShaderProgramBinary& binary,
+						  GenericMemoryPoolAllocator<U8>& tmpAlloc, GenericMemoryPoolAllocator<U8>& binaryAlloc)
 {
 	ANKI_ASSERT(binary.m_variants.getSize() > 0);
 
-	Refl refl(binaryAlloc);
+	Refl refl(binaryAlloc, &symbolsToReflect);
 
 	for(ShaderProgramBinaryVariant& variant : binary.m_variants)
 	{
@@ -999,7 +1015,7 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 	binary.m_presentShaderTypes = parser.getShaderTypes();
 
 	// Reflection
-	ANKI_CHECK(doReflection(binary, tempAllocator, binaryAllocator));
+	ANKI_CHECK(doReflection(parser.getSymbolsToReflect(), binary, tempAllocator, binaryAllocator));
 
 	return Error::NONE;
 }

+ 19 - 0
AnKi/ShaderCompiler/ShaderProgramParser.cpp

@@ -526,6 +526,21 @@ Error ShaderProgramParser::parsePragmaRayType(const StringAuto* begin, const Str
 	return Error::NONE;
 }
 
+Error ShaderProgramParser::parsePragmaReflect(const StringAuto* begin, const StringAuto* end, CString line,
+											  CString fname)
+{
+	ANKI_ASSERT(begin && end);
+
+	if(begin >= end)
+	{
+		ANKI_PP_ERROR_MALFORMED();
+	}
+
+	m_symbolsToReflect.pushBack(*begin);
+
+	return Error::NONE;
+}
+
 Error ShaderProgramParser::parsePragmaRewriteMutation(const StringAuto* begin, const StringAuto* end, CString line,
 													  CString fname)
 {
@@ -791,6 +806,10 @@ Error ShaderProgramParser::parseLine(CString line, CString fname, Bool& foundPra
 			{
 				ANKI_CHECK(parsePragmaRayType(token + 1, end, line, fname));
 			}
+			else if(*token == "reflect")
+			{
+				ANKI_CHECK(parsePragmaReflect(token + 1, end, line, fname));
+			}
 			else
 			{
 				ANKI_PP_ERROR_MALFORMED();

+ 10 - 0
AnKi/ShaderCompiler/ShaderProgramParser.h

@@ -85,6 +85,7 @@ private:
 /// #pragma anki end
 /// #pragma anki library "name"
 /// #pragma anki ray_type NUMBER
+/// #pragma anki reflect NAME
 ///
 /// Only the "anki input" should be in an ifdef-like guard. For everything else it's ignored.
 class ShaderProgramParser
@@ -136,6 +137,11 @@ public:
 		return m_rayType;
 	}
 
+	const StringListAuto& getSymbolsToReflect() const
+	{
+		return m_symbolsToReflect;
+	}
+
 	/// Generates the common header that will be used by all AnKi shaders.
 	static void generateAnkiShaderHeader(ShaderType shaderType, const ShaderCompilerOptions& compilerOptions,
 										 StringAuto& header);
@@ -188,6 +194,8 @@ private:
 	StringAuto m_libName = {m_alloc};
 	U32 m_rayType = MAX_U32;
 
+	StringListAuto m_symbolsToReflect = {m_alloc};
+
 	ANKI_USE_RESULT Error parseFile(CString fname, U32 depth);
 	ANKI_USE_RESULT Error parseLine(CString line, CString fname, Bool& foundPragmaOnce, U32 depth);
 	ANKI_USE_RESULT Error parseInclude(const StringAuto* begin, const StringAuto* end, CString line, CString fname,
@@ -202,6 +210,8 @@ private:
 												 CString fname);
 	ANKI_USE_RESULT Error parsePragmaRayType(const StringAuto* begin, const StringAuto* end, CString line,
 											 CString fname);
+	ANKI_USE_RESULT Error parsePragmaReflect(const StringAuto* begin, const StringAuto* end, CString line,
+											 CString fname);
 
 	void tokenizeLine(CString line, DynamicArrayAuto<StringAuto>& tokens) const;
 

+ 17 - 2
AnKi/ShaderCompiler/ShaderProgramReflection.cpp

@@ -57,9 +57,11 @@ static ShaderVariableDataType spirvcrossBaseTypeToAnki(spirv_cross::SPIRType::Ba
 class SpirvReflector : public spirv_cross::Compiler
 {
 public:
-	SpirvReflector(const U32* ir, PtrSize wordCount, const GenericMemoryPoolAllocator<U8>& tmpAlloc)
+	SpirvReflector(const U32* ir, PtrSize wordCount, const GenericMemoryPoolAllocator<U8>& tmpAlloc,
+				   ShaderReflectionVisitorInterface* interface)
 		: spirv_cross::Compiler(ir, wordCount)
 		, m_alloc(tmpAlloc)
+		, m_interface(interface)
 	{
 	}
 
@@ -126,6 +128,7 @@ private:
 	};
 
 	GenericMemoryPoolAllocator<U8> m_alloc;
+	ShaderReflectionVisitorInterface* m_interface = nullptr;
 
 	ANKI_USE_RESULT Error spirvTypeToAnki(const spirv_cross::SPIRType& type, ShaderVariableDataType& out) const;
 
@@ -329,6 +332,12 @@ Error SpirvReflector::blockReflection(const spirv_cross::Resource& res, Bool isS
 			ANKI_SHADER_COMPILER_LOGE("Can't accept zero name length");
 			return Error::USER_DATA;
 		}
+
+		if(m_interface->skipSymbol(name.c_str()))
+		{
+			return Error::NONE;
+		}
+
 		newBlock.m_name.create(name.c_str());
 	}
 
@@ -450,6 +459,12 @@ Error SpirvReflector::opaqueReflection(const spirv_cross::Resource& res, Dynamic
 		ANKI_SHADER_COMPILER_LOGE("Can't accept zero length name");
 		return Error::USER_DATA;
 	}
+
+	if(m_interface->skipSymbol(name.c_str()))
+	{
+		return Error::NONE;
+	}
+
 	newOpaque.m_name.create(name.c_str());
 
 	// Type
@@ -652,7 +667,7 @@ Error SpirvReflector::performSpirvReflection(Array<ConstWeakArray<U8>, U32(Shade
 
 		// Parse SPIR-V
 		const unsigned int* spvb = reinterpret_cast<const unsigned int*>(spirv[type].getBegin());
-		SpirvReflector compiler(spvb, spirv[type].getSizeInBytes() / sizeof(unsigned int), tmpAlloc);
+		SpirvReflector compiler(spvb, spirv[type].getSizeInBytes() / sizeof(unsigned int), tmpAlloc, &interface);
 
 		// Uniform blocks
 		for(const spirv_cross::Resource& res : compiler.get_shader_resources().uniform_buffers)

+ 2 - 0
AnKi/ShaderCompiler/ShaderProgramReflection.h

@@ -46,6 +46,8 @@ public:
 											  U32 arraySize) = 0;
 
 	virtual ANKI_USE_RESULT Error visitConstant(U32 idx, CString name, ShaderVariableDataType type, U32 constantId) = 0;
+
+	virtual ANKI_USE_RESULT Bool skipSymbol(CString symbol) const = 0;
 };
 
 /// Does reflection using SPIR-V.

+ 1 - 0
AnKi/Shaders/ForwardShadingFog.ankiprog

@@ -12,6 +12,7 @@ struct PerDraw
 	F32 m_fogDistanceOfMaxThikness;
 };
 
+#pragma anki reflect b_ankiPerDraw
 layout(set = 1, binding = 0, row_major) uniform b_ankiPerDraw
 {
 	PerDraw u_ankiPerDraw;

+ 4 - 0
AnKi/Shaders/ForwardShadingParticles.ankiprog

@@ -17,16 +17,20 @@ struct PerDraw
 	Vec4 m_colorBias;
 };
 
+#pragma anki reflect b_ankiPerDraw
 layout(set = 1, binding = 0, row_major) uniform b_ankiPerDraw
 {
 	PerDraw u_ankiPerDraw;
 };
 
+#pragma anki reflect u_ankiGlobalSampler
 layout(set = 1, binding = 1) uniform sampler u_ankiGlobalSampler;
 #if ANIMATED_TEXTURE == 0
+#	pragma anki reflect u_diffuseMap
 layout(set = 1, binding = 2) uniform texture2D u_diffuseMap;
 #endif
 #if ANIMATED_TEXTURE == 1
+#	pragma anki reflect u_diffuseMapArr
 layout(set = 1, binding = 2) uniform texture2DArray u_diffuseMapArr;
 #endif
 

+ 12 - 0
AnKi/Shaders/GBufferGeneric.ankiprog

@@ -41,31 +41,39 @@
 
 #include <AnKi/Shaders/GBufferCommon.glsl>
 
+#pragma anki reflect u_ankiGlobalSampler
 layout(set = 0, binding = 2) uniform sampler u_ankiGlobalSampler;
 #if DIFFUSE_TEX == 1 && ANKI_PASS == PASS_GB
+#	pragma anki reflect u_diffTex
 layout(set = 0, binding = 3) uniform texture2D u_diffTex;
 #	define USING_DIFF_TEX 1
 #endif
 #if SPECULAR_TEX == 1 && ANKI_PASS == PASS_GB
+#	pragma anki reflect u_specTex
 layout(set = 0, binding = 4) uniform texture2D u_specTex;
 #	define USING_SPECULAR_TEX 1
 #endif
 #if ROUGHNESS_TEX == 1 && ANKI_PASS == PASS_GB
+#	pragma anki reflect u_roughnessTex
 layout(set = 0, binding = 5) uniform texture2D u_roughnessTex;
 #	define USING_ROUGHNESS_TEX 1
 #endif
 #if NORMAL_TEX == 1 && ANKI_PASS == PASS_GB && ANKI_LOD < 2
+#	pragma anki reflect u_normalTex
 layout(set = 0, binding = 6) uniform texture2D u_normalTex;
 #	define USING_NORMAL_TEX 1
 #endif
 #if METAL_TEX == 1 && ANKI_PASS == PASS_GB
+#	pragma anki reflect u_metallicTex
 layout(set = 0, binding = 7) uniform texture2D u_metallicTex;
 #	define USING_METALLIC_TEX 1
 #endif
 #if REALLY_USING_PARALLAX
+#	pragma anki reflect u_heightTex
 layout(set = 0, binding = 8) uniform texture2D u_heightTex;
 #endif
 #if EMISSIVE_TEX == 1 && ANKI_PASS == PASS_GB
+#	pragma anki reflect u_emissiveTex
 layout(set = 0, binding = 9) uniform texture2D u_emissiveTex;
 #	define USING_EMISSIVE_TEX 1
 #endif
@@ -112,23 +120,27 @@ struct PerInstance
 };
 
 #if ANKI_PASS == PASS_GB
+#	pragma anki reflect b_ankiPerDraw
 layout(set = 0, binding = 0, row_major, std140) uniform b_ankiPerDraw
 {
 	PerDraw u_ankiPerDraw;
 };
 #endif
 
+#pragma anki reflect b_ankiPerInstance
 layout(set = 0, binding = 1, row_major, std140) uniform b_ankiPerInstance
 {
 	PerInstance u_ankiPerInstance[MAX_INSTANCE_COUNT];
 };
 
 #if ANKI_BONES
+#	pragma anki reflect b_ankiBoneTransforms
 layout(set = 0, binding = 10, row_major, std140) readonly buffer b_ankiBoneTransforms
 {
 	Mat4 u_ankiBoneTransforms[];
 };
 
+#	pragma anki reflect b_ankiPrevFrameBoneTransforms
 layout(set = 0, binding = 11, row_major, std140) readonly buffer b_ankiPrevFrameBoneTransforms
 {
 	Mat4 u_ankiPrevFrameBoneTransforms[];

+ 1 - 0
AnKi/Shaders/GBufferGpuParticles.ankiprog

@@ -19,6 +19,7 @@ struct PerDraw
 	Vec3 m_finalEmission;
 };
 
+#pragma anki reflect b_ankiPerDraw
 layout(set = 0, binding = 0, std140, row_major) uniform b_ankiPerDraw
 {
 	PerDraw u_ankiPerDraw;