浏览代码

Add GPU visibility in probe reflection rendering

Panagiotis Christopoulos Charitos 2 年之前
父节点
当前提交
ed9e0121fb

+ 3 - 8
AnKi/Renderer/GBuffer.cpp

@@ -8,7 +8,6 @@
 #include <AnKi/Renderer/RenderQueue.h>
 #include <AnKi/Renderer/VrsSriGeneration.h>
 #include <AnKi/Renderer/Scale.h>
-#include <AnKi/Renderer/GpuVisibility.h>
 #include <AnKi/Util/Logger.h>
 #include <AnKi/Util/Tracer.h>
 #include <AnKi/Core/ConfigSet.h>
@@ -23,11 +22,6 @@ Error GBuffer::init()
 {
 	Error err = initInternal();
 
-	if(!err)
-	{
-		err = m_visibility.init();
-	}
-
 	if(!err)
 	{
 		err = m_hzb.init();
@@ -170,8 +164,9 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 	const Array<F32, kMaxLodCount - 1> lodDistances = {ConfigSet::getSingleton().getLod0MaxDistance(),
 													   ConfigSet::getSingleton().getLod1MaxDistance()};
 	GpuVisibilityOutput visOut;
-	m_visibility.populateRenderGraph(RenderingTechnique::kGBuffer, matrices.m_viewProjection, matrices.m_cameraTransform.getTranslationPart().xyz(),
-									 lodDistances, &m_runCtx.m_hzbRt, rgraph, visOut);
+	getRenderer().getGpuVisibility().populateRenderGraph(RenderingTechnique::kGBuffer, matrices.m_viewProjection,
+														 matrices.m_cameraTransform.getTranslationPart().xyz(), lodDistances, &m_runCtx.m_hzbRt,
+														 rgraph, visOut);
 
 	const Bool enableVrs =
 		GrManager::getSingleton().getDeviceCapabilities().m_vrs && ConfigSet::getSingleton().getRVrs() && ConfigSet::getSingleton().getRGBufferVrs();

+ 3 - 2
AnKi/Renderer/GBuffer.h

@@ -6,12 +6,14 @@
 #pragma once
 
 #include <AnKi/Renderer/RendererObject.h>
-#include <AnKi/Renderer/GpuVisibility.h>
 #include <AnKi/Renderer/HzbHelper.h>
 #include <AnKi/Gr.h>
 
 namespace anki {
 
+// Forward
+class GpuVisibilityOutput;
+
 /// @addtogroup renderer
 /// @{
 
@@ -78,7 +80,6 @@ private:
 	FramebufferDescription m_fbDescr;
 
 	HzbHelper m_hzb;
-	GpuVisibility m_visibility;
 
 	class
 	{

+ 1 - 1
AnKi/Renderer/GpuVisibility.cpp

@@ -54,7 +54,7 @@ Error GpuVisibility::init()
 
 void GpuVisibility::populateRenderGraph(RenderingTechnique technique, const Mat4& viewProjectionMat, Vec3 lodReferencePoint,
 										const Array<F32, kMaxLodCount - 1> lodDistances, const RenderTargetHandle* hzbRt,
-										RenderGraphDescription& rgraph, GpuVisibilityOutput& out)
+										RenderGraphDescription& rgraph, GpuVisibilityOutput& out) const
 {
 	const U32 aabbCount = GpuSceneContiguousArrays::getSingleton().getElementCount(techniqueToArrayType(technique));
 	const U32 bucketCount = RenderStateBucketContainer::getSingleton().getBucketCount(technique);

+ 1 - 1
AnKi/Renderer/GpuVisibility.h

@@ -42,7 +42,7 @@ public:
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingTechnique technique, const Mat4& viewProjectionMat, Vec3 lodReferencePoint,
 							 const Array<F32, kMaxLodCount - 1> lodDistances, const RenderTargetHandle* hzbRt, RenderGraphDescription& rgraph,
-							 GpuVisibilityOutput& out);
+							 GpuVisibilityOutput& out) const;
 
 private:
 	ShaderProgramResourcePtr m_prog;

+ 86 - 100
AnKi/Renderer/ProbeReflections.cpp

@@ -174,50 +174,31 @@ Error ProbeReflections::initShadowMapping()
 	return Error::kNone;
 }
 
-void ProbeReflections::runGBuffer(RenderPassWorkContext& rgraphCtx)
+void ProbeReflections::runGBuffer(const Array<GpuVisibilityOutput, 6>& visOuts, RenderPassWorkContext& rgraphCtx)
 {
 	ANKI_ASSERT(m_ctx.m_probe);
 	ANKI_TRACE_SCOPED_EVENT(RCubeRefl);
 	const ReflectionProbeQueueElementForRefresh& probe = *m_ctx.m_probe;
 	CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 
-	I32 start, end;
-	U32 startu, endu;
-	splitThreadedProblem(rgraphCtx.m_currentSecondLevelCommandBufferIndex, rgraphCtx.m_secondLevelCommandBufferCount, m_ctx.m_gbufferRenderableCount,
-						 startu, endu);
-	start = I32(startu);
-	end = I32(endu);
+	const U32 faceIdx = rgraphCtx.m_currentSecondLevelCommandBufferIndex;
 
-	I32 drawcallCount = 0;
-	for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
-	{
-		const I32 faceDrawcallCount = I32(probe.m_renderQueues[faceIdx]->m_renderables.getSize());
-		const I32 localStart = max(I32(0), start - drawcallCount);
-		const I32 localEnd = min(faceDrawcallCount, end - drawcallCount);
+	const U32 viewportX = faceIdx * m_gbuffer.m_tileSize;
+	cmdb.setViewport(viewportX, 0, m_gbuffer.m_tileSize, m_gbuffer.m_tileSize);
+	cmdb.setScissor(viewportX, 0, m_gbuffer.m_tileSize, m_gbuffer.m_tileSize);
 
-		if(localStart < localEnd)
-		{
-			const U32 viewportX = faceIdx * m_gbuffer.m_tileSize;
-			cmdb.setViewport(viewportX, 0, m_gbuffer.m_tileSize, m_gbuffer.m_tileSize);
-			cmdb.setScissor(viewportX, 0, m_gbuffer.m_tileSize, m_gbuffer.m_tileSize);
-
-			const RenderQueue& rqueue = *probe.m_renderQueues[faceIdx];
-			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
-
-			RenderableDrawerArguments args;
-			args.m_viewMatrix = rqueue.m_viewMatrix;
-			args.m_cameraTransform = rqueue.m_cameraTransform;
-			args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
-			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care about prev mats
-			args.m_sampler = getRenderer().getSamplers().m_trilinearRepeat.get();
-
-			getRenderer().getSceneDrawer().drawRange(args, rqueue.m_renderables.getBegin() + localStart, rqueue.m_renderables.getBegin() + localEnd,
-													 cmdb);
-		}
-	}
+	const RenderQueue& rqueue = *probe.m_renderQueues[faceIdx];
 
-	// Restore state
-	cmdb.setScissor(0, 0, kMaxU32, kMaxU32);
+	RenderableDrawerArguments args;
+	args.m_viewMatrix = rqueue.m_viewMatrix;
+	args.m_cameraTransform = rqueue.m_cameraTransform;
+	args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
+	args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care about prev mats
+	args.m_sampler = getRenderer().getSamplers().m_trilinearRepeat.get();
+	args.m_renderingTechinuqe = RenderingTechnique::kGBuffer;
+	args.fillMdi(visOuts[faceIdx]);
+
+	getRenderer().getSceneDrawer().drawMdi(args, cmdb);
 }
 
 void ProbeReflections::runLightShading(U32 faceIdx, const RenderingContext& rctx, RenderPassWorkContext& rgraphCtx)
@@ -346,7 +327,18 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 	RenderGraphDescription& rgraph = rctx.m_renderGraphDescr;
 
-	// G-buffer pass
+	// GBuffer visibility
+	Array<GpuVisibilityOutput, 6> visOuts;
+	for(U32 i = 0; i < 6; ++i)
+	{
+		const RenderQueue& queue = *m_ctx.m_probe->m_renderQueues[i];
+		Array<F32, kMaxLodCount - 1> lodDistances = {1000.0f, 1001.0f}; // Something far to force detailed LODs
+		getRenderer().getGpuVisibility().populateRenderGraph(RenderingTechnique::kGBuffer, queue.m_viewProjectionMatrix,
+															 queue.m_cameraTransform.getTranslationPart().xyz(), lodDistances, nullptr, rgraph,
+															 visOuts[i]);
+	}
+
+	// GBuffer pass
 	{
 		// RTs
 		Array<RenderTargetHandle, kMaxColorRenderTargets> rts;
@@ -357,19 +349,11 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 		}
 		m_ctx.m_gbufferDepthRt = rgraph.newRenderTarget(m_gbuffer.m_depthRtDescr);
 
-		// Compute task count
-		m_ctx.m_gbufferRenderableCount = 0;
-		for(U32 i = 0; i < 6; ++i)
-		{
-			m_ctx.m_gbufferRenderableCount += m_ctx.m_probe->m_renderQueues[i]->m_renderables.getSize();
-		}
-		const U32 taskCount = computeNumberOfSecondLevelCommandBuffers(m_ctx.m_gbufferRenderableCount);
-
 		// Pass
-		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("CubeRefl gbuff");
+		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("CubeRefl GBuffer");
 		pass.setFramebufferInfo(m_gbuffer.m_fbDescr, rts, m_ctx.m_gbufferDepthRt);
-		pass.setWork(taskCount, [this](RenderPassWorkContext& rgraphCtx) {
-			runGBuffer(rgraphCtx);
+		pass.setWork(6, [this, visOuts](RenderPassWorkContext& rgraphCtx) {
+			runGBuffer(visOuts, rgraphCtx);
 		});
 
 		for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
@@ -382,10 +366,32 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 		pass.newBufferDependency(getRenderer().getGpuSceneBufferHandle(),
 								 BufferUsageBit::kStorageGeometryRead | BufferUsageBit::kStorageFragmentRead);
+
+		for(U32 i = 0; i < 6; ++i)
+		{
+			pass.newBufferDependency(visOuts[i].m_mdiDrawCountsHandle, BufferUsageBit::kIndirectDraw);
+		}
+	}
+
+	// Shadow visibility. Optional
+	const Bool doShadows =
+		m_ctx.m_probe->m_renderQueues[0]->m_directionalLight.m_uuid && m_ctx.m_probe->m_renderQueues[0]->m_directionalLight.m_shadowCascadeCount > 0;
+	Array<GpuVisibilityOutput, 6> shadowVisOuts;
+	if(doShadows)
+	{
+		for(U i = 0; i < 6; ++i)
+		{
+			const RenderQueue& queue = *m_ctx.m_probe->m_renderQueues[i]->m_directionalLight.m_shadowRenderQueues[0];
+			Array<F32, kMaxLodCount - 1> lodDistances = {1000.0f, 1001.0f}; // Something far to force detailed LODs
+
+			getRenderer().getGpuVisibility().populateRenderGraph(RenderingTechnique::kDepth, queue.m_viewProjectionMatrix,
+																 queue.m_cameraTransform.getTranslationPart().xyz(), lodDistances, nullptr, rgraph,
+																 shadowVisOuts[i]);
+		}
 	}
 
-	// Shadow pass. Optional
-	if(m_ctx.m_probe->m_renderQueues[0]->m_directionalLight.m_uuid && m_ctx.m_probe->m_renderQueues[0]->m_directionalLight.m_shadowCascadeCount > 0)
+	// Shadows. Optional
+	if(doShadows)
 	{
 		// Update light matrices
 		for(U i = 0; i < 6; ++i)
@@ -403,22 +409,14 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 			lightMat = atlasMtx * lightMat;
 		}
 
-		// Compute task count
-		m_ctx.m_shadowRenderableCount = 0;
-		for(U32 i = 0; i < 6; ++i)
-		{
-			m_ctx.m_shadowRenderableCount += m_ctx.m_probe->m_renderQueues[i]->m_directionalLight.m_shadowRenderQueues[0]->m_renderables.getSize();
-		}
-		const U32 taskCount = computeNumberOfSecondLevelCommandBuffers(m_ctx.m_shadowRenderableCount);
-
 		// RT
 		m_ctx.m_shadowMapRt = rgraph.newRenderTarget(m_shadowMapping.m_rtDescr);
 
 		// Pass
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("CubeRefl SM");
 		pass.setFramebufferInfo(m_shadowMapping.m_fbDescr, {}, m_ctx.m_shadowMapRt);
-		pass.setWork(taskCount, [this](RenderPassWorkContext& rgraphCtx) {
-			runShadowMapping(rgraphCtx);
+		pass.setWork(6, [this, shadowVisOuts](RenderPassWorkContext& rgraphCtx) {
+			runShadowMapping(shadowVisOuts, rgraphCtx);
 		});
 
 		TextureSubresourceInfo subresource(DepthStencilAspectBit::kDepth);
@@ -426,6 +424,11 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 		pass.newBufferDependency(getRenderer().getGpuSceneBufferHandle(),
 								 BufferUsageBit::kStorageGeometryRead | BufferUsageBit::kStorageFragmentRead);
+
+		for(U32 i = 0; i < 6; ++i)
+		{
+			pass.newBufferDependency(shadowVisOuts[i].m_mdiDrawCountsHandle, BufferUsageBit::kIndirectDraw);
+		}
 	}
 	else
 	{
@@ -522,54 +525,37 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 	}
 }
 
-void ProbeReflections::runShadowMapping(RenderPassWorkContext& rgraphCtx)
+void ProbeReflections::runShadowMapping(const Array<GpuVisibilityOutput, 6>& visOuts, RenderPassWorkContext& rgraphCtx)
 {
 	ANKI_ASSERT(m_ctx.m_probe);
 	ANKI_TRACE_SCOPED_EVENT(RCubeRefl);
 
-	I32 start, end;
-	U32 startu, endu;
-	splitThreadedProblem(rgraphCtx.m_currentSecondLevelCommandBufferIndex, rgraphCtx.m_secondLevelCommandBufferCount, m_ctx.m_shadowRenderableCount,
-						 startu, endu);
-	start = I32(startu);
-	end = I32(endu);
-
 	CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 	cmdb.setPolygonOffset(kShadowsPolygonOffsetFactor, kShadowsPolygonOffsetUnits);
 
-	I32 drawcallCount = 0;
-	for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
-	{
-		ANKI_ASSERT(m_ctx.m_probe->m_renderQueues[faceIdx]);
-		const RenderQueue& faceRenderQueue = *m_ctx.m_probe->m_renderQueues[faceIdx];
-		ANKI_ASSERT(faceRenderQueue.m_directionalLight.m_uuid != 0);
-		ANKI_ASSERT(faceRenderQueue.m_directionalLight.m_shadowCascadeCount == 1);
-		ANKI_ASSERT(faceRenderQueue.m_directionalLight.m_shadowRenderQueues[0]);
-		const RenderQueue& cascadeRenderQueue = *faceRenderQueue.m_directionalLight.m_shadowRenderQueues[0];
-
-		const I32 faceDrawcallCount = I32(cascadeRenderQueue.m_renderables.getSize());
-		const I32 localStart = max(I32(0), start - drawcallCount);
-		const I32 localEnd = min(faceDrawcallCount, end - drawcallCount);
-
-		if(localStart < localEnd)
-		{
-			const U32 rez = m_shadowMapping.m_rtDescr.m_height;
-			cmdb.setViewport(rez * faceIdx, 0, rez, rez);
-			cmdb.setScissor(rez * faceIdx, 0, rez, rez);
-
-			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
-
-			RenderableDrawerArguments args;
-			args.m_viewMatrix = cascadeRenderQueue.m_viewMatrix;
-			args.m_cameraTransform = Mat3x4::getIdentity(); // Don't care
-			args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
-			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
-			args.m_sampler = getRenderer().getSamplers().m_trilinearRepeatAniso.get();
-
-			getRenderer().getSceneDrawer().drawRange(args, cascadeRenderQueue.m_renderables.getBegin() + localStart,
-													 cascadeRenderQueue.m_renderables.getBegin() + localEnd, cmdb);
-		}
-	}
+	const U32 faceIdx = rgraphCtx.m_currentSecondLevelCommandBufferIndex;
+
+	ANKI_ASSERT(m_ctx.m_probe->m_renderQueues[faceIdx]);
+	const RenderQueue& faceRenderQueue = *m_ctx.m_probe->m_renderQueues[faceIdx];
+	ANKI_ASSERT(faceRenderQueue.m_directionalLight.m_uuid != 0);
+	ANKI_ASSERT(faceRenderQueue.m_directionalLight.m_shadowCascadeCount == 1);
+	ANKI_ASSERT(faceRenderQueue.m_directionalLight.m_shadowRenderQueues[0]);
+	const RenderQueue& cascadeRenderQueue = *faceRenderQueue.m_directionalLight.m_shadowRenderQueues[0];
+
+	const U32 rez = m_shadowMapping.m_rtDescr.m_height;
+	cmdb.setViewport(rez * faceIdx, 0, rez, rez);
+	cmdb.setScissor(rez * faceIdx, 0, rez, rez);
+
+	RenderableDrawerArguments args;
+	args.m_viewMatrix = cascadeRenderQueue.m_viewMatrix;
+	args.m_cameraTransform = Mat3x4::getIdentity(); // Don't care
+	args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
+	args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
+	args.m_sampler = getRenderer().getSamplers().m_trilinearRepeatAniso.get();
+	args.m_renderingTechinuqe = RenderingTechnique::kDepth;
+	args.fillMdi(visOuts[faceIdx]);
+
+	getRenderer().getSceneDrawer().drawMdi(args, cmdb);
 }
 
 } // end namespace anki

+ 5 - 5
AnKi/Renderer/ProbeReflections.h

@@ -11,6 +11,9 @@
 
 namespace anki {
 
+// Forward
+class GpuVisibilityOutput;
+
 /// @addtogroup renderer
 /// @{
 
@@ -107,9 +110,6 @@ private:
 		RenderTargetHandle m_lightShadingRt;
 		BufferHandle m_irradianceDiceValuesBuffHandle;
 		RenderTargetHandle m_shadowMapRt;
-
-		U32 m_gbufferRenderableCount = 0;
-		U32 m_shadowRenderableCount = 0;
 	} m_ctx; ///< Runtime context.
 
 	Error initInternal();
@@ -119,8 +119,8 @@ private:
 	Error initIrradianceToRefl();
 	Error initShadowMapping();
 
-	void runGBuffer(RenderPassWorkContext& rgraphCtx);
-	void runShadowMapping(RenderPassWorkContext& rgraphCtx);
+	void runGBuffer(const Array<GpuVisibilityOutput, 6>& visOuts, RenderPassWorkContext& rgraphCtx);
+	void runShadowMapping(const Array<GpuVisibilityOutput, 6>& visOuts, RenderPassWorkContext& rgraphCtx);
 	void runLightShading(U32 faceIdx, const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 	void runMipmappingOfLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx);
 	void runIrradiance(RenderPassWorkContext& rgraphCtx);

+ 2 - 0
AnKi/Renderer/Renderer.cpp

@@ -290,6 +290,8 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 		m_jitterOffsets[i] = generateJitter(i);
 	}
 
+	ANKI_CHECK(m_visibility.init());
+
 	return Error::kNone;
 }
 

+ 7 - 0
AnKi/Renderer/Renderer.h

@@ -7,6 +7,7 @@
 
 #include <AnKi/Renderer/Common.h>
 #include <AnKi/Renderer/Drawer.h>
+#include <AnKi/Renderer/GpuVisibility.h>
 #include <AnKi/Math.h>
 #include <AnKi/Gr.h>
 #include <AnKi/Resource/Forward.h>
@@ -88,6 +89,11 @@ public:
 		return m_sceneDrawer;
 	}
 
+	const GpuVisibility& getGpuVisibility() const
+	{
+		return m_visibility;
+	}
+
 	/// Create the init info for a 2D texture that will be used as a render target.
 	[[nodiscard]] TextureInitInfo create2DRenderTargetInitInfo(U32 w, U32 h, Format format, TextureUsageBit usage, CString name = {});
 
@@ -181,6 +187,7 @@ private:
 	UVec2 m_postProcessResolution = UVec2(0u); ///< The resolution of post processing and following passes.
 
 	RenderableDrawer m_sceneDrawer;
+	GpuVisibility m_visibility;
 
 	U64 m_frameCount; ///< Frame number
 

+ 1 - 1
AnKi/Renderer/RendererObject.cpp

@@ -16,7 +16,7 @@ Renderer& RendererObject::getRenderer()
 	return MainRenderer::getSingleton().getOffscreenRenderer();
 }
 
-void* RendererObject::allocateRebarStagingMemory(PtrSize size, RebarAllocation& token)
+void* RendererObject::allocateRebarStagingMemory(PtrSize size, RebarAllocation& token) const
 {
 	return RebarTransientMemoryPool::getSingleton().allocateFrame(size, token);
 }

+ 5 - 5
AnKi/Renderer/RendererObject.h

@@ -38,7 +38,7 @@ public:
 protected:
 	static ANKI_PURE Renderer& getRenderer();
 
-	void* allocateRebarStagingMemory(PtrSize size, RebarAllocation& token);
+	void* allocateRebarStagingMemory(PtrSize size, RebarAllocation& token) const;
 
 	U32 computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount) const;
 
@@ -66,7 +66,7 @@ protected:
 	}
 
 	template<typename TPtr>
-	TPtr allocateUniforms(PtrSize size, RebarAllocation& token)
+	TPtr allocateUniforms(PtrSize size, RebarAllocation& token) const
 	{
 		return static_cast<TPtr>(allocateRebarStagingMemory(size, token));
 	}
@@ -74,7 +74,7 @@ protected:
 	void bindUniforms(CommandBuffer& cmdb, U32 set, U32 binding, const RebarAllocation& token) const;
 
 	template<typename TPtr>
-	TPtr allocateAndBindUniforms(PtrSize size, CommandBuffer& cmdb, U32 set, U32 binding)
+	TPtr allocateAndBindUniforms(PtrSize size, CommandBuffer& cmdb, U32 set, U32 binding) const
 	{
 		RebarAllocation token;
 		TPtr ptr = allocateUniforms<TPtr>(size, token);
@@ -83,7 +83,7 @@ protected:
 	}
 
 	template<typename TPtr>
-	TPtr allocateStorage(PtrSize size, RebarAllocation& token)
+	TPtr allocateStorage(PtrSize size, RebarAllocation& token) const
 	{
 		return static_cast<TPtr>(allocateRebarStagingMemory(size, token));
 	}
@@ -91,7 +91,7 @@ protected:
 	void bindStorage(CommandBuffer& cmdb, U32 set, U32 binding, const RebarAllocation& token) const;
 
 	template<typename TPtr>
-	TPtr allocateAndBindStorage(PtrSize size, CommandBuffer& cmdb, U32 set, U32 binding)
+	TPtr allocateAndBindStorage(PtrSize size, CommandBuffer& cmdb, U32 set, U32 binding) const
 	{
 		RebarAllocation token;
 		TPtr ptr = allocateStorage<TPtr>(size, token);

+ 3 - 4
AnKi/Renderer/ShadowMapping.cpp

@@ -64,8 +64,6 @@ Error ShadowMapping::initInternal()
 	m_clearDepthProg->getOrCreateVariant(variant);
 	m_clearDepthGrProg.reset(&variant->getProgram());
 
-	ANKI_CHECK(m_visibility.init());
-
 	return Error::kNone;
 }
 
@@ -237,8 +235,9 @@ void ShadowMapping::newWorkItem(const UVec4& atlasViewport, const RenderQueue& q
 
 	const Array<F32, kMaxLodCount - 1> lodDistances = {ConfigSet::getSingleton().getLod0MaxDistance(),
 													   ConfigSet::getSingleton().getLod1MaxDistance()};
-	m_visibility.populateRenderGraph(RenderingTechnique::kDepth, queue.m_viewProjectionMatrix, queue.m_cameraTransform.getTranslationPart().xyz(),
-									 lodDistances, nullptr, rgraph, work.m_visOut);
+	getRenderer().getGpuVisibility().populateRenderGraph(RenderingTechnique::kDepth, queue.m_viewProjectionMatrix,
+														 queue.m_cameraTransform.getTranslationPart().xyz(), lodDistances, nullptr, rgraph,
+														 work.m_visOut);
 
 	work.m_viewport = atlasViewport;
 	work.m_mvp = queue.m_viewProjectionMatrix;

+ 0 - 3
AnKi/Renderer/ShadowMapping.h

@@ -9,7 +9,6 @@
 #include <AnKi/Gr.h>
 #include <AnKi/Resource/ImageResource.h>
 #include <AnKi/Renderer/TileAllocator.h>
-#include <AnKi/Renderer/GpuVisibility.h>
 
 namespace anki {
 
@@ -53,8 +52,6 @@ private:
 	ShaderProgramResourcePtr m_clearDepthProg;
 	ShaderProgramPtr m_clearDepthGrProg;
 
-	GpuVisibility m_visibility;
-
 	class
 	{
 	public:

+ 3 - 3
AnKi/Shaders/TraditionalDeferredShading.ankiprog

@@ -53,9 +53,9 @@ Vec4 main([[vk::location(0)]] Vec3 position : POSITION) : SV_POSITION
 	g_unis;
 
 [[vk::binding(2)]] SamplerState g_gbufferSampler;
-[[vk::binding(3)]] Texture2D<RVec4> g_gbufferTex0;
-[[vk::binding(4)]] Texture2D<RVec4> g_gbufferTex1;
-[[vk::binding(5)]] Texture2D<RVec4> g_gbufferTex2;
+[[vk::binding(3)]] Texture2D<Vec4> g_gbufferTex0;
+[[vk::binding(4)]] Texture2D<Vec4> g_gbufferTex1;
+[[vk::binding(5)]] Texture2D<Vec4> g_gbufferTex2;
 [[vk::binding(6)]] Texture2D g_depthTex;
 
 #if LIGHT_TYPE == DIR_LIGHT_TYPE