Browse Source

Hook up the new cluster binning to indirect diffuse and specular

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
42bb717974

+ 83 - 0
AnKi/Renderer/ClusterBinning2.cpp

@@ -6,9 +6,14 @@
 #include <AnKi/Renderer/ClusterBinning2.h>
 #include <AnKi/Renderer/ClusterBinning2.h>
 #include <AnKi/Renderer/PrimaryNonRenderableVisibility.h>
 #include <AnKi/Renderer/PrimaryNonRenderableVisibility.h>
 #include <AnKi/Renderer/Renderer.h>
 #include <AnKi/Renderer/Renderer.h>
+#include <AnKi/Renderer/ProbeReflections.h>
+#include <AnKi/Renderer/VolumetricLightingAccumulation.h>
 #include <AnKi/Core/GpuMemory/GpuVisibleTransientMemoryPool.h>
 #include <AnKi/Core/GpuMemory/GpuVisibleTransientMemoryPool.h>
 #include <AnKi/Scene/Components/CameraComponent.h>
 #include <AnKi/Scene/Components/CameraComponent.h>
+#include <AnKi/Scene/Components/LightComponent.h>
 #include <AnKi/Collision/Functions.h>
 #include <AnKi/Collision/Functions.h>
+#include <AnKi/Util/Tracer.h>
+#include <AnKi/Util/HighRezTimer.h>
 
 
 namespace anki {
 namespace anki {
 
 
@@ -47,6 +52,23 @@ void ClusterBinning2::populateRenderGraph(RenderingContext& ctx)
 {
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 
+	// Fire an async job to fill the general uniforms
+	{
+		m_runCtx.m_rctx = &ctx;
+
+		RebarAllocation alloc;
+		m_runCtx.m_uniformsCpu = RebarTransientMemoryPool::getSingleton().allocateFrame<ClusteredShadingUniforms2>(1, alloc);
+
+		m_runCtx.m_clusterUniformsOffset = alloc.m_offset;
+
+		CoreThreadHive::getSingleton().submitTask(
+			[](void* userData, [[maybe_unused]] U32 threadId, [[maybe_unused]] ThreadHive& hive,
+			   [[maybe_unused]] ThreadHiveSemaphore* signalSemaphore) {
+				static_cast<ClusterBinning2*>(userData)->writeClusterUniformsInternal();
+			},
+			this);
+	}
+
 	// Allocate the clusters buffer
 	// Allocate the clusters buffer
 	{
 	{
 		const U32 clusterCount = getRenderer().getTileCounts().x() * getRenderer().getTileCounts().y() + getRenderer().getZSplitCount();
 		const U32 clusterCount = getRenderer().getTileCounts().x() * getRenderer().getTileCounts().y() + getRenderer().getZSplitCount();
@@ -272,4 +294,65 @@ void ClusterBinning2::populateRenderGraph(RenderingContext& ctx)
 	}
 	}
 }
 }
 
 
+void ClusterBinning2::writeClusterUniformsInternal()
+{
+	ANKI_TRACE_SCOPED_EVENT(RWriteClusterShadingObjects);
+
+	RenderingContext& ctx = *m_runCtx.m_rctx;
+	ClusteredShadingUniforms2& unis = *m_runCtx.m_uniformsCpu;
+
+	unis.m_renderingSize = Vec2(F32(getRenderer().getInternalResolution().x()), F32(getRenderer().getInternalResolution().y()));
+
+	unis.m_time = F32(HighRezTimer::getCurrentTime());
+	unis.m_frame = getRenderer().getFrameCount() & kMaxU32;
+
+	Plane nearPlane;
+	extractClipPlane(ctx.m_matrices.m_viewProjection, FrustumPlaneType::kNear, nearPlane);
+	unis.m_nearPlaneWSpace = Vec4(nearPlane.getNormal().xyz(), nearPlane.getOffset());
+	unis.m_near = ctx.m_cameraNear;
+	unis.m_far = ctx.m_cameraFar;
+	unis.m_cameraPosition = ctx.m_matrices.m_cameraTransform.getTranslationPart().xyz();
+
+	unis.m_tileCounts = getRenderer().getTileCounts();
+	unis.m_zSplitCount = getRenderer().getZSplitCount();
+	unis.m_zSplitCountOverFrustumLength = F32(getRenderer().getZSplitCount()) / (ctx.m_cameraFar - ctx.m_cameraNear);
+	unis.m_zSplitMagic.x() = (ctx.m_cameraNear - ctx.m_cameraFar) / (ctx.m_cameraNear * F32(getRenderer().getZSplitCount()));
+	unis.m_zSplitMagic.y() = ctx.m_cameraFar / (ctx.m_cameraNear * F32(getRenderer().getZSplitCount()));
+	unis.m_tileSize = getRenderer().getTileSize();
+	unis.m_lightVolumeLastZSplit = getRenderer().getVolumetricLightingAccumulation().getFinalZSplit();
+
+	unis.m_reflectionProbesMipCount = F32(getRenderer().getProbeReflections().getReflectionTextureMipmapCount());
+
+	unis.m_matrices = ctx.m_matrices;
+	unis.m_previousMatrices = ctx.m_prevMatrices;
+
+	// Directional light
+	const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
+	if(dirLight)
+	{
+		const CameraComponent& cam = SceneGraph::getSingleton().getActiveCameraNode().getFirstComponentOfType<CameraComponent>();
+
+		DirectionalLight& out = unis.m_directionalLight;
+
+		out.m_diffuseColor = dirLight->getDiffuseColor().xyz();
+		out.m_shadowCascadeCount = cam.getShadowCascadeCount();
+		out.m_direction = dirLight->getDirection();
+		out.m_active = 1;
+		for(U32 i = 0; i < kMaxShadowCascades; ++i)
+		{
+			out.m_shadowCascadeDistances[i] = cam.getShadowCascadeDistance(i);
+		}
+		out.m_shadowLayer = (dirLight->getShadowEnabled()) ? 1 : kMaxU32; // TODO RT
+
+		for(U cascade = 0; cascade < cam.getShadowCascadeCount(); ++cascade)
+		{
+			// out.m_textureMatrices[cascade] = in.m_textureMatrices[cascade]; TODO
+		}
+	}
+	else
+	{
+		unis.m_directionalLight.m_active = 0;
+	}
+}
+
 } // end namespace anki
 } // end namespace anki

+ 33 - 0
AnKi/Renderer/ClusterBinning2.h

@@ -25,6 +25,33 @@ public:
 	/// Populate the rendergraph.
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
 	void populateRenderGraph(RenderingContext& ctx);
 
 
+	BufferOffsetRange getClusteredShadingUniforms() const
+	{
+		ANKI_ASSERT(m_runCtx.m_clusterUniformsOffset != kMaxPtrSize);
+		return BufferOffsetRange{&RebarTransientMemoryPool::getSingleton().getBuffer(), m_runCtx.m_clusterUniformsOffset,
+								 sizeof(ClusteredShadingUniforms2)};
+	}
+
+	const BufferOffsetRange& getPackedObjectsBuffer(GpuSceneNonRenderableObjectType type) const
+	{
+		return m_runCtx.m_packedObjectsBuffers[type];
+	}
+
+	BufferHandle getPackedObjectsBufferHandle(GpuSceneNonRenderableObjectType type) const
+	{
+		return m_runCtx.m_packedObjectsHandles[type];
+	}
+
+	const BufferOffsetRange& getClustersBuffer() const
+	{
+		return m_runCtx.m_clustersBuffer;
+	}
+
+	BufferHandle getClustersBufferHandle() const
+	{
+		return m_runCtx.m_clustersHandle;
+	}
+
 private:
 private:
 	ShaderProgramResourcePtr m_jobSetupProg;
 	ShaderProgramResourcePtr m_jobSetupProg;
 	ShaderProgramPtr m_jobSetupGrProg;
 	ShaderProgramPtr m_jobSetupGrProg;
@@ -43,7 +70,13 @@ private:
 
 
 		Array<BufferHandle, U32(GpuSceneNonRenderableObjectType::kCount)> m_packedObjectsHandles;
 		Array<BufferHandle, U32(GpuSceneNonRenderableObjectType::kCount)> m_packedObjectsHandles;
 		Array<BufferOffsetRange, U32(GpuSceneNonRenderableObjectType::kCount)> m_packedObjectsBuffers;
 		Array<BufferOffsetRange, U32(GpuSceneNonRenderableObjectType::kCount)> m_packedObjectsBuffers;
+
+		PtrSize m_clusterUniformsOffset = kMaxPtrSize; ///< Offset into the ReBAR buffer.
+		ClusteredShadingUniforms2* m_uniformsCpu = nullptr;
+		RenderingContext* m_rctx = nullptr;
 	} m_runCtx;
 	} m_runCtx;
+
+	void writeClusterUniformsInternal();
 };
 };
 /// @}
 /// @}
 
 

+ 17 - 8
AnKi/Renderer/IndirectDiffuse.cpp

@@ -10,7 +10,7 @@
 #include <AnKi/Renderer/DownscaleBlur.h>
 #include <AnKi/Renderer/DownscaleBlur.h>
 #include <AnKi/Renderer/MotionVectors.h>
 #include <AnKi/Renderer/MotionVectors.h>
 #include <AnKi/Renderer/IndirectDiffuseProbes.h>
 #include <AnKi/Renderer/IndirectDiffuseProbes.h>
-#include <AnKi/Renderer/ClusterBinning.h>
+#include <AnKi/Renderer/ClusterBinning2.h>
 #include <AnKi/Renderer/PackVisibleClusteredObjects.h>
 #include <AnKi/Renderer/PackVisibleClusteredObjects.h>
 #include <AnKi/Core/CVarSet.h>
 #include <AnKi/Core/CVarSet.h>
 
 
@@ -223,12 +223,14 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 		// Create main pass
 		// Create main pass
 		TextureUsageBit readUsage;
 		TextureUsageBit readUsage;
 		TextureUsageBit writeUsage;
 		TextureUsageBit writeUsage;
+		BufferUsageBit readBufferUsage;
 		RenderPassDescriptionBase* prpass;
 		RenderPassDescriptionBase* prpass;
 		if(preferCompute)
 		if(preferCompute)
 		{
 		{
 			ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("IndirectDiffuse");
 			ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("IndirectDiffuse");
 			readUsage = TextureUsageBit::kSampledCompute;
 			readUsage = TextureUsageBit::kSampledCompute;
 			writeUsage = TextureUsageBit::kImageComputeWrite;
 			writeUsage = TextureUsageBit::kImageComputeWrite;
+			readBufferUsage = BufferUsageBit::kStorageComputeRead;
 			prpass = &rpass;
 			prpass = &rpass;
 		}
 		}
 		else
 		else
@@ -237,6 +239,7 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 			rpass.setFramebufferInfo(m_main.m_fbDescr, {m_runCtx.m_mainRtHandles[kWrite]}, {}, (enableVrs) ? m_runCtx.m_sriRt : RenderTargetHandle());
 			rpass.setFramebufferInfo(m_main.m_fbDescr, {m_runCtx.m_mainRtHandles[kWrite]}, {}, (enableVrs) ? m_runCtx.m_sriRt : RenderTargetHandle());
 			readUsage = TextureUsageBit::kSampledFragment;
 			readUsage = TextureUsageBit::kSampledFragment;
 			writeUsage = TextureUsageBit::kFramebufferWrite;
 			writeUsage = TextureUsageBit::kFramebufferWrite;
+			readBufferUsage = BufferUsageBit::kStorageFragmentRead;
 			prpass = &rpass;
 			prpass = &rpass;
 
 
 			if(enableVrs)
 			if(enableVrs)
@@ -261,17 +264,23 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 		prpass->newTextureDependency(getRenderer().getMotionVectors().getHistoryLengthRt(), readUsage);
 		prpass->newTextureDependency(getRenderer().getMotionVectors().getHistoryLengthRt(), readUsage);
 		prpass->newTextureDependency(m_runCtx.m_mainRtHandles[kRead], readUsage);
 		prpass->newTextureDependency(m_runCtx.m_mainRtHandles[kRead], readUsage);
 
 
+		prpass->newBufferDependency(
+			getRenderer().getClusterBinning2().getPackedObjectsBufferHandle(GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe),
+			readBufferUsage);
+		prpass->newBufferDependency(getRenderer().getClusterBinning2().getClustersBufferHandle(), readBufferUsage);
+
 		prpass->setWork([this, &ctx, enableVrs](RenderPassWorkContext& rgraphCtx) {
 		prpass->setWork([this, &ctx, enableVrs](RenderPassWorkContext& rgraphCtx) {
 			CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 			CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 			cmdb.bindShaderProgram(m_main.m_grProg.get());
 			cmdb.bindShaderProgram(m_main.m_grProg.get());
 
 
-			cmdb.bindUniformBuffer(0, 0, &RebarTransientMemoryPool::getSingleton().getBuffer(),
-								   getRenderer().getClusterBinning().getClusteredUniformsRebarToken().m_offset,
-								   getRenderer().getClusterBinning().getClusteredUniformsRebarToken().m_range);
-			getRenderer().getPackVisibleClusteredObjects().bindClusteredObjectBuffer(cmdb, 0, 1, ClusteredObjectType::kGlobalIlluminationProbe);
-			cmdb.bindStorageBuffer(0, 2, &RebarTransientMemoryPool::getSingleton().getBuffer(),
-								   getRenderer().getClusterBinning().getClustersRebarToken().m_offset,
-								   getRenderer().getClusterBinning().getClustersRebarToken().m_range);
+			BufferOffsetRange buff = getRenderer().getClusterBinning2().getClusteredShadingUniforms();
+			cmdb.bindUniformBuffer(0, 0, buff.m_buffer, buff.m_offset, buff.m_range);
+
+			buff = getRenderer().getClusterBinning2().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe);
+			cmdb.bindStorageBuffer(0, 1, buff.m_buffer, buff.m_offset, buff.m_range);
+
+			buff = getRenderer().getClusterBinning2().getClustersBuffer();
+			cmdb.bindStorageBuffer(0, 2, buff.m_buffer, buff.m_offset, buff.m_range);
 
 
 			cmdb.bindSampler(0, 3, getRenderer().getSamplers().m_trilinearClamp.get());
 			cmdb.bindSampler(0, 3, getRenderer().getSamplers().m_trilinearClamp.get());
 			rgraphCtx.bindColorTexture(0, 4, getRenderer().getGBuffer().getColorRt(2));
 			rgraphCtx.bindColorTexture(0, 4, getRenderer().getGBuffer().getColorRt(2));

+ 16 - 8
AnKi/Renderer/IndirectSpecular.cpp

@@ -12,7 +12,7 @@
 #include <AnKi/Renderer/ProbeReflections.h>
 #include <AnKi/Renderer/ProbeReflections.h>
 #include <AnKi/Renderer/MotionVectors.h>
 #include <AnKi/Renderer/MotionVectors.h>
 #include <AnKi/Renderer/VrsSriGeneration.h>
 #include <AnKi/Renderer/VrsSriGeneration.h>
-#include <AnKi/Renderer/ClusterBinning.h>
+#include <AnKi/Renderer/ClusterBinning2.h>
 #include <AnKi/Renderer/PackVisibleClusteredObjects.h>
 #include <AnKi/Renderer/PackVisibleClusteredObjects.h>
 #include <AnKi/Core/CVarSet.h>
 #include <AnKi/Core/CVarSet.h>
 
 
@@ -119,6 +119,7 @@ void IndirectSpecular::populateRenderGraph(RenderingContext& ctx)
 		RenderPassDescriptionBase* ppass;
 		RenderPassDescriptionBase* ppass;
 		TextureUsageBit readUsage;
 		TextureUsageBit readUsage;
 		TextureUsageBit writeUsage;
 		TextureUsageBit writeUsage;
+		BufferUsageBit readBufferUsage;
 		if(preferCompute)
 		if(preferCompute)
 		{
 		{
 			ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("SSR");
 			ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("SSR");
@@ -126,6 +127,7 @@ void IndirectSpecular::populateRenderGraph(RenderingContext& ctx)
 			ppass = &pass;
 			ppass = &pass;
 			readUsage = TextureUsageBit::kSampledCompute;
 			readUsage = TextureUsageBit::kSampledCompute;
 			writeUsage = TextureUsageBit::kImageComputeWrite;
 			writeUsage = TextureUsageBit::kImageComputeWrite;
+			readBufferUsage = BufferUsageBit::kStorageComputeRead;
 		}
 		}
 		else
 		else
 		{
 		{
@@ -136,6 +138,7 @@ void IndirectSpecular::populateRenderGraph(RenderingContext& ctx)
 			ppass = &pass;
 			ppass = &pass;
 			readUsage = TextureUsageBit::kSampledFragment;
 			readUsage = TextureUsageBit::kSampledFragment;
 			writeUsage = TextureUsageBit::kFramebufferWrite;
 			writeUsage = TextureUsageBit::kFramebufferWrite;
+			readBufferUsage = BufferUsageBit::kStorageFragmentRead;
 
 
 			if(enableVrs)
 			if(enableVrs)
 			{
 			{
@@ -160,6 +163,10 @@ void IndirectSpecular::populateRenderGraph(RenderingContext& ctx)
 		ppass->newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), readUsage);
 		ppass->newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), readUsage);
 		ppass->newTextureDependency(getRenderer().getMotionVectors().getHistoryLengthRt(), readUsage);
 		ppass->newTextureDependency(getRenderer().getMotionVectors().getHistoryLengthRt(), readUsage);
 
 
+		ppass->newBufferDependency(getRenderer().getClusterBinning2().getPackedObjectsBufferHandle(GpuSceneNonRenderableObjectType::kReflectionProbe),
+								   readBufferUsage);
+		ppass->newBufferDependency(getRenderer().getClusterBinning2().getClustersBufferHandle(), readBufferUsage);
+
 		ppass->setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 		ppass->setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 			run(ctx, rgraphCtx);
 			run(ctx, rgraphCtx);
 		});
 		});
@@ -207,13 +214,14 @@ void IndirectSpecular::run(const RenderingContext& ctx, RenderPassWorkContext& r
 	cmdb.bindSampler(0, 9, getRenderer().getSamplers().m_trilinearRepeat.get());
 	cmdb.bindSampler(0, 9, getRenderer().getSamplers().m_trilinearRepeat.get());
 	cmdb.bindTexture(0, 10, &m_noiseImage->getTextureView());
 	cmdb.bindTexture(0, 10, &m_noiseImage->getTextureView());
 
 
-	cmdb.bindUniformBuffer(0, 11, &RebarTransientMemoryPool::getSingleton().getBuffer(),
-						   getRenderer().getClusterBinning().getClusteredUniformsRebarToken().m_offset,
-						   getRenderer().getClusterBinning().getClusteredUniformsRebarToken().m_range);
-	getRenderer().getPackVisibleClusteredObjects().bindClusteredObjectBuffer(cmdb, 0, 12, ClusteredObjectType::kReflectionProbe);
-	cmdb.bindStorageBuffer(0, 13, &RebarTransientMemoryPool::getSingleton().getBuffer(),
-						   getRenderer().getClusterBinning().getClustersRebarToken().m_offset,
-						   getRenderer().getClusterBinning().getClustersRebarToken().m_range);
+	BufferOffsetRange buff = getRenderer().getClusterBinning2().getClusteredShadingUniforms();
+	cmdb.bindUniformBuffer(0, 11, buff.m_buffer, buff.m_offset, buff.m_range);
+
+	buff = getRenderer().getClusterBinning2().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kReflectionProbe);
+	cmdb.bindStorageBuffer(0, 12, buff.m_buffer, buff.m_offset, buff.m_range);
+
+	buff = getRenderer().getClusterBinning2().getClustersBuffer();
+	cmdb.bindStorageBuffer(0, 13, buff.m_buffer, buff.m_offset, buff.m_range);
 
 
 	cmdb.bindAllBindless(1);
 	cmdb.bindAllBindless(1);
 
 

+ 5 - 0
AnKi/Scene/Components/CameraComponent.h

@@ -92,6 +92,11 @@ public:
 		}
 		}
 	}
 	}
 
 
+	U32 getShadowCascadeCount() const
+	{
+		return m_frustum.getShadowCascadeCount();
+	}
+
 	F32 getShadowCascadeDistance(U32 cascade) const
 	F32 getShadowCascadeDistance(U32 cascade) const
 	{
 	{
 		if(ANKI_SCENE_ASSERT(cascade < m_frustum.getShadowCascadeCount()))
 		if(ANKI_SCENE_ASSERT(cascade < m_frustum.getShadowCascadeCount()))

+ 16 - 0
AnKi/Shaders/ClusteredShadingCommon.hlsl

@@ -139,6 +139,8 @@ Cluster mergeClusters(Cluster tileCluster, Cluster zCluster)
 }
 }
 
 
 #if defined(CLUSTERED_SHADING_CLUSTERS_BINDING)
 #if defined(CLUSTERED_SHADING_CLUSTERS_BINDING)
+// TODO rm
+
 /// Get the final cluster after ORing and ANDing the masks.
 /// Get the final cluster after ORing and ANDing the masks.
 Cluster getClusterFragCoord(Vec3 fragCoord, U32 tileSize, UVec2 tileCounts, U32 zSplitCount, F32 a, F32 b)
 Cluster getClusterFragCoord(Vec3 fragCoord, U32 tileSize, UVec2 tileCounts, U32 zSplitCount, F32 a, F32 b)
 {
 {
@@ -152,4 +154,18 @@ Cluster getClusterFragCoord(Vec3 fragCoord)
 	return getClusterFragCoord(fragCoord, g_clusteredShading.m_tileSize, g_clusteredShading.m_tileCounts, g_clusteredShading.m_zSplitCount,
 	return getClusterFragCoord(fragCoord, g_clusteredShading.m_tileSize, g_clusteredShading.m_tileCounts, g_clusteredShading.m_zSplitCount,
 							   g_clusteredShading.m_zSplitMagic.x, g_clusteredShading.m_zSplitMagic.y);
 							   g_clusteredShading.m_zSplitMagic.x, g_clusteredShading.m_zSplitMagic.y);
 }
 }
+#else
+/// Get the final cluster after ORing and ANDing the masks.
+Cluster getClusterFragCoord(StructuredBuffer<Cluster> clusters, Vec3 fragCoord, U32 tileSize, UVec2 tileCounts, U32 zSplitCount, F32 a, F32 b)
+{
+	const Cluster tileCluster = clusters[computeTileClusterIndexFragCoord(fragCoord.xy, tileSize, tileCounts.x)];
+	const Cluster zCluster = clusters[computeZSplitClusterIndex(fragCoord.z, zSplitCount, a, b) + tileCounts.x * tileCounts.y];
+	return mergeClusters(tileCluster, zCluster);
+}
+
+Cluster getClusterFragCoord(StructuredBuffer<Cluster> clusters, ClusteredShadingUniforms2 unis, Vec3 fragCoord)
+{
+	return getClusterFragCoord(clusters, fragCoord, unis.m_tileSize, unis.m_tileCounts, unis.m_zSplitCount, unis.m_zSplitMagic.x,
+							   unis.m_zSplitMagic.y);
+}
 #endif
 #endif

+ 30 - 0
AnKi/Shaders/Include/ClusteredShadingTypes.h

@@ -282,6 +282,36 @@ constexpr U32 kSizeof_ClusteredShadingUniforms =
 	(6u + (U32)ClusteredObjectType::kCount) * sizeof(Vec4) + 2u * sizeof(CommonMatrices) + sizeof(DirectionalLight);
 	(6u + (U32)ClusteredObjectType::kCount) * sizeof(Vec4) + 2u * sizeof(CommonMatrices) + sizeof(DirectionalLight);
 static_assert(sizeof(ClusteredShadingUniforms) == kSizeof_ClusteredShadingUniforms);
 static_assert(sizeof(ClusteredShadingUniforms) == kSizeof_ClusteredShadingUniforms);
 
 
+/// Common uniforms for light shading passes.
+struct ClusteredShadingUniforms2
+{
+	Vec2 m_renderingSize;
+	F32 m_time;
+	U32 m_frame;
+
+	Vec4 m_nearPlaneWSpace;
+
+	Vec3 m_cameraPosition;
+	F32 m_reflectionProbesMipCount;
+
+	UVec2 m_tileCounts;
+	U32 m_zSplitCount;
+	F32 m_zSplitCountOverFrustumLength; ///< m_zSplitCount/(far-near)
+
+	Vec2 m_zSplitMagic; ///< It's the "a" and "b" of computeZSplitClusterIndex(). See there for details.
+	U32 m_tileSize;
+	U32 m_lightVolumeLastZSplit;
+
+	UVec2 m_padding0;
+	F32 m_near;
+	F32 m_far;
+
+	DirectionalLight m_directionalLight;
+
+	CommonMatrices m_matrices;
+	CommonMatrices m_previousMatrices;
+};
+
 // Define the type of some cluster object masks
 // Define the type of some cluster object masks
 #if ANKI_GLSL
 #if ANKI_GLSL
 #	if ANKI_CLUSTERED_SHADING_USE_64BIT
 #	if ANKI_CLUSTERED_SHADING_USE_64BIT

+ 8 - 10
AnKi/Shaders/IndirectDiffuse.hlsl

@@ -10,6 +10,7 @@
 #include <AnKi/Shaders/ImportanceSampling.hlsl>
 #include <AnKi/Shaders/ImportanceSampling.hlsl>
 #include <AnKi/Shaders/TonemappingFunctions.hlsl>
 #include <AnKi/Shaders/TonemappingFunctions.hlsl>
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
+#include <AnKi/Shaders/ClusteredShadingCommon.hlsl>
 
 
 #define ENABLE_SSGI true
 #define ENABLE_SSGI true
 #define ENABLE_PROBES true
 #define ENABLE_PROBES true
@@ -19,19 +20,16 @@
 
 
 ANKI_SPECIALIZATION_CONSTANT_U32(kSampleCount, 0u);
 ANKI_SPECIALIZATION_CONSTANT_U32(kSampleCount, 0u);
 
 
-#define CLUSTERED_SHADING_SET 0u
-#define CLUSTERED_SHADING_UNIFORMS_BINDING 0u
-#define CLUSTERED_SHADING_GI_BINDING 1u
-#define CLUSTERED_SHADING_CLUSTERS_BINDING 2u
-#include <AnKi/Shaders/ClusteredShadingCommon.hlsl>
-
+[[vk::binding(0)]] ConstantBuffer<ClusteredShadingUniforms2> g_clusteredShading;
+[[vk::binding(1)]] StructuredBuffer<GlobalIlluminationProbe> g_giProbes;
+[[vk::binding(2)]] StructuredBuffer<Cluster> g_clusters;
 [[vk::binding(3)]] SamplerState g_linearAnyClampSampler;
 [[vk::binding(3)]] SamplerState g_linearAnyClampSampler;
 [[vk::binding(4)]] Texture2D<Vec4> g_gbufferRt2;
 [[vk::binding(4)]] Texture2D<Vec4> g_gbufferRt2;
-[[vk::binding(5)]] Texture2D g_depthTex;
+[[vk::binding(5)]] Texture2D<Vec4> g_depthTex;
 [[vk::binding(6)]] Texture2D<RVec4> g_lightBufferRt;
 [[vk::binding(6)]] Texture2D<RVec4> g_lightBufferRt;
 [[vk::binding(7)]] Texture2D<RVec4> g_historyTex;
 [[vk::binding(7)]] Texture2D<RVec4> g_historyTex;
-[[vk::binding(8)]] Texture2D g_motionVectorsTex;
-[[vk::binding(9)]] Texture2D g_historyLengthTex;
+[[vk::binding(8)]] Texture2D<Vec4> g_motionVectorsTex;
+[[vk::binding(9)]] Texture2D<Vec4> g_historyLengthTex;
 
 
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)
 [[vk::binding(10)]] RWTexture2D<RVec4> g_outUav;
 [[vk::binding(10)]] RWTexture2D<RVec4> g_outUav;
@@ -151,7 +149,7 @@ RVec3 main([[vk::location(0)]] Vec2 uv : TEXCOORD, Vec4 svPosition : SV_POSITION
 		RVec3 probeColor = Vec3(0.0, 0.0, 0.0);
 		RVec3 probeColor = Vec3(0.0, 0.0, 0.0);
 
 
 		// Get the cluster
 		// Get the cluster
-		Cluster cluster = getClusterFragCoord(Vec3(fragCoord * 2.0, depth));
+		Cluster cluster = getClusterFragCoord(g_clusters, g_clusteredShading, Vec3(fragCoord * 2.0, depth));
 
 
 		const U32 oneProbe = WaveActiveAllTrue(countbits(cluster.m_giProbesMask) == 1);
 		const U32 oneProbe = WaveActiveAllTrue(countbits(cluster.m_giProbesMask) == 1);
 		if(oneProbe)
 		if(oneProbe)

+ 9 - 9
AnKi/Shaders/IndirectSpecular.hlsl

@@ -11,28 +11,28 @@
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
 #include <AnKi/Shaders/TonemappingFunctions.hlsl>
 #include <AnKi/Shaders/TonemappingFunctions.hlsl>
 #include <AnKi/Shaders/SsRaymarching.hlsl>
 #include <AnKi/Shaders/SsRaymarching.hlsl>
+#include <AnKi/Shaders/ClusteredShadingCommon.hlsl>
 
 
 [[vk::binding(0)]] ConstantBuffer<SsrUniforms> g_unis;
 [[vk::binding(0)]] ConstantBuffer<SsrUniforms> g_unis;
 
 
 [[vk::binding(1)]] SamplerState g_trilinearClampSampler;
 [[vk::binding(1)]] SamplerState g_trilinearClampSampler;
 [[vk::binding(2)]] Texture2D<RVec4> g_gbufferRt1;
 [[vk::binding(2)]] Texture2D<RVec4> g_gbufferRt1;
 [[vk::binding(3)]] Texture2D<RVec4> g_gbufferRt2;
 [[vk::binding(3)]] Texture2D<RVec4> g_gbufferRt2;
-[[vk::binding(4)]] Texture2D g_depthRt;
+[[vk::binding(4)]] Texture2D<Vec4> g_depthRt;
 [[vk::binding(5)]] Texture2D<RVec4> g_lightBufferRt;
 [[vk::binding(5)]] Texture2D<RVec4> g_lightBufferRt;
 
 
 [[vk::binding(6)]] Texture2D<RVec4> g_historyTex;
 [[vk::binding(6)]] Texture2D<RVec4> g_historyTex;
-[[vk::binding(7)]] Texture2D g_motionVectorsTex;
+[[vk::binding(7)]] Texture2D<Vec4> g_motionVectorsTex;
 [[vk::binding(8)]] Texture2D<RVec4> g_historyLengthTex;
 [[vk::binding(8)]] Texture2D<RVec4> g_historyLengthTex;
 
 
 [[vk::binding(9)]] SamplerState g_trilinearRepeatSampler;
 [[vk::binding(9)]] SamplerState g_trilinearRepeatSampler;
 [[vk::binding(10)]] Texture2D<RVec4> g_noiseTex;
 [[vk::binding(10)]] Texture2D<RVec4> g_noiseTex;
-constexpr Vec2 kNoiseTexSize = 64.0;
 
 
-#define CLUSTERED_SHADING_SET 0u
-#define CLUSTERED_SHADING_UNIFORMS_BINDING 11u
-#define CLUSTERED_SHADING_REFLECTIONS_BINDING 12u
-#define CLUSTERED_SHADING_CLUSTERS_BINDING 13u
-#include <AnKi/Shaders/ClusteredShadingCommon.hlsl>
+[[vk::binding(11)]] ConstantBuffer<ClusteredShadingUniforms2> g_clusteredShading;
+[[vk::binding(12)]] StructuredBuffer<ReflectionProbe> g_reflectionProbes;
+[[vk::binding(13)]] StructuredBuffer<Cluster> g_clusters;
+
+constexpr Vec2 kNoiseTexSize = 64.0;
 
 
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)
 [[vk::binding(14)]] RWTexture2D<RVec4> g_outUav;
 [[vk::binding(14)]] RWTexture2D<RVec4> g_outUav;
@@ -190,7 +190,7 @@ RVec3 main(Vec2 uv : TEXCOORD, Vec4 svPosition : SV_POSITION) : SV_TARGET0
 		const Vec2 ndc = uvToNdc(uv);
 		const Vec2 ndc = uvToNdc(uv);
 		const Vec4 worldPos4 = mul(g_clusteredShading.m_matrices.m_invertedViewProjectionJitter, Vec4(ndc, depth, 1.0));
 		const Vec4 worldPos4 = mul(g_clusteredShading.m_matrices.m_invertedViewProjectionJitter, Vec4(ndc, depth, 1.0));
 		const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
 		const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
-		Cluster cluster = getClusterFragCoord(Vec3(fragCoord * 2.0, depth));
+		Cluster cluster = getClusterFragCoord(g_clusters, g_clusteredShading, Vec3(fragCoord * 2.0, depth));
 
 
 		// Compute the refl dir in word space this time
 		// Compute the refl dir in word space this time
 		const RVec3 viewDir = normalize(g_clusteredShading.m_cameraPosition - worldPos);
 		const RVec3 viewDir = normalize(g_clusteredShading.m_cameraPosition - worldPos);