Browse Source

[BUGFIX] Fix viewport+scissor setting. Fix Indirect

Panagiotis Christopoulos Charitos 8 years ago
parent
commit
78419d8a1f

+ 2 - 0
src/anki/Config.h.cmake

@@ -155,6 +155,7 @@
 #	define ANKI_DONT_INLINE __attribute__((noinline))
 #	define ANKI_UNUSED __attribute__((__unused__))
 #	define ANKI_COLD __attribute__((cold, optimize("Os")))
+#	define ANKI_HOT __attribute__ ((hot))
 #else
 #	define ANKI_LIKELY(x) ((x) == 1)
 #	define ANKI_UNLIKELY(x) ((x) == 1)
@@ -164,6 +165,7 @@
 #	define ANKI_DONT_INLINE
 #	define ANKI_UNUSED
 #	define ANKI_COLD
+#	define ANKI_HOT
 #endif
 
 // Pack structs

+ 9 - 4
src/anki/gr/RenderGraph.cpp

@@ -404,16 +404,19 @@ FramebufferPtr RenderGraph::getOrCreateFramebuffer(
 	return fb;
 }
 
+template<Bool isTexture>
 Bool RenderGraph::overlappingDependency(const RenderPassDependency& a, const RenderPassDependency& b)
 {
-	if(a.m_isTexture && b.m_isTexture)
+	ANKI_ASSERT(a.m_isTexture == isTexture && b.m_isTexture == isTexture);
+
+	if(isTexture)
 	{
 		return a.m_texture.m_handle == b.m_texture.m_handle
 			&& (a.m_texture.m_surface == b.m_texture.m_surface || a.m_texture.m_wholeTex || b.m_texture.m_wholeTex);
 	}
 	else
 	{
-		return a.m_isTexture == b.m_isTexture && a.m_buffer.m_handle == b.m_buffer.m_handle;
+		return a.m_buffer.m_handle == b.m_buffer.m_handle;
 	}
 }
 
@@ -438,7 +441,7 @@ Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const Rend
 				{
 					for(const RenderPassDependency& producer : b.m_producers)
 					{
-						if(overlappingDependency(producer, consumer))
+						if(overlappingDependency<true>(producer, consumer))
 						{
 							return true;
 						}
@@ -449,6 +452,7 @@ Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const Rend
 	}
 
 	// Buffers
+	if(a.m_hasBufferDeps)
 	{
 		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> aReadBWrite = a.m_consumerBufferMask & b.m_producerBufferMask;
 		BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> aWriteBRead = a.m_producerBufferMask & b.m_consumerBufferMask;
@@ -466,7 +470,7 @@ Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const Rend
 				{
 					for(const RenderPassDependency& producer : b.m_producers)
 					{
-						if(overlappingDependency(producer, consumer))
+						if(overlappingDependency<false>(producer, consumer))
 						{
 							return true;
 						}
@@ -639,6 +643,7 @@ void RenderGraph::initRenderPassesAndSetDeps(const RenderGraphDescription& descr
 			ANKI_ASSERT(inPass.m_secondLevelCmdbsCount == 0 && "Can't have second level cmdbs");
 		}
 
+		// Set dependencies
 		U j = passIdx;
 		while(j--)
 		{

+ 9 - 3
src/anki/gr/RenderGraph.h

@@ -26,7 +26,7 @@ class RenderGraph;
 /// @name RenderGraph constants
 /// @{
 static constexpr U MAX_RENDER_GRAPH_PASSES = 128;
-static constexpr U MAX_RENDER_GRAPH_RENDER_TARGETS = 128; ///< Max imported or not render targets in RenderGraph.
+static constexpr U MAX_RENDER_GRAPH_RENDER_TARGETS = 64; ///< Max imported or not render targets in RenderGraph.
 static constexpr U MAX_RENDER_GRAPH_BUFFERS = 64;
 /// @}
 
@@ -277,6 +277,7 @@ public:
 		else if(dep.m_buffer.m_usage != BufferUsageBit::NONE)
 		{
 			m_consumerBufferMask.set(dep.m_buffer.m_handle.m_idx);
+			m_hasBufferDeps = true;
 		}
 	}
 
@@ -291,6 +292,7 @@ public:
 		else
 		{
 			m_producerBufferMask.set(dep.m_buffer.m_handle.m_idx);
+			m_hasBufferDeps = true;
 		}
 	}
 
@@ -316,6 +318,7 @@ protected:
 	BitSet<MAX_RENDER_GRAPH_RENDER_TARGETS, U64> m_producerRtMask = {false};
 	BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> m_consumerBufferMask = {false};
 	BitSet<MAX_RENDER_GRAPH_BUFFERS, U64> m_producerBufferMask = {false};
+	Bool8 m_hasBufferDeps = false; ///< Opt.
 
 	String m_name;
 
@@ -676,8 +679,11 @@ private:
 	FramebufferPtr getOrCreateFramebuffer(
 		const FramebufferInitInfo& fbInit, const RenderTargetHandle* rtHandles, U64 hash);
 
-	static Bool passADependsOnB(const RenderPassDescriptionBase& a, const RenderPassDescriptionBase& b);
-	static Bool overlappingDependency(const RenderPassDependency& a, const RenderPassDependency& b);
+	static ANKI_HOT Bool passADependsOnB(const RenderPassDescriptionBase& a, const RenderPassDescriptionBase& b);
+
+	template<Bool isTexture>
+	static ANKI_HOT Bool overlappingDependency(const RenderPassDependency& a, const RenderPassDependency& b);
+
 	static Bool passHasUnmetDependencies(const BakeContext& ctx, U32 passIdx);
 
 	void getCrntUsageAndAspect(

+ 4 - 0
src/anki/gr/vulkan/CommandBufferImpl.cpp

@@ -137,6 +137,10 @@ void CommandBufferImpl::beginRenderPass(FramebufferPtr fb,
 	m_microCmdb->pushObjectRef(fb);
 
 	m_subpassContents = VK_SUBPASS_CONTENTS_MAX_ENUM;
+
+	// Re-set the viewport and scissor because sometimes they are set clamped
+	m_viewportDirty = true;
+	m_scissorDirty = true;
 }
 
 void CommandBufferImpl::beginRenderPassInternal()

+ 40 - 0
src/anki/gr/vulkan/CommandBufferImpl.h

@@ -374,7 +374,9 @@ private:
 	Array<U32, 4> m_viewport = {{0, 0, 0, 0}};
 	Array<U32, 4> m_scissor = {{0, 0, MAX_U32, MAX_U32}};
 	Bool8 m_viewportDirty = true;
+	VkViewport m_lastViewport = {};
 	Bool8 m_scissorDirty = true;
+	VkRect2D m_lastScissor = {{-1, -1}, {MAX_U32, MAX_U32}};
 	Array<U32, 2> m_stencilCompareMasks = {{0x5A5A5A5A, 0x5A5A5A5A}}; ///< Use a stupid number to initialize.
 	Array<U32, 2> m_stencilWriteMasks = {{0x5A5A5A5A, 0x5A5A5A5A}};
 	Array<U32, 2> m_stencilReferenceMasks = {{0x5A5A5A5A, 0x5A5A5A5A}};
@@ -468,6 +470,44 @@ private:
 	void beginRecording();
 
 	Bool flipViewport() const;
+
+	static VkViewport computeViewport(U32* viewport, U32 fbWidth, U32 fbHeight, Bool flipvp)
+	{
+		const U32 minx = viewport[0];
+		const U32 miny = viewport[1];
+		const U32 width = min<U32>(fbWidth, viewport[2]);
+		const U32 height = min<U32>(fbHeight, viewport[3]);
+		ANKI_ASSERT(width > 0 && height > 0);
+		ANKI_ASSERT(minx + width <= fbWidth);
+		ANKI_ASSERT(miny + height <= fbHeight);
+
+		VkViewport s = {};
+		s.x = minx;
+		s.y = (flipvp) ? (fbHeight - miny) : miny; // Move to the bottom;
+		s.width = width;
+		s.height = (flipvp) ? -F32(height) : height;
+		s.minDepth = 0.0f;
+		s.maxDepth = 1.0f;
+		return s;
+	}
+
+	static VkRect2D computeScissor(U32* scissor, U32 fbWidth, U32 fbHeight, Bool flipvp)
+	{
+		const U32 minx = scissor[0];
+		const U32 miny = scissor[1];
+		const U32 width = min<U32>(fbWidth, scissor[2]);
+		const U32 height = min<U32>(fbHeight, scissor[3]);
+		ANKI_ASSERT(minx + width <= fbWidth);
+		ANKI_ASSERT(miny + height <= fbHeight);
+
+		VkRect2D out = {};
+		out.extent.width = width;
+		out.extent.height = height;
+		out.offset.x = minx;
+		out.offset.y = (flipvp) ? (fbHeight - (miny + height)) : miny;
+
+		return out;
+	}
 };
 /// @}
 

+ 15 - 29
src/anki/gr/vulkan/CommandBufferImpl.inl.h

@@ -520,22 +520,14 @@ inline void CommandBufferImpl::drawcallCommon()
 		U32 fbWidth, fbHeight;
 		m_activeFb->m_impl->getAttachmentsSize(fbWidth, fbHeight);
 
-		const U32 minx = m_viewport[0];
-		const U32 miny = m_viewport[1];
-		const U32 width = min<U32>(fbWidth, m_viewport[2]);
-		const U32 height = min<U32>(fbHeight, m_viewport[3]);
-		ANKI_ASSERT(width > 0 && height > 0);
-		ANKI_ASSERT(minx + width <= fbWidth);
-		ANKI_ASSERT(miny + height <= fbHeight);
-
-		VkViewport s;
-		s.x = minx;
-		s.y = (flipvp) ? (fbHeight - miny) : miny; // Move to the bottom;
-		s.width = width;
-		s.height = (flipvp) ? -F32(height) : height;
-		s.minDepth = 0.0f;
-		s.maxDepth = 1.0f;
-		ANKI_CMD(vkCmdSetViewport(m_handle, 0, 1, &s), ANY_OTHER_COMMAND);
+		VkViewport vp = computeViewport(&m_viewport[0], fbWidth, fbHeight, flipvp);
+
+		// Additional optimization
+		if(memcmp(&vp, &m_lastViewport, sizeof(vp)) != 0)
+		{
+			ANKI_CMD(vkCmdSetViewport(m_handle, 0, 1, &vp), ANY_OTHER_COMMAND);
+			m_lastViewport = vp;
+		}
 
 		m_viewportDirty = false;
 	}
@@ -543,26 +535,20 @@ inline void CommandBufferImpl::drawcallCommon()
 	// Flush scissor
 	if(ANKI_UNLIKELY(m_scissorDirty))
 	{
-		VkRect2D scissor = {};
-
 		const Bool flipvp = flipViewport();
 
 		U32 fbWidth, fbHeight;
 		m_activeFb->m_impl->getAttachmentsSize(fbWidth, fbHeight);
 
-		const U32 minx = m_scissor[0];
-		const U32 miny = m_scissor[1];
-		const U32 width = min<U32>(fbWidth, m_scissor[2]);
-		const U32 height = min<U32>(fbHeight, m_scissor[3]);
-		ANKI_ASSERT(minx + width <= fbWidth);
-		ANKI_ASSERT(miny + height <= fbHeight);
+		VkRect2D scissor = computeScissor(&m_scissor[0], fbWidth, fbHeight, flipvp);
 
-		scissor.extent.width = width;
-		scissor.extent.height = height;
-		scissor.offset.x = minx;
-		scissor.offset.y = (flipvp) ? (fbHeight - (miny + height)) : miny;
+		// Additional optimization
+		if(memcmp(&scissor, &m_lastScissor, sizeof(scissor)) != 0)
+		{
+			ANKI_CMD(vkCmdSetScissor(m_handle, 0, 1, &scissor), ANY_OTHER_COMMAND);
+			m_lastScissor = scissor;
+		}
 
-		ANKI_CMD(vkCmdSetScissor(m_handle, 0, 1, &scissor), ANY_OTHER_COMMAND);
 		m_scissorDirty = false;
 	}
 

+ 4 - 0
src/anki/gr/vulkan/TextureImpl.cpp

@@ -131,6 +131,10 @@ Error TextureImpl::init(const TextureInitInfo& init_, Texture* tex)
 		getGrManagerImpl().flushCommandBuffer(cmdb, nullptr);
 	}
 
+#if 0
+	printf("image %s handle %p\n", (init.getName()) ? init.getName().cstr() : "-", m_imageHandle);
+#endif
+
 	return Error::NONE;
 }
 

+ 8 - 3
src/anki/renderer/Indirect.cpp

@@ -643,8 +643,12 @@ void Indirect::populateRenderGraph(RenderingContext& rctx)
 				pass.newConsumer({m_ctx.m_gbufferColorRts[i], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 				pass.newProducer({m_ctx.m_gbufferColorRts[i], TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 			}
-			pass.newConsumer({m_ctx.m_gbufferDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
-			pass.newProducer({m_ctx.m_gbufferDepthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
+			pass.newConsumer({m_ctx.m_gbufferDepthRt,
+				TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
+				DepthStencilAspectBit::DEPTH});
+			pass.newProducer({m_ctx.m_gbufferDepthRt,
+				TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
+				DepthStencilAspectBit::DEPTH});
 		}
 
 		// Light shading passes
@@ -683,7 +687,8 @@ void Indirect::populateRenderGraph(RenderingContext& rctx)
 				{
 					pass.newConsumer({m_ctx.m_gbufferColorRts[i], TextureUsageBit::SAMPLED_FRAGMENT});
 				}
-				pass.newConsumer({m_ctx.m_gbufferDepthRt, TextureUsageBit::SAMPLED_FRAGMENT});
+				pass.newConsumer(
+					{m_ctx.m_gbufferDepthRt, TextureUsageBit::SAMPLED_FRAGMENT, DepthStencilAspectBit::DEPTH});
 			}
 		}
 

+ 5 - 2
src/anki/renderer/Ssao.cpp

@@ -88,12 +88,15 @@ Error Ssao::init(const ConfigSet& config)
 	for(U i = 0; i < 2; ++i)
 	{
 		// RT
-		m_rtTextures[i] = m_r->createAndClearRenderTarget(m_r->create2DRenderTargetInitInfo(m_width,
+		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(m_width,
 			m_height,
 			Ssao::RT_PIXEL_FORMAT,
 			TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE | TextureUsageBit::CLEAR,
 			SamplingFilter::LINEAR,
-			"ssaomain"));
+			"ssaomain");
+		texinit.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
+
+		m_rtTextures[i] = m_r->createAndClearRenderTarget(texinit);
 	}
 
 	// FB descr

+ 6 - 1
src/anki/util/BitSet.h

@@ -112,7 +112,12 @@ public:
 
 	Bool operator==(const BitSet& b) const
 	{
-		return memcmp(&m_chunks[0], &b.m_chunks[0], sizeof(m_chunks)) == 0;
+		Bool same = m_chunks[0] == b.m_chunks[0];
+		for(U i = 1; i < CHUNK_COUNT; ++i)
+		{
+			same = same && (m_chunks[i] == b.m_chunks[i]);
+		}
+		return same;
 	}
 
 	Bool operator!=(const BitSet& b) const