Pārlūkot izejas kodu

Add some functionality to the shader compiler to dump shader source

Panagiotis Christopoulos Charitos 6 gadi atpakaļ
vecāks
revīzija
dd1f72b46c

+ 1 - 2
shaders/LightShading.glslp

@@ -233,10 +233,9 @@ void main()
 		if(subgroupAllEqual(crntProbeIdx)
 			&& subgroupAll(crntProbeIdx != MAX_U32 && u_lightIndices[idxOffset + 1u] == MAX_U32))
 		{
-			// All sugroups point to the same probe and there is only one probe, do a fast path without blend weight
+			// All subgroups point to the same probe and there is only one probe, do a fast path without blend weight
 
 			GlobalIlluminationProbe probe = u_giProbes[subgroupBroadcastFirst(crntProbeIdx)]; // It should be uniform
-			idxOffset += 2u;
 
 			// Sample
 			diffIndirect = sampleGlobalIllumination(

+ 1 - 0
src/anki/core/Config.cpp

@@ -74,6 +74,7 @@ Config::Config()
 
 	// Resource
 	newOption("rsrc.maxTextureSize", 1024 * 1024);
+	newOption("rsrc.dumpShaderSources", false);
 	newOption("rsrc.dataPaths", ".", "The engine loads assets only in from these paths. Separate them with :");
 	newOption("rsrc.transferScratchMemorySize", 256_MB);
 

+ 26 - 21
src/anki/gr/ShaderCompiler.cpp

@@ -382,7 +382,10 @@ Error ShaderCompiler::preprocess(
 	return Error::NONE;
 }
 
-Error ShaderCompiler::compile(CString source, const ShaderCompilerOptions& options, DynamicArrayAuto<U8>& bin) const
+Error ShaderCompiler::compile(CString source,
+	const ShaderCompilerOptions& options,
+	DynamicArrayAuto<U8>& bin,
+	CString finalSourceDumpFilename) const
 {
 	ANKI_ASSERT(!source.isEmpty() && source.getLength() > 0);
 	Error err = Error::NONE;
@@ -421,23 +424,13 @@ Error ShaderCompiler::compile(CString source, const ShaderCompilerOptions& optio
 		ANKI_CHECK(genSpirv(finalSrc.toCString(), options, bin));
 	}
 
-#if 0
 	// Dump
+	if(finalSourceDumpFilename)
 	{
-		static I id = 0;
-
-		String homeDir;
-		ANKI_CHECK(getHomeDirectory(m_alloc, homeDir));
-
 		File file;
-		ANKI_CHECK(
-			file.open(StringAuto(m_alloc).sprintf("%s/.anki/cache/%d.dump.glsl", homeDir.cstr(), id++).toCString(),
-				FileOpenFlag::WRITE));
-		ANKI_CHECK(file.write(finalSrc.cstr(), finalSrc.getLength() + 1));
-
-		homeDir.destroy(m_alloc);
+		ANKI_CHECK(file.open(finalSourceDumpFilename, FileOpenFlag::WRITE));
+		ANKI_CHECK(file.write(finalSrc.cstr(), finalSrc.getLength() - 1));
 	}
-#endif
 
 	return err;
 }
@@ -478,10 +471,13 @@ void ShaderCompiler::logShaderErrorCode(CString error, CString source, GenericMe
 		&error[0]);
 }
 
-Error ShaderCompilerCache::compile(
-	CString source, U64* hash, const ShaderCompilerOptions& options, DynamicArrayAuto<U8>& bin) const
+Error ShaderCompilerCache::compile(CString source,
+	U64* hash,
+	const ShaderCompilerOptions& options,
+	DynamicArrayAuto<U8>& bin,
+	Bool dumpShaderSource) const
 {
-	Error err = compileInternal(source, hash, options, bin);
+	const Error err = compileInternal(source, hash, options, bin, dumpShaderSource);
 	if(err)
 	{
 		ANKI_GR_LOGE("Failed to compile or retrieve shader from the cache");
@@ -490,8 +486,11 @@ Error ShaderCompilerCache::compile(
 	return err;
 }
 
-Error ShaderCompilerCache::compileInternal(
-	CString source, U64* hash, const ShaderCompilerOptions& options, DynamicArrayAuto<U8>& bin) const
+Error ShaderCompilerCache::compileInternal(CString source,
+	U64* hash,
+	const ShaderCompilerOptions& options,
+	DynamicArrayAuto<U8>& bin,
+	Bool dumpShaderSource) const
 {
 	ANKI_ASSERT(!source.isEmpty() && source.getLength() > 0);
 
@@ -524,11 +523,17 @@ Error ShaderCompilerCache::compileInternal(
 	else
 	{
 		ANKI_GR_LOGI("%s not found in cache. Will compile", fname.cstr());
-		ANKI_CHECK(m_compiler.compile(source, options, bin));
+
+		StringAuto dumpSrcFname(m_alloc);
+		if(dumpShaderSource)
+		{
+			dumpSrcFname.sprintf("%s/%llu.glsl", m_cacheDir.cstr(), fhash);
+		}
+
+		ANKI_CHECK(m_compiler.compile(source, options, bin, (dumpSrcFname) ? dumpSrcFname.toCString() : CString()));
 
 		File file;
 		ANKI_CHECK(file.open(fname.toCString(), FileOpenFlag::WRITE | FileOpenFlag::BINARY));
-
 		ANKI_CHECK(file.write(&bin[0], bin.getSize()));
 	}
 

+ 16 - 6
src/anki/gr/ShaderCompiler.h

@@ -56,8 +56,11 @@ public:
 	/// @param source The source in GLSL.
 	/// @param options Compile options.
 	/// @param bin The output binary.
-	ANKI_USE_RESULT Error compile(
-		CString source, const ShaderCompilerOptions& options, DynamicArrayAuto<U8>& bin) const;
+	/// @param finalSourceDumpFilename Write the final source to this filename if it's not empty.
+	ANKI_USE_RESULT Error compile(CString source,
+		const ShaderCompilerOptions& options,
+		DynamicArrayAuto<U8>& bin,
+		CString finalSourceDumpFilename = {}) const;
 
 	ANKI_USE_RESULT Error preprocess(
 		CString source, const ShaderCompilerOptions& options, const StringList& defines, StringAuto& out) const;
@@ -99,16 +102,23 @@ public:
 	/// @param sourceHash Optional hash of the source. If it's nullptr then the @a source will be hashed.
 	/// @param options Compile options.
 	/// @param bin The output binary.
-	ANKI_USE_RESULT Error compile(
-		CString source, U64* hash, const ShaderCompilerOptions& options, DynamicArrayAuto<U8>& bin) const;
+	/// @param dumpShaderSource If true dump the shaders' source as well.
+	ANKI_USE_RESULT Error compile(CString source,
+		U64* hash,
+		const ShaderCompilerOptions& options,
+		DynamicArrayAuto<U8>& bin,
+		Bool dumpShaderSource = false) const;
 
 private:
 	GenericMemoryPoolAllocator<U8> m_alloc;
 	ShaderCompiler m_compiler;
 	String m_cacheDir;
 
-	ANKI_USE_RESULT Error compileInternal(
-		CString source, U64* hash, const ShaderCompilerOptions& options, DynamicArrayAuto<U8>& bin) const;
+	ANKI_USE_RESULT Error compileInternal(CString source,
+		U64* hash,
+		const ShaderCompilerOptions& options,
+		DynamicArrayAuto<U8>& bin,
+		Bool dumpShaderSource) const;
 };
 /// @}
 

+ 1 - 0
src/anki/resource/ResourceManager.cpp

@@ -48,6 +48,7 @@ Error ResourceManager::init(ResourceManagerInitInfo& init)
 
 	// Init some constants
 	m_maxTextureSize = init.m_config->getNumber("rsrc.maxTextureSize");
+	m_dumpShaderSource = init.m_config->getNumber("rsrc.dumpShaderSources");
 
 	// Init type resource managers
 #define ANKI_INSTANTIATE_RESOURCE(rsrc_, ptr_) TypeResourceManager<rsrc_>::init(m_alloc);

+ 6 - 0
src/anki/resource/ResourceManager.h

@@ -133,6 +133,11 @@ anki_internal:
 		return m_maxTextureSize;
 	}
 
+	Bool getDumpShaderSource() const
+	{
+		return m_dumpShaderSource;
+	}
+
 	ResourceAllocator<U8>& getAllocator()
 	{
 		return m_alloc;
@@ -222,6 +227,7 @@ private:
 	U64 m_loadRequestCount = 0;
 	TransferGpuAllocator* m_transferGpuAlloc = nullptr;
 	ShaderCompilerCache* m_shaderCompiler = nullptr;
+	Bool m_dumpShaderSource = false;
 };
 /// @}
 

+ 2 - 1
src/anki/resource/ShaderProgramResource.cpp

@@ -605,7 +605,8 @@ void ShaderProgramResource::initVariant(ConstWeakArray<ShaderProgramResourceMuta
 		compileOptions.setFromGrManager(getManager().getGrManager());
 		compileOptions.m_shaderType = i;
 
-		Error err = getManager().getShaderCompiler().compile(src.toCString(), nullptr, compileOptions, bin);
+		const Error err = getManager().getShaderCompiler().compile(
+			src.toCString(), nullptr, compileOptions, bin, getManager().getDumpShaderSource());
 		if(err)
 		{
 			ANKI_RESOURCE_LOGF("Shader compilation failed");