Forráskód Böngészése

Add some SVGF bits

Panagiotis Christopoulos Charitos 4 éve
szülő
commit
8d9b53cbb2

+ 23 - 24
AnKi/Renderer/RtShadows.cpp

@@ -33,30 +33,29 @@ Error RtShadows::init(const ConfigSet& cfg)
 
 Error RtShadows::initInternal(const ConfigSet& cfg)
 {
-	// Get the program
-	const ShaderProgramResourceSystem& shaderSystem = getResourceManager().getShaderProgramResourceSystem();
-	const ShaderProgramRaytracingLibrary* library = nullptr;
-	for(const ShaderProgramRaytracingLibrary& lib : shaderSystem.getRayTracingLibraries())
-	{
-		if(lib.getLibraryName() == "RtShadows")
-		{
-			library = &lib;
-			break;
-		}
-	}
-	ANKI_ASSERT(library);
-	m_grProg = library->getShaderProgram();
+	// Ray gen prog
+	ANKI_CHECK(getResourceManager().loadResource("Shaders/RtShadowsRayGen.ankiprog", m_rayGenProg));
+	ShaderProgramResourceVariantInitInfo variantInitInfo(m_rayGenProg);
+	variantInitInfo.addMutation("SVGF", 0);
+	const ShaderProgramResourceVariant* variant;
+	m_rayGenProg->getOrCreateVariant(variantInitInfo, variant);
+	m_rtLibraryGrProg = variant->getProgram();
+	m_rayGenShaderGroupIdx = variant->getShaderGroupHandleIndex();
+
+	// Miss prog
+	ANKI_CHECK(getResourceManager().loadResource("Shaders/RtShadowsMiss.ankiprog", m_missProg));
+	m_missProg->getOrCreateVariant(variant);
+	m_missShaderGroupIdx = variant->getShaderGroupHandleIndex();
 
 	// Denoise program
 	ANKI_CHECK(getResourceManager().loadResource("Shaders/RtShadowsDenoise.ankiprog", m_denoiseProg));
-	ShaderProgramResourceVariantInitInfo variantInitInfo(m_denoiseProg);
-	variantInitInfo.addConstant("OUT_IMAGE_SIZE", UVec2(m_r->getWidth(), m_r->getHeight()));
-	variantInitInfo.addConstant("SAMPLE_COUNT", 8u);
-	variantInitInfo.addConstant("SPIRAL_TURN_COUNT", 27u);
-	variantInitInfo.addConstant("PIXEL_RADIUS", 12u);
+	ShaderProgramResourceVariantInitInfo variantInitInfo2(m_denoiseProg);
+	variantInitInfo2.addConstant("OUT_IMAGE_SIZE", UVec2(m_r->getWidth(), m_r->getHeight()));
+	variantInitInfo2.addConstant("SAMPLE_COUNT", 8u);
+	variantInitInfo2.addConstant("SPIRAL_TURN_COUNT", 27u);
+	variantInitInfo2.addConstant("PIXEL_RADIUS", 12u);
 
-	const ShaderProgramResourceVariant* variant;
-	m_denoiseProg->getOrCreateVariant(variantInitInfo, variant);
+	m_denoiseProg->getOrCreateVariant(variantInitInfo2, variant);
 	m_grDenoiseProg = variant->getProgram();
 
 	// RTs
@@ -211,7 +210,7 @@ void RtShadows::run(RenderPassWorkContext& rgraphCtx)
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	const ClusterBinOut& rsrc = ctx.m_clusterBinOut;
 
-	cmdb->bindShaderProgram(m_grProg);
+	cmdb->bindShaderProgram(m_rtLibraryGrProg);
 
 	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearRepeat);
 
@@ -295,10 +294,10 @@ void RtShadows::buildSbt()
 	m_runCtx.m_sbtOffset = token.m_offset;
 
 	// Set the miss and ray gen handles
-	ConstWeakArray<U8> shaderGroupHandles = m_grProg->getShaderGroupHandles();
-	memcpy(sbt, &shaderGroupHandles[0], shaderHandleSize);
+	ConstWeakArray<U8> shaderGroupHandles = m_rtLibraryGrProg->getShaderGroupHandles();
+	memcpy(sbt, &shaderGroupHandles[m_rayGenShaderGroupIdx * shaderHandleSize], shaderHandleSize);
 	sbt += m_sbtRecordSize;
-	memcpy(sbt, &shaderGroupHandles[shaderHandleSize], shaderHandleSize);
+	memcpy(sbt, &shaderGroupHandles[m_missShaderGroupIdx * shaderHandleSize], shaderHandleSize);
 	sbt += m_sbtRecordSize;
 
 	// Init SBT and instances

+ 8 - 1
AnKi/Renderer/RtShadows.h

@@ -51,10 +51,16 @@ public:
 		U64 m_frameLastUsed = MAX_U64;
 	};
 
-	ShaderProgramPtr m_grProg;
 	TexturePtr m_historyAndFinalRt;
 	RenderTargetDescription m_renderRt;
 
+	ShaderProgramResourcePtr m_rayGenProg;
+	ShaderProgramPtr m_rtLibraryGrProg;
+	U32 m_rayGenShaderGroupIdx = MAX_U32;
+
+	ShaderProgramResourcePtr m_missProg;
+	U32 m_missShaderGroupIdx = MAX_U32;
+
 	ShaderProgramResourcePtr m_denoiseProg;
 	ShaderProgramPtr m_grDenoiseProg;
 
@@ -63,6 +69,7 @@ public:
 	Array<ShadowLayer, MAX_RT_SHADOW_LAYERS> m_shadowLayers;
 
 	Bool m_historyAndFinalRtImportedOnce = false;
+	Bool m_useSvgf = false;
 
 	ShaderProgramResourcePtr m_visualizeRenderTargetsProg;
 

+ 18 - 12
AnKi/Resource/ShaderProgramResourceSystem.cpp

@@ -16,16 +16,19 @@
 namespace anki
 {
 
+U64 ShaderProgramRaytracingLibrary::generateShaderGroupGroupHash(CString resourceFilename, U64 mutationHash,
+																 GenericMemoryPoolAllocator<U8> alloc)
+{
+	ANKI_ASSERT(resourceFilename.getLength() > 0);
+	StringAuto basename(alloc);
+	getFilepathFilename(resourceFilename, basename);
+	const U64 hash = appendHash(basename.cstr(), basename.getLength(), mutationHash);
+	return hash;
+}
+
 ShaderProgramResourceSystem::~ShaderProgramResourceSystem()
 {
 	m_cacheDir.destroy(m_alloc);
-
-	for(ShaderProgramRaytracingLibrary& lib : m_rtLibraries)
-	{
-		lib.m_libraryName.destroy(m_alloc);
-		lib.m_resourceHashToShaderGroupHandleIndex.destroy(m_alloc);
-	}
-
 	m_rtLibraries.destroy(m_alloc);
 }
 
@@ -315,7 +318,8 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(CString cacheDir, co
 
 		void addGroup(CString filename, U64 mutationHash, U32 rayGen, U32 miss, U32 chit, U32 ahit)
 		{
-			const U64 groupHash = ShaderProgramRaytracingLibrary::generateShaderGroupGroupHash(filename, mutationHash);
+			const U64 groupHash =
+				ShaderProgramRaytracingLibrary::generateShaderGroupGroupHash(filename, mutationHash, m_alloc);
 			for(const ShaderGroup& group : m_shaderGroups)
 			{
 				ANKI_ASSERT(group.m_hitGroupHash != groupHash && "Shouldn't find group with the same hash");
@@ -415,7 +419,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(CString cacheDir, co
 			// Iterate all mutations
 			ConstWeakArray<ShaderProgramBinaryMutation> mutations;
 			ShaderProgramBinaryMutation dummyMutation;
-			if(binary.m_mutations.getSize())
+			if(binary.m_mutations.getSize() > 1)
 			{
 				mutations = binary.m_mutations;
 			}
@@ -462,7 +466,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(CString cacheDir, co
 			// Iterate all mutations
 			ConstWeakArray<ShaderProgramBinaryMutation> mutations;
 			ShaderProgramBinaryMutation dummyMutation;
-			if(binary.m_mutations.getSize())
+			if(binary.m_mutations.getSize() > 1)
 			{
 				mutations = binary.m_mutations;
 			}
@@ -502,7 +506,7 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(CString cacheDir, co
 			// Before you iterate the mutations do some work if there are none
 			ConstWeakArray<ShaderProgramBinaryMutation> mutations;
 			ShaderProgramBinaryMutation dummyMutation;
-			if(binary.m_mutations.getSize())
+			if(binary.m_mutations.getSize() > 1)
 			{
 				mutations = binary.m_mutations;
 			}
@@ -541,13 +545,15 @@ Error ShaderProgramResourceSystem::createRayTracingPrograms(CString cacheDir, co
 	// See the ShaderProgram class for info.
 	if(libs.getSize() != 0)
 	{
-		outLibs.resize(alloc, libs.getSize());
+		outLibs.create(alloc, libs.getSize());
 
 		for(U32 libIdx = 0; libIdx < libs.getSize(); ++libIdx)
 		{
 			ShaderProgramRaytracingLibrary& outLib = outLibs[libIdx];
 			const Lib& inLib = libs[libIdx];
 
+			outLib.m_alloc = alloc;
+
 			if(inLib.m_presentStages
 			   != (ShaderTypeBit::RAY_GEN | ShaderTypeBit::MISS | ShaderTypeBit::CLOSEST_HIT | ShaderTypeBit::ANY_HIT))
 			{

+ 10 - 7
AnKi/Resource/ShaderProgramResourceSystem.h

@@ -23,6 +23,12 @@ class ShaderProgramRaytracingLibrary
 	friend class ShaderProgramResourceSystem;
 
 public:
+	~ShaderProgramRaytracingLibrary()
+	{
+		m_libraryName.destroy(m_alloc);
+		m_resourceHashToShaderGroupHandleIndex.destroy(m_alloc);
+	}
+
 	CString getLibraryName() const
 	{
 		return m_libraryName;
@@ -43,22 +49,19 @@ public:
 	/// handle index.
 	U32 getShaderGroupHandleIndex(CString resourceFilename, U64 mutationHash) const
 	{
-		return getIndex(generateShaderGroupGroupHash(resourceFilename, mutationHash));
+		return getIndex(generateShaderGroupGroupHash(resourceFilename, mutationHash, m_alloc));
 	}
 
 private:
+	GenericMemoryPoolAllocator<U8> m_alloc;
 	String m_libraryName;
 	U32 m_rayTypeCount = MAX_U32;
 	ShaderProgramPtr m_program;
 	HashMap<U64, U32> m_resourceHashToShaderGroupHandleIndex;
 
 	/// Given the filename of a program (that contains ray tracing shaders) and a specific mutation get a hash back.
-	static U64 generateShaderGroupGroupHash(CString resourceFilename, U64 mutationHash)
-	{
-		ANKI_ASSERT(resourceFilename.getLength() > 0);
-		const U64 hash = appendHash(resourceFilename.cstr(), resourceFilename.getLength(), mutationHash);
-		return hash;
-	}
+	static U64 generateShaderGroupGroupHash(CString resourceFilename, U64 mutationHash,
+											GenericMemoryPoolAllocator<U8> alloc);
 
 	/// The hash generated by generateShaderGroupGroupHash() can be used to retrieve the group position in the
 	/// m_program.

+ 2 - 2
AnKi/ShaderCompiler/ShaderProgramDump.cpp

@@ -56,11 +56,11 @@ void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& huma
 
 	if(binary.m_rayType != MAX_U32)
 	{
-		lines.pushBack("**\nRAY TYPE**\n");
+		lines.pushBack("\n**RAY TYPE**\n");
 		lines.pushBackSprintf(ANKI_TAB "%u\n", binary.m_rayType);
 	}
 
-	lines.pushBack("**\nMUTATORS**\n");
+	lines.pushBack("\n**MUTATORS**\n");
 	if(binary.m_mutators.getSize() > 0)
 	{
 		for(const ShaderProgramBinaryMutator& mutator : binary.m_mutators)

+ 13 - 0
AnKi/Shaders/RtShadows.glsl

@@ -15,6 +15,13 @@ UVec4 packRtShadows(F32 shadowFactors[MAX_RT_SHADOW_LAYERS])
 	return UVec4(a, b, 0, 0);
 }
 
+UVec4 packRtShadows(F32 shadowFactors[MAX_RT_SHADOW_LAYERS], U32 temporalHistory)
+{
+	UVec4 packed = packRtShadows(shadowFactors);
+	packed.z = temporalHistory;
+	return packed;
+}
+
 void unpackRtShadows(UVec4 packed, out F32 shadowFactors[MAX_RT_SHADOW_LAYERS])
 {
 	const Vec4 a = newUnpackUnorm4x8(packed.x);
@@ -28,3 +35,9 @@ void unpackRtShadows(UVec4 packed, out F32 shadowFactors[MAX_RT_SHADOW_LAYERS])
 	shadowFactors[6] = b[2];
 	shadowFactors[7] = b[3];
 }
+
+void unpackRtShadows(UVec4 packed, out F32 shadowFactors[MAX_RT_SHADOW_LAYERS], out U32 temporalHistory)
+{
+	unpackRtShadows(packed, shadowFactors);
+	temporalHistory = packed.z;
+}

+ 35 - 2
AnKi/Shaders/RtShadowsRayGen.ankiprog

@@ -3,6 +3,8 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
+#pragma anki mutator SVGF 0 1
+
 #pragma anki library RtShadows
 #pragma anki ray_type 0
 
@@ -142,6 +144,11 @@ void main()
 	}
 
 	// Do temporal accumulation
+#if SVGF
+	// Gives the number of frames with temporal stability
+	U32 temporalHistory;
+#endif
+
 	{
 		const Vec2 historyUv = uv + textureLod(u_motionVectorsRt, u_linearAnyClampSampler, uv, 0.0).rg;
 		const F32 rejectionFactor = textureLod(u_motionVectorsRejectionRt, u_linearAnyClampSampler, uv, 0.0).r;
@@ -149,21 +156,47 @@ void main()
 		// Use nearest because it's an integer texture
 		const UVec4 history2 = textureLod(u_historyRt, u_nearestAnyClampSampler, historyUv, 0.0);
 		F32 history[MAX_RT_SHADOW_LAYERS];
+#if SVGF
+		unpackRtShadows(history2, history, temporalHistory);
+#else
 		unpackRtShadows(history2, history);
+#endif
 
 		// Compute blend factors
 		const F32 nominalBlendFactor = 0.1;
 		const F32 blendFactor = mix(nominalBlendFactor, 1.0, rejectionFactor);
 
 		// Blend with history
-		ANKI_UNROLL for(U32 i = 0; i < MAX_RT_SHADOW_LAYERS; ++i)
+#if SVGF
+		F32 maxLerp = 0.0;
+#endif
+		for(U32 i = 0; i < MAX_RT_SHADOW_LAYERS; ++i)
+		{
+			const F32 lerp = min(1.0, u_unis.historyRejectFactor[i] + blendFactor);
+			shadowFactors[i] = mix(history[i], shadowFactors[i], lerp);
+#if SVGF
+			maxLerp = max(maxLerp, lerp);
+#endif
+		}
+
+#if SVGF
+		if(maxLerp == 1.0)
+		{
+			temporalHistory = 1; // Rejected the history of one layer, reset the temporal history
+		}
+		else
 		{
-			shadowFactors[i] = mix(history[i], shadowFactors[i], min(1.0, u_unis.historyRejectFactor[i] + blendFactor));
+			++temporalHistory; // Sample seems stable, inc it's temporal history
 		}
+#endif
 	}
 
 	// Store
+#if SVGF
+	const UVec4 packed = packRtShadows(shadowFactors, temporalHistory);
+#else
 	const UVec4 packed = packRtShadows(shadowFactors);
+#endif
 	imageStore(u_outImg, IVec2(gl_LaunchIDEXT.xy), packed);
 }
 #pragma anki end