Browse Source

Nuke VK's render area (DX doesn't support this). Fix a VK bug setting the scissor

Panagiotis Christopoulos Charitos 11 months ago
parent
commit
dbe172633c

+ 5 - 9
AnKi/Gr/CommandBuffer.h

@@ -234,18 +234,14 @@ public:
 	void bindShaderProgram(ShaderProgram* prog);
 
 	/// Begin a renderpass.
-	/// The minx, miny, width, height control the area that the load and store operations will happen. If the scissor is bigger than the render area
-	/// the results are undefined.
-	void beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, U32 minx = 0, U32 miny = 0, U32 width = kMaxU32,
-						 U32 height = kMaxU32, const TextureView& vrsRt = TextureView(), U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0);
+	void beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, const TextureView& vrsRt = TextureView(),
+						 U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0);
 
 	/// See beginRenderPass.
-	void beginRenderPass(std::initializer_list<RenderTarget> colorRts, RenderTarget* depthStencilRt = nullptr, U32 minx = 0, U32 miny = 0,
-						 U32 width = kMaxU32, U32 height = kMaxU32, const TextureView& vrsRt = TextureView(), U8 vrsRtTexelSizeX = 0,
-						 U8 vrsRtTexelSizeY = 0)
+	void beginRenderPass(std::initializer_list<RenderTarget> colorRts, RenderTarget* depthStencilRt = nullptr,
+						 const TextureView& vrsRt = TextureView(), U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0)
 	{
-		beginRenderPass(ConstWeakArray(colorRts.begin(), U32(colorRts.size())), depthStencilRt, minx, miny, width, height, vrsRt, vrsRtTexelSizeX,
-						vrsRtTexelSizeY);
+		beginRenderPass(ConstWeakArray(colorRts.begin(), U32(colorRts.size())), depthStencilRt, vrsRt, vrsRtTexelSizeX, vrsRtTexelSizeY);
 	}
 
 	/// End renderpass.

+ 2 - 3
AnKi/Gr/D3D/D3DCommandBuffer.cpp

@@ -308,9 +308,8 @@ void CommandBuffer::bindShaderProgram(ShaderProgram* prog)
 	}
 }
 
-void CommandBuffer::beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, U32 minx, U32 miny, U32 width, U32 height,
-									[[maybe_unused]] const TextureView& vrsRt, [[maybe_unused]] U8 vrsRtTexelSizeX,
-									[[maybe_unused]] U8 vrsRtTexelSizeY)
+void CommandBuffer::beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, [[maybe_unused]] const TextureView& vrsRt,
+									[[maybe_unused]] U8 vrsRtTexelSizeX, [[maybe_unused]] U8 vrsRtTexelSizeY)
 {
 	ANKI_D3D_SELF(CommandBufferImpl);
 	self.commandCommon();

+ 10 - 17
AnKi/Gr/RenderGraph.cpp

@@ -124,17 +124,12 @@ public:
 		Array<RenderTarget, kMaxColorRenderTargets> m_colorRts;
 		RenderTarget m_dsRt;
 		TextureView m_vrsRt;
-		Array<U32, 4> m_renderArea = {};
 		U8 m_colorRtCount = 0;
 		U8 m_vrsTexelSizeX = 0;
 		U8 m_vrsTexelSizeY = 0;
+		Bool m_hasRenderpass = false;
 
 		Array<TexturePtr, kMaxColorRenderTargets + 2> m_refs;
-
-		Bool hasRenderpass() const
-		{
-			return m_renderArea[3] != 0;
-		}
 	} m_beginRenderpassInfo;
 
 	BaseString<MemoryPoolPtrWrapper<StackMemoryPool>> m_name;
@@ -676,9 +671,9 @@ void RenderGraph::initGraphicsPasses(const RenderGraphBuilder& descr)
 		{
 			const GraphicsRenderPass& inPass = static_cast<const GraphicsRenderPass&>(baseInPass);
 
-			if(inPass.hasRenderpass())
+			if(inPass.m_hasRenderpass)
 			{
-				outPass.m_beginRenderpassInfo.m_renderArea = inPass.m_rpassRenderArea;
+				outPass.m_beginRenderpassInfo.m_hasRenderpass = true;
 				outPass.m_beginRenderpassInfo.m_colorRtCount = inPass.m_colorRtCount;
 
 				// Init the usage bits
@@ -982,8 +977,8 @@ void RenderGraph::minimizeSubchannelSwitches()
 		U32 computePasses = 0;
 
 		std::sort(batch.m_passIndices.getBegin(), batch.m_passIndices.getEnd(), [&](U32 a, U32 b) {
-			const Bool aIsCompute = !ctx.m_passes[a].m_beginRenderpassInfo.hasRenderpass();
-			const Bool bIsCompute = !ctx.m_passes[b].m_beginRenderpassInfo.hasRenderpass();
+			const Bool aIsCompute = !ctx.m_passes[a].m_beginRenderpassInfo.m_hasRenderpass;
+			const Bool bIsCompute = !ctx.m_passes[b].m_beginRenderpassInfo.m_hasRenderpass;
 
 			graphicsPasses += !aIsCompute + !bIsCompute;
 			computePasses += aIsCompute + bIsCompute;
@@ -1023,8 +1018,8 @@ void RenderGraph::sortBatchPasses()
 	for(Batch& batch : ctx.m_batches)
 	{
 		std::sort(batch.m_passIndices.getBegin(), batch.m_passIndices.getEnd(), [&](U32 a, U32 b) {
-			const Bool aIsCompute = !ctx.m_passes[a].m_beginRenderpassInfo.hasRenderpass();
-			const Bool bIsCompute = !ctx.m_passes[b].m_beginRenderpassInfo.hasRenderpass();
+			const Bool aIsCompute = !ctx.m_passes[a].m_beginRenderpassInfo.m_hasRenderpass;
+			const Bool bIsCompute = !ctx.m_passes[b].m_beginRenderpassInfo.m_hasRenderpass;
 
 			return aIsCompute < bIsCompute;
 		});
@@ -1209,16 +1204,14 @@ void RenderGraph::recordAndSubmitCommandBuffers(FencePtr* optionalFence)
 					{
 						Pass& pass = m_ctx->m_passes[passIdx];
 
-						const Vec3 passColor = (pass.m_beginRenderpassInfo.hasRenderpass()) ? Vec3(0.0f, 1.0f, 0.0f) : Vec3(1.0f, 1.0f, 0.0f);
+						const Vec3 passColor = (pass.m_beginRenderpassInfo.m_hasRenderpass) ? Vec3(0.0f, 1.0f, 0.0f) : Vec3(1.0f, 1.0f, 0.0f);
 						cmdb->pushDebugMarker(pass.m_name, passColor);
 
-						if(pass.m_beginRenderpassInfo.hasRenderpass())
+						if(pass.m_beginRenderpassInfo.m_hasRenderpass)
 						{
 							cmdb->beginRenderPass({pass.m_beginRenderpassInfo.m_colorRts.getBegin(), U32(pass.m_beginRenderpassInfo.m_colorRtCount)},
 												  pass.m_beginRenderpassInfo.m_dsRt.m_textureView.isValid() ? &pass.m_beginRenderpassInfo.m_dsRt
 																											: nullptr,
-												  pass.m_beginRenderpassInfo.m_renderArea[0], pass.m_beginRenderpassInfo.m_renderArea[1],
-												  pass.m_beginRenderpassInfo.m_renderArea[2], pass.m_beginRenderpassInfo.m_renderArea[3],
 												  pass.m_beginRenderpassInfo.m_vrsRt, pass.m_beginRenderpassInfo.m_vrsTexelSizeX,
 												  pass.m_beginRenderpassInfo.m_vrsTexelSizeY);
 						}
@@ -1229,7 +1222,7 @@ void RenderGraph::recordAndSubmitCommandBuffers(FencePtr* optionalFence)
 							pass.m_callback(ctx);
 						}
 
-						if(pass.m_beginRenderpassInfo.hasRenderpass())
+						if(pass.m_beginRenderpassInfo.m_hasRenderpass)
 						{
 							cmdb->endRenderPass();
 						}

+ 4 - 11
AnKi/Gr/RenderGraph.h

@@ -373,28 +373,21 @@ public:
 	}
 
 	void setRenderpassInfo(ConstWeakArray<GraphicsRenderPassTargetDesc> colorRts, const GraphicsRenderPassTargetDesc* depthStencilRt = nullptr,
-						   U32 minx = 0, U32 miny = 0, U32 width = kMaxU32, U32 height = kMaxU32, const RenderTargetHandle* vrsRt = nullptr,
-						   U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0);
+						   const RenderTargetHandle* vrsRt = nullptr, U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0);
 
 	void setRenderpassInfo(std::initializer_list<GraphicsRenderPassTargetDesc> colorRts, const GraphicsRenderPassTargetDesc* depthStencilRt = nullptr,
-						   U32 minx = 0, U32 miny = 0, U32 width = kMaxU32, U32 height = kMaxU32, const RenderTargetHandle* vrsRt = nullptr,
-						   U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0)
+						   const RenderTargetHandle* vrsRt = nullptr, U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0)
 	{
 		ConstWeakArray<GraphicsRenderPassTargetDesc> colorRtsArr(colorRts.begin(), U32(colorRts.size()));
-		setRenderpassInfo(colorRtsArr, depthStencilRt, minx, miny, width, height, vrsRt, vrsRtTexelSizeX, vrsRtTexelSizeY);
+		setRenderpassInfo(colorRtsArr, depthStencilRt, vrsRt, vrsRtTexelSizeX, vrsRtTexelSizeY);
 	}
 
 private:
 	Array<GraphicsRenderPassTargetDesc, kMaxColorRenderTargets + 2> m_rts;
-	Array<U32, 4> m_rpassRenderArea = {};
 	U8 m_colorRtCount = 0;
 	U8 m_vrsRtTexelSizeX = 0;
 	U8 m_vrsRtTexelSizeY = 0;
-
-	Bool hasRenderpass() const
-	{
-		return m_rpassRenderArea[3] != 0;
-	}
+	Bool m_hasRenderpass = false;
 };
 
 /// A compute render pass for RenderGraph.

+ 3 - 3
AnKi/Gr/RenderGraph.inl.h

@@ -155,8 +155,8 @@ inline void RenderPassBase::newDependency(const RenderPassDependency& dep)
 }
 
 inline void GraphicsRenderPass::setRenderpassInfo(ConstWeakArray<GraphicsRenderPassTargetDesc> colorRts,
-												  const GraphicsRenderPassTargetDesc* depthStencilRt, U32 minx, U32 miny, U32 width, U32 height,
-												  const RenderTargetHandle* vrsRt, U8 vrsRtTexelSizeX, U8 vrsRtTexelSizeY)
+												  const GraphicsRenderPassTargetDesc* depthStencilRt, const RenderTargetHandle* vrsRt,
+												  U8 vrsRtTexelSizeX, U8 vrsRtTexelSizeY)
 {
 	m_colorRtCount = U8(colorRts.getSize());
 	for(U32 i = 0; i < m_colorRtCount; ++i)
@@ -188,7 +188,7 @@ inline void GraphicsRenderPass::setRenderpassInfo(ConstWeakArray<GraphicsRenderP
 		m_vrsRtTexelSizeY = vrsRtTexelSizeY;
 	}
 
-	m_rpassRenderArea = {minx, miny, width, height};
+	m_hasRenderpass = true;
 }
 
 inline RenderGraphBuilder::~RenderGraphBuilder()

+ 6 - 14
AnKi/Gr/Vulkan/VkCommandBuffer.cpp

@@ -341,8 +341,8 @@ void CommandBuffer::bindShaderProgram(ShaderProgram* prog)
 	self.m_microCmdb->pushObjectRef(prog);
 }
 
-void CommandBuffer::beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, U32 minx, U32 miny, U32 width, U32 height,
-									const TextureView& vrsRt, U8 vrsRtTexelSizeX, U8 vrsRtTexelSizeY)
+void CommandBuffer::beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, const TextureView& vrsRt, U8 vrsRtTexelSizeX,
+									U8 vrsRtTexelSizeY)
 {
 	ANKI_VK_SELF(CommandBufferImpl);
 
@@ -466,18 +466,10 @@ void CommandBuffer::beginRenderPass(ConstWeakArray<RenderTarget> colorRts, Rende
 	info.layerCount = 1;
 
 	// Set the render area
-	ANKI_ASSERT(minx < fbWidth && miny < fbHeight);
-
-	const U32 maxx = min<U32>(minx + width, fbWidth);
-	const U32 maxy = min<U32>(miny + height, fbHeight);
-	width = maxx - minx;
-	height = maxy - miny;
-	ANKI_ASSERT(minx + width <= fbWidth && miny + height <= fbHeight);
-
-	info.renderArea.offset.x = minx;
-	info.renderArea.offset.y = miny;
-	info.renderArea.extent.width = width;
-	info.renderArea.extent.height = height;
+	info.renderArea.offset.x = 0;
+	info.renderArea.offset.y = 0;
+	info.renderArea.extent.width = fbWidth;
+	info.renderArea.extent.height = fbHeight;
 
 	// State bookkeeping
 	self.m_graphicsState.beginRenderPass({colorFormats.getBegin(), colorRts.getSize()}, dsFormat, UVec2(fbWidth, fbHeight));

+ 1 - 1
AnKi/Gr/Vulkan/VkGraphicsState.cpp

@@ -40,7 +40,7 @@ static VkRect2D computeScissor(const U32 scissor[], U32 fbWidth, U32 fbHeight)
 	out.extent.width = width;
 	out.extent.height = height;
 	out.offset.x = minx;
-	out.offset.y = fbHeight - (miny + height);
+	out.offset.y = miny;
 
 	return out;
 }

+ 1 - 1
AnKi/Renderer/GBuffer.cpp

@@ -162,7 +162,7 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 		depthRti.m_loadOperation = loadOp;
 		depthRti.m_clearValue.m_depthStencil.m_depth = 1.0f;
 		depthRti.m_subresource.m_depthStencilAspect = DepthStencilAspectBit::kDepth;
-		pass.setRenderpassInfo(WeakArray{colorRti}, &depthRti, 0, 0, kMaxU32, kMaxU32);
+		pass.setRenderpassInfo(WeakArray{colorRti}, &depthRti);
 
 		pass.setWork([&ctx, visOut, this](RenderPassWorkContext& rgraphCtx) {
 			ANKI_TRACE_SCOPED_EVENT(GBuffer);

+ 1 - 1
AnKi/Renderer/LightShading.cpp

@@ -252,7 +252,7 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	GraphicsRenderPassTargetDesc depthRt(getRenderer().getGBuffer().getDepthRt());
 	depthRt.m_loadOperation = RenderTargetLoadOperation::kLoad;
 	depthRt.m_subresource.m_depthStencilAspect = DepthStencilAspectBit::kDepth;
-	pass.setRenderpassInfo({colorRt}, &depthRt, 0, 0, kMaxU32, kMaxU32, (enableVrs) ? &sriRt : nullptr,
+	pass.setRenderpassInfo({colorRt}, &depthRt, (enableVrs) ? &sriRt : nullptr,
 						   (enableVrs) ? getRenderer().getVrsSriGeneration().getSriTexelDimension() : 0,
 						   (enableVrs) ? getRenderer().getVrsSriGeneration().getSriTexelDimension() : 0);
 

+ 15 - 41
AnKi/Renderer/ShadowMapping.cpp

@@ -21,6 +21,8 @@
 namespace anki {
 
 static StatCounter g_tilesAllocatedStatVar(StatCategory::kRenderer, "Shadow tiles (re)allocated", StatFlag::kMainThreadUpdates);
+static StatCounter g_shadowLightsProcessedStatVar(StatCategory::kRenderer, "Lights processed by shadows",
+												  StatFlag::kMainThreadUpdates | StatFlag::kZeroEveryFrame);
 
 class LightHash
 {
@@ -279,8 +281,8 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 	}
 
 	// Process the point lights first
-	U32 lightIdx = 0;
 	WeakArray<LightComponent*> lights = getRenderer().getPrimaryNonRenderableVisibility().getInterestingVisibleComponents().m_shadowLights;
+	g_shadowLightsProcessedStatVar.increment(lights.getSize() + (dirLight != 0));
 	for(LightComponent* lightc : lights)
 	{
 		if(lightc->getLightComponentType() != LightComponentType::kPoint || !lightc->getShadowEnabled())
@@ -333,7 +335,7 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 			// Vis testing
 			const Array<F32, kMaxLodCount - 1> lodDistances = {g_lod0MaxDistanceCVar, g_lod1MaxDistanceCVar};
 			DistanceGpuVisibilityInput visIn;
-			visIn.m_passesName = generateTempPassName("Shadows point light lightIdx:%u", lightIdx);
+			visIn.m_passesName = generateTempPassName("Shadows point light light UUID:%u", lightc->getUuid());
 			visIn.m_technique = RenderingTechnique::kDepth;
 			visIn.m_lodReferencePoint = ctx.m_matrices.m_cameraTransform.getTranslationPart().xyz();
 			visIn.m_lodDistances = lodDistances;
@@ -350,8 +352,8 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 			BufferView clearTileIndirectArgs;
 			if(!renderAllways)
 			{
-				clearTileIndirectArgs =
-					createVetVisibilityPass(generateTempPassName("Shadows: Vet point light lightIdx:%u", lightIdx), *lightc, visOut, rgraph);
+				clearTileIndirectArgs = createVetVisibilityPass(generateTempPassName("Shadows: Vet point light light UUID:%u", lightc->getUuid()),
+																*lightc, visOut, rgraph);
 			}
 
 			// Draw
@@ -371,19 +373,16 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 				subpasses[face].m_viewProjMat = frustum.getViewProjectionMatrix();
 			}
 
-			createDrawShadowsPass(subpasses, visOut, generateTempPassName("Shadows: Point light lightIdx:%u", lightIdx), rgraph);
+			createDrawShadowsPass(subpasses, visOut, generateTempPassName("Shadows: Point light UUID:%u", lightc->getUuid()), rgraph);
 		}
 		else
 		{
 			// Can't be a caster from now on
 			lightc->setShadowAtlasUvViewports({});
 		}
-
-		++lightIdx;
 	}
 
 	// Process the spot lights 2nd
-	lightIdx = 0;
 	for(LightComponent* lightc : lights)
 	{
 		if(lightc->getLightComponentType() != LightComponentType::kSpot || !lightc->getShadowEnabled())
@@ -411,7 +410,7 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 			// Vis testing
 			const Array<F32, kMaxLodCount - 1> lodDistances = {g_lod0MaxDistanceCVar, g_lod1MaxDistanceCVar};
 			FrustumGpuVisibilityInput visIn;
-			visIn.m_passesName = generateTempPassName("Shadows spot light lightIdx:%u", lightIdx);
+			visIn.m_passesName = generateTempPassName("Shadows spot light UUID:%u", lightc->getUuid());
 			visIn.m_technique = RenderingTechnique::kDepth;
 			visIn.m_lodReferencePoint = cameraOrigin;
 			visIn.m_lodDistances = lodDistances;
@@ -429,12 +428,12 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 			if(!renderAllways)
 			{
 				clearTileIndirectArgs =
-					createVetVisibilityPass(generateTempPassName("Shadows: Vet spot light lightIdx:%u", lightIdx), *lightc, visOut, rgraph);
+					createVetVisibilityPass(generateTempPassName("Shadows: Vet spot light UUID:%u", lightc->getUuid()), *lightc, visOut, rgraph);
 			}
 
 			// Add draw pass
 			createDrawShadowsPass(atlasViewport, lightc->getSpotLightViewProjectionMatrix(), lightc->getSpotLightViewMatrix(), visOut,
-								  clearTileIndirectArgs, {}, generateTempPassName("Shadows: Spot light lightIdx:%u", lightIdx), rgraph);
+								  clearTileIndirectArgs, {}, generateTempPassName("Shadows: Spot light UUID:%u", lightc->getUuid()), rgraph);
 		}
 		else
 		{
@@ -491,7 +490,7 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 			// Vis testing
 			const Array<F32, kMaxLodCount - 1> lodDistances = {g_lod0MaxDistanceCVar, g_lod1MaxDistanceCVar};
 			FrustumGpuVisibilityInput visIn;
-			visIn.m_passesName = generateTempPassName("Shadows: Dir light cascade lightIdx:%u cascade:%u", lightIdx, cascade);
+			visIn.m_passesName = generateTempPassName("Shadows: Dir light cascade cascade:%u", cascade);
 			visIn.m_technique = RenderingTechnique::kDepth;
 			visIn.m_viewProjectionMatrix = cascadeViewProjMats[cascade];
 			visIn.m_lodReferencePoint = ctx.m_matrices.m_cameraTransform.getTranslationPart().xyz();
@@ -505,8 +504,7 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 
 			// Draw
 			createDrawShadowsPass(dirLightAtlasViewports[cascade], cascadeViewProjMats[cascade], cascadeViewMats[cascade], visOut, {},
-								  hzbGenIn.m_cascades[cascade].m_hzbRt,
-								  generateTempPassName("Shadows: Dir light lightIdx:%u cascade:%u", lightIdx, cascade), rgraph);
+								  hzbGenIn.m_cascades[cascade].m_hzbRt, generateTempPassName("Shadows: Dir light cascade:%u", cascade), rgraph);
 
 			// Update the texture matrix to point to the correct region in the atlas
 			ctx.m_dirLightTextureMatrices[cascade] = createSpotLightTextureMatrix(dirLightAtlasViewports[cascade]) * cascadeViewProjMats[cascade];
@@ -597,42 +595,19 @@ void ShadowMapping::createDrawShadowsPass(ConstWeakArray<ShadowSubpassInfo> subp
 	newArray<ShadowSubpassInfo>(getRenderer().getFrameMemoryPool(), subpasses_.getSize(), subpasses);
 	memcpy(subpasses.getBegin(), subpasses_.getBegin(), subpasses.getSizeInBytes());
 
-	// Compute the whole viewport
-	UVec4 viewport;
-	if(subpasses.getSize() == 1)
-	{
-		viewport = subpasses[0].m_viewport;
-	}
-	else
-	{
-		viewport = UVec4(kMaxU32, kMaxU32, 0, 0);
-		for(const ShadowSubpassInfo& s : subpasses)
-		{
-			viewport.x() = min(viewport.x(), s.m_viewport.x());
-			viewport.y() = min(viewport.y(), s.m_viewport.y());
-			viewport.z() = max(viewport.z(), s.m_viewport.x() + s.m_viewport.z());
-			viewport.w() = max(viewport.w(), s.m_viewport.y() + s.m_viewport.w());
-		}
-		viewport.z() -= viewport.x();
-		viewport.w() -= viewport.y();
-	}
-
 	// Create the pass
 	GraphicsRenderPass& pass = rgraph.newGraphicsRenderPass(passName);
 
-	const Bool maySkipDrawcalls = subpasses[0].m_clearTileIndirectArgs.isValid();
-	const Bool renderpassClear = subpasses.getSize() == 1 && !maySkipDrawcalls; // Rely on renderpass clear
-
 	GraphicsRenderPassTargetDesc smRti(m_runCtx.m_rt);
-	smRti.m_loadOperation = (renderpassClear) ? RenderTargetLoadOperation::kClear : RenderTargetLoadOperation::kLoad;
+	smRti.m_loadOperation = RenderTargetLoadOperation::kLoad;
 	smRti.m_clearValue.m_depthStencil.m_depth = 1.0f;
 	smRti.m_subresource.m_depthStencilAspect = DepthStencilAspectBit::kDepth;
-	pass.setRenderpassInfo({}, &smRti, viewport[0], viewport[1], viewport[2], viewport[3]);
+	pass.setRenderpassInfo({}, &smRti);
 
 	pass.newBufferDependency(visOut.m_dependency, BufferUsageBit::kIndirectDraw);
 	pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kRtvDsvWrite);
 
-	pass.setWork([this, visOut, subpasses, renderpassClear](RenderPassWorkContext& rgraphCtx) {
+	pass.setWork([this, visOut, subpasses](RenderPassWorkContext& rgraphCtx) {
 		ANKI_TRACE_SCOPED_EVENT(ShadowMapping);
 
 		CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
@@ -644,7 +619,6 @@ void ShadowMapping::createDrawShadowsPass(ConstWeakArray<ShadowSubpassInfo> subp
 			cmdb.setViewport(spass.m_viewport[0], spass.m_viewport[1], spass.m_viewport[2], spass.m_viewport[3]);
 
 			// Clear the tile
-			if(!renderpassClear)
 			{
 				cmdb.bindShaderProgram(m_clearDepthGrProg.get());
 				cmdb.setDepthCompareOperation(CompareOperation::kAlways);

+ 3 - 3
AnKi/Ui/Canvas.cpp

@@ -246,12 +246,12 @@ void Canvas::appendToCommandBufferInternal(CommandBuffer& cmdb)
 			}
 			else
 			{
-				// Project scissor/clipping rectangles into framebuffer space. Flip Y
+				// Project scissor/clipping rectangles into framebuffer space
 				Vec4 clipRect;
 				clipRect.x() = (pcmd.ClipRect.x - clipOff.x()) * clipScale.x();
-				clipRect.y() = (fbHeight - pcmd.ClipRect.w - clipOff.y()) * clipScale.y();
+				clipRect.y() = (pcmd.ClipRect.y - clipOff.y()) * clipScale.y();
 				clipRect.z() = (pcmd.ClipRect.z - clipOff.x()) * clipScale.x();
-				clipRect.w() = (fbHeight - pcmd.ClipRect.y - clipOff.y()) * clipScale.y();
+				clipRect.w() = (pcmd.ClipRect.w - clipOff.y()) * clipScale.y();
 
 				if(clipRect.x() < fbWidth && clipRect.y() < fbHeight && clipRect.z() >= 0.0f && clipRect.w() >= 0.0f)
 				{