浏览代码

Add shader library notations

Panagiotis Christopoulos Charitos 5 年之前
父节点
当前提交
4eff844659

+ 5 - 2
shaders/RtShadows.ankiprog

@@ -3,6 +3,9 @@
 // Code licensed under the BSD License.
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 // http://www.anki3d.org/LICENSE
 
 
+#pragma anki library RtShadows
+#pragma anki sub_library Main
+
 #pragma anki mutator ALPHA_TEXTURE 0 1
 #pragma anki mutator ALPHA_TEXTURE 0 1
 
 
 #include <shaders/Common.glsl>
 #include <shaders/Common.glsl>
@@ -13,7 +16,7 @@ struct Payload
 	F32 m_shadowFactor;
 	F32 m_shadowFactor;
 };
 };
 
 
-#if defined(ALPHA_TEXTURE)
+#if ALPHA_TEXTURE == 1
 layout(set = 0, binding = 0, scalar) buffer b_ankiModelInstances
 layout(set = 0, binding = 0, scalar) buffer b_ankiModelInstances
 {
 {
 	ModelInstance u_ankiModelInstances[];
 	ModelInstance u_ankiModelInstances[];
@@ -36,7 +39,7 @@ ANKI_REF(Vertex, 4);
 
 
 void main()
 void main()
 {
 {
-#if defined(ALPHA_TEXTURE)
+#if ALPHA_TEXTURE == 1
 	const Mesh mesh = u_ankiModelInstances[nonuniformEXT(gl_InstanceID)].m_mesh;
 	const Mesh mesh = u_ankiModelInstances[nonuniformEXT(gl_InstanceID)].m_mesh;
 
 
 	const U32 offset = gl_PrimitiveID * ANKI_SIZEOF(U16Vec3);
 	const U32 offset = gl_PrimitiveID * ANKI_SIZEOF(U16Vec3);

+ 8 - 2
src/anki/shader_compiler/ShaderProgramBinary.h

@@ -252,8 +252,8 @@ public:
 	WeakArray<ShaderProgramBinaryOpaqueInstance> m_opaques;
 	WeakArray<ShaderProgramBinaryOpaqueInstance> m_opaques;
 	WeakArray<ShaderProgramBinaryConstantInstance> m_constants;
 	WeakArray<ShaderProgramBinaryConstantInstance> m_constants;
 	Array<U32, 3> m_workgroupSizes = {MAX_U32, MAX_U32, MAX_U32};
 	Array<U32, 3> m_workgroupSizes = {MAX_U32, MAX_U32, MAX_U32};
-	Array<U32, 3> m_workgroupSizesConstants = {
-		{MAX_U32, MAX_U32, MAX_U32}}; ///< Indices to ShaderProgramBinary::m_constants.
+	Array<U32, 3> m_workgroupSizesConstants = {MAX_U32, MAX_U32,
+											   MAX_U32}; ///< Indices to ShaderProgramBinary::m_constants.
 
 
 	template<typename TSerializer, typename TClass>
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	static void serializeCommon(TSerializer& s, TClass self)
@@ -381,6 +381,8 @@ public:
 	WeakArray<ShaderProgramBinaryOpaque> m_opaques;
 	WeakArray<ShaderProgramBinaryOpaque> m_opaques;
 	WeakArray<ShaderProgramBinaryConstant> m_constants;
 	WeakArray<ShaderProgramBinaryConstant> m_constants;
 	ShaderTypeBit m_presentShaderTypes = ShaderTypeBit::NONE;
 	ShaderTypeBit m_presentShaderTypes = ShaderTypeBit::NONE;
+	Array<char, 64> m_libraryName = {}; ///< The name of the shader library. Mainly for RT shaders.
+	Array<char, 64> m_subLibraryName = {}; ///< The name of the sub shader library. Mainly the ray type.
 
 
 	template<typename TSerializer, typename TClass>
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	static void serializeCommon(TSerializer& s, TClass self)
@@ -398,6 +400,10 @@ public:
 		s.doValue("m_constants", offsetof(ShaderProgramBinary, m_constants), self.m_constants);
 		s.doValue("m_constants", offsetof(ShaderProgramBinary, m_constants), self.m_constants);
 		s.doValue("m_presentShaderTypes", offsetof(ShaderProgramBinary, m_presentShaderTypes),
 		s.doValue("m_presentShaderTypes", offsetof(ShaderProgramBinary, m_presentShaderTypes),
 				  self.m_presentShaderTypes);
 				  self.m_presentShaderTypes);
+		s.doArray("m_libraryName", offsetof(ShaderProgramBinary, m_libraryName), &self.m_libraryName[0],
+				  self.m_libraryName.getSize());
+		s.doArray("m_subLibraryName", offsetof(ShaderProgramBinary, m_subLibraryName), &self.m_subLibraryName[0],
+				  self.m_subLibraryName.getSize());
 	}
 	}
 
 
 	template<typename TDeserializer>
 	template<typename TDeserializer>

+ 2 - 0
src/anki/shader_compiler/ShaderProgramBinary.xml

@@ -114,6 +114,8 @@
 				<member name="m_opaques" type="WeakArray&lt;ShaderProgramBinaryOpaque&gt;" />
 				<member name="m_opaques" type="WeakArray&lt;ShaderProgramBinaryOpaque&gt;" />
 				<member name="m_constants" type="WeakArray&lt;ShaderProgramBinaryConstant&gt;" />
 				<member name="m_constants" type="WeakArray&lt;ShaderProgramBinaryConstant&gt;" />
 				<member name="m_presentShaderTypes" type="ShaderTypeBit" constructor="= ShaderTypeBit::NONE" />
 				<member name="m_presentShaderTypes" type="ShaderTypeBit" constructor="= ShaderTypeBit::NONE" />
+				<member name="m_libraryName" type="char" array_size="64" constructor="= {}" comment="The name of the shader library. Mainly for RT shaders" />
+				<member name="m_subLibraryName" type="char" array_size="64" constructor="= {}" comment="The name of the sub shader library. Mainly the ray type" />
 			</members>
 			</members>
 		</class>
 		</class>
 	</classes>
 	</classes>

+ 24 - 1
src/anki/shader_compiler/ShaderProgramCompiler.cpp

@@ -13,7 +13,7 @@
 namespace anki
 namespace anki
 {
 {
 
 
-static const char* SHADER_BINARY_MAGIC = "ANKISDR2";
+static const char* SHADER_BINARY_MAGIC = "ANKISDR3";
 const U32 SHADER_BINARY_VERSION = 1;
 const U32 SHADER_BINARY_VERSION = 1;
 
 
 Error ShaderProgramBinaryWrapper::serializeToFile(CString fname) const
 Error ShaderProgramBinaryWrapper::serializeToFile(CString fname) const
@@ -982,6 +982,29 @@ Error compileShaderProgramInternal(CString fname, ShaderProgramFilesystemInterfa
 		binary.m_mutations.getBegin(), binary.m_mutations.getEnd(),
 		binary.m_mutations.getBegin(), binary.m_mutations.getEnd(),
 		[](const ShaderProgramBinaryMutation& a, const ShaderProgramBinaryMutation& b) { return a.m_hash < b.m_hash; });
 		[](const ShaderProgramBinaryMutation& a, const ShaderProgramBinaryMutation& b) { return a.m_hash < b.m_hash; });
 
 
+	// Lib name
+	if(parser.getLibraryName().getLength() > 0)
+	{
+		if(parser.getLibraryName().getLength() >= sizeof(binary.m_libraryName))
+		{
+			ANKI_SHADER_COMPILER_LOGE("Library name too long: %s", parser.getLibraryName().cstr());
+			return Error::USER_DATA;
+		}
+
+		memcpy(&binary.m_libraryName[0], &parser.getLibraryName()[0], parser.getLibraryName().getLength());
+	}
+
+	if(parser.getSubLibraryName().getLength() > 0)
+	{
+		if(parser.getSubLibraryName().getLength() >= sizeof(binary.m_subLibraryName))
+		{
+			ANKI_SHADER_COMPILER_LOGE("Sub library name too long: %s", parser.getSubLibraryName().cstr());
+			return Error::USER_DATA;
+		}
+
+		memcpy(&binary.m_subLibraryName[0], &parser.getSubLibraryName()[0], parser.getSubLibraryName().getLength());
+	}
+
 	// Misc
 	// Misc
 	binary.m_presentShaderTypes = parser.getShaderTypes();
 	binary.m_presentShaderTypes = parser.getShaderTypes();
 
 

+ 14 - 0
src/anki/shader_compiler/ShaderProgramDump.cpp

@@ -36,6 +36,19 @@ void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& huma
 	GenericMemoryPoolAllocator<U8> alloc = humanReadable.getAllocator();
 	GenericMemoryPoolAllocator<U8> alloc = humanReadable.getAllocator();
 	StringListAuto lines(alloc);
 	StringListAuto lines(alloc);
 
 
+	if(binary.m_libraryName[0])
+	{
+		lines.pushBack("**LIBRARY**\n");
+		lines.pushBackSprintf(ANKI_TAB "%s\n", &binary.m_libraryName[0]);
+
+		if(binary.m_subLibraryName[0])
+		{
+			lines.pushBackSprintf(ANKI_TAB "%s (sublibrary)\n", &binary.m_subLibraryName[0]);
+		}
+
+		lines.pushBack("\n");
+	}
+
 	lines.pushBack("**MUTATORS**\n");
 	lines.pushBack("**MUTATORS**\n");
 	if(binary.m_mutators.getSize() > 0)
 	if(binary.m_mutators.getSize() > 0)
 	{
 	{
@@ -60,6 +73,7 @@ void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& huma
 	{
 	{
 		spirv_cross::CompilerGLSL::Options options;
 		spirv_cross::CompilerGLSL::Options options;
 		options.vulkan_semantics = true;
 		options.vulkan_semantics = true;
+		options.version = 460;
 
 
 		const unsigned int* spvb = reinterpret_cast<const unsigned int*>(code.m_binary.getBegin());
 		const unsigned int* spvb = reinterpret_cast<const unsigned int*>(code.m_binary.getBegin());
 		ANKI_ASSERT((code.m_binary.getSize() % (sizeof(unsigned int))) == 0);
 		ANKI_ASSERT((code.m_binary.getSize() % (sizeof(unsigned int))) == 0);

+ 65 - 1
src/anki/shader_compiler/ShaderProgramParser.cpp

@@ -476,6 +476,46 @@ Error ShaderProgramParser::parsePragmaMutator(const StringAuto* begin, const Str
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
+Error ShaderProgramParser::parsePragmaLibraryName(const StringAuto* begin, const StringAuto* end, CString line,
+												  CString fname)
+{
+	ANKI_ASSERT(begin && end);
+
+	if(begin >= end)
+	{
+		ANKI_PP_ERROR_MALFORMED();
+	}
+
+	if(m_libName.getLength() > 0)
+	{
+		ANKI_PP_ERROR_MALFORMED_MSG("Library name already set");
+	}
+
+	m_libName = *begin;
+
+	return Error::NONE;
+}
+
+Error ShaderProgramParser::parsePragmaSubLibraryName(const StringAuto* begin, const StringAuto* end, CString line,
+													 CString fname)
+{
+	ANKI_ASSERT(begin && end);
+
+	if(begin >= end)
+	{
+		ANKI_PP_ERROR_MALFORMED();
+	}
+
+	if(m_sublibName.getLength() > 0)
+	{
+		ANKI_PP_ERROR_MALFORMED_MSG("Sub library name already set");
+	}
+
+	m_sublibName = *begin;
+
+	return Error::NONE;
+}
+
 Error ShaderProgramParser::parsePragmaRewriteMutation(const StringAuto* begin, const StringAuto* end, CString line,
 Error ShaderProgramParser::parsePragmaRewriteMutation(const StringAuto* begin, const StringAuto* end, CString line,
 													  CString fname)
 													  CString fname)
 {
 {
@@ -725,6 +765,14 @@ Error ShaderProgramParser::parseLine(CString line, CString fname, Bool& foundPra
 			{
 			{
 				ANKI_CHECK(parsePragmaRewriteMutation(token + 1, end, line, fname));
 				ANKI_CHECK(parsePragmaRewriteMutation(token + 1, end, line, fname));
 			}
 			}
+			else if(*token == "library")
+			{
+				ANKI_CHECK(parsePragmaLibraryName(token + 1, end, line, fname));
+			}
+			else if(*token == "sub_library")
+			{
+				ANKI_CHECK(parsePragmaSubLibraryName(token + 1, end, line, fname));
+			}
 			else
 			else
 			{
 			{
 				ANKI_PP_ERROR_MALFORMED();
 				ANKI_PP_ERROR_MALFORMED();
@@ -841,8 +889,24 @@ Error ShaderProgramParser::parse()
 	{
 	{
 		m_codeLines.join("\n", m_codeSource);
 		m_codeLines.join("\n", m_codeSource);
 		m_codeLines.destroy();
 		m_codeLines.destroy();
+	}
+
+	// Create the hash
+	{
+		if(m_codeLines.getSize())
+		{
+			m_codeSourceHash = appendHash(m_codeSource.getBegin(), m_codeSource.getLength(), SHADER_HEADER_HASH);
+		}
 
 
-		m_codeSourceHash = appendHash(m_codeSource.getBegin(), m_codeSource.getLength(), SHADER_HEADER_HASH);
+		if(m_libName.getLength() > 0)
+		{
+			m_codeSourceHash = appendHash(m_libName.getBegin(), m_libName.getLength(), m_codeSourceHash);
+		}
+
+		if(m_sublibName.getLength() > 0)
+		{
+			m_codeSourceHash = appendHash(m_sublibName.getBegin(), m_sublibName.getLength(), m_codeSourceHash);
+		}
 	}
 	}
 
 
 	return Error::NONE;
 	return Error::NONE;

+ 19 - 0
src/anki/shader_compiler/ShaderProgramParser.h

@@ -83,6 +83,8 @@ private:
 ///                               NAME_A VALUE4 NAME_B VALUE5 [NAME_C VALUE6...]
 ///                               NAME_A VALUE4 NAME_B VALUE5 [NAME_C VALUE6...]
 /// #pragma anki start {vert | tessc | tesse | geom | frag | comp | rgen | ahit | chit | miss | int | call}
 /// #pragma anki start {vert | tessc | tesse | geom | frag | comp | rgen | ahit | chit | miss | int | call}
 /// #pragma anki end
 /// #pragma anki end
+/// #pragma anki library "name"
+/// #pragma anki sub_library "name"
 ///
 ///
 /// Only the "anki input" should be in an ifdef-like guard. For everything else it's ignored.
 /// Only the "anki input" should be in an ifdef-like guard. For everything else it's ignored.
 class ShaderProgramParser : public NonCopyable
 class ShaderProgramParser : public NonCopyable
@@ -120,6 +122,16 @@ public:
 		return m_codeSourceHash;
 		return m_codeSourceHash;
 	}
 	}
 
 
+	CString getLibraryName() const
+	{
+		return m_libName;
+	}
+
+	CString getSubLibraryName() const
+	{
+		return m_sublibName;
+	}
+
 	/// Generates the common header that will be used by all AnKi shaders.
 	/// Generates the common header that will be used by all AnKi shaders.
 	static void generateAnkiShaderHeader(ShaderType shaderType, const GpuDeviceCapabilities& caps,
 	static void generateAnkiShaderHeader(ShaderType shaderType, const GpuDeviceCapabilities& caps,
 										 const BindlessLimits& limits, StringAuto& header);
 										 const BindlessLimits& limits, StringAuto& header);
@@ -170,6 +182,9 @@ private:
 	GpuDeviceCapabilities m_gpuCapabilities;
 	GpuDeviceCapabilities m_gpuCapabilities;
 	BindlessLimits m_bindlessLimits;
 	BindlessLimits m_bindlessLimits;
 
 
+	StringAuto m_libName = {m_alloc};
+	StringAuto m_sublibName = {m_alloc};
+
 	ANKI_USE_RESULT Error parseFile(CString fname, U32 depth);
 	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 parseLine(CString line, CString fname, Bool& foundPragmaOnce, U32 depth);
 	ANKI_USE_RESULT Error parseInclude(const StringAuto* begin, const StringAuto* end, CString line, CString fname,
 	ANKI_USE_RESULT Error parseInclude(const StringAuto* begin, const StringAuto* end, CString line, CString fname,
@@ -180,6 +195,10 @@ private:
 	ANKI_USE_RESULT Error parsePragmaEnd(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
 	ANKI_USE_RESULT Error parsePragmaEnd(const StringAuto* begin, const StringAuto* end, CString line, CString fname);
 	ANKI_USE_RESULT Error parsePragmaRewriteMutation(const StringAuto* begin, const StringAuto* end, CString line,
 	ANKI_USE_RESULT Error parsePragmaRewriteMutation(const StringAuto* begin, const StringAuto* end, CString line,
 													 CString fname);
 													 CString fname);
+	ANKI_USE_RESULT Error parsePragmaLibraryName(const StringAuto* begin, const StringAuto* end, CString line,
+												 CString fname);
+	ANKI_USE_RESULT Error parsePragmaSubLibraryName(const StringAuto* begin, const StringAuto* end, CString line,
+													CString fname);
 
 
 	void tokenizeLine(CString line, DynamicArrayAuto<StringAuto>& tokens) const;
 	void tokenizeLine(CString line, DynamicArrayAuto<StringAuto>& tokens) const;
 
 

+ 21 - 0
src/anki/shader_compiler/ShaderProgramReflection.cpp

@@ -16,12 +16,33 @@ static ShaderVariableDataType spirvcrossBaseTypeToAnki(spirv_cross::SPIRType::Ba
 
 
 	switch(cross)
 	switch(cross)
 	{
 	{
+	case spirv_cross::SPIRType::SByte:
+		out = ShaderVariableDataType::I8;
+		break;
+	case spirv_cross::SPIRType::UByte:
+		out = ShaderVariableDataType::U8;
+		break;
+	case spirv_cross::SPIRType::Short:
+		out = ShaderVariableDataType::I16;
+		break;
+	case spirv_cross::SPIRType::UShort:
+		out = ShaderVariableDataType::U16;
+		break;
 	case spirv_cross::SPIRType::Int:
 	case spirv_cross::SPIRType::Int:
 		out = ShaderVariableDataType::I32;
 		out = ShaderVariableDataType::I32;
 		break;
 		break;
 	case spirv_cross::SPIRType::UInt:
 	case spirv_cross::SPIRType::UInt:
 		out = ShaderVariableDataType::U32;
 		out = ShaderVariableDataType::U32;
 		break;
 		break;
+	case spirv_cross::SPIRType::Int64:
+		out = ShaderVariableDataType::I64;
+		break;
+	case spirv_cross::SPIRType::UInt64:
+		out = ShaderVariableDataType::U64;
+		break;
+	case spirv_cross::SPIRType::Half:
+		out = ShaderVariableDataType::F16;
+		break;
 	case spirv_cross::SPIRType::Float:
 	case spirv_cross::SPIRType::Float:
 		out = ShaderVariableDataType::F32;
 		out = ShaderVariableDataType::F32;
 		break;
 		break;

+ 3 - 7
src/anki/util/String.h

@@ -204,8 +204,7 @@ public:
 	/// Get the string length.
 	/// Get the string length.
 	U32 getLength() const
 	U32 getLength() const
 	{
 	{
-		checkInit();
-		return U32(std::strlen(m_ptr));
+		return (m_ptr == nullptr) ? 0 : U32(std::strlen(m_ptr));
 	}
 	}
 
 
 	PtrSize find(const CString& cstr, PtrSize position = 0) const
 	PtrSize find(const CString& cstr, PtrSize position = 0) const
@@ -497,12 +496,9 @@ public:
 	}
 	}
 
 
 	/// Return the string's length. It doesn't count the terminating character.
 	/// Return the string's length. It doesn't count the terminating character.
-	PtrSize getLength() const
+	U32 getLength() const
 	{
 	{
-		auto size = m_data.getSize();
-		auto out = (size != 0) ? (size - 1) : 0;
-		ANKI_ASSERT(size == 0 || std::strlen(&m_data[0]) == out);
-		return out;
+		return (m_data.getSize() == 0) ? 0 : U32(std::strlen(&m_data[0]));
 	}
 	}
 
 
 	/// Return the CString.
 	/// Return the CString.