Browse Source

Vulkan: Some framebuffer bits

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
03ed5d2b50

+ 2 - 1
CMakeLists.txt

@@ -33,7 +33,8 @@ else()
 	message(FATAL_ERROR "Unknown system")
 	message(FATAL_ERROR "Unknown system")
 endif()
 endif()
 
 
-if(${CMAKE_C_COMPILER_ID} MATCHES "GNU")
+message(${CMAKE_C_COMPILER_ID})
+if(${CMAKE_C_COMPILER_ID} MATCHES "GNU" OR ${CMAKE_C_COMPILER_ID} MATCHES "Clang")
 	set(GCC TRUE)
 	set(GCC TRUE)
 else()
 else()
 	set(GCC FALSE)
 	set(GCC FALSE)

+ 2 - 1
src/anki/gr/vulkan/DescriptorSet.cpp

@@ -44,10 +44,11 @@ void DescriptorSetFactory::newDescriptorSetLayout(const DescriptorSetLayoutInitI
 			[](const DescriptorBinding& a, const DescriptorBinding& b) { return a.m_binding < b.m_binding; });
 			[](const DescriptorBinding& a, const DescriptorBinding& b) { return a.m_binding < b.m_binding; });
 
 
 		hash = computeHash(&bindings[0], init.m_bindings.getSizeInBytes());
 		hash = computeHash(&bindings[0], init.m_bindings.getSizeInBytes());
+		ANKI_ASSERT(hash != 1);
 	}
 	}
 	else
 	else
 	{
 	{
-		hash = 0;
+		hash = 1;
 	}
 	}
 
 
 	// Find or create the cache entry
 	// Find or create the cache entry

+ 1 - 0
src/anki/gr/vulkan/DescriptorSet.h

@@ -134,6 +134,7 @@ public:
 		ANKI_ASSERT(!"TODO");
 		ANKI_ASSERT(!"TODO");
 	}
 	}
 
 
+	/// @note It's thread-safe.
 	void newDescriptorSetLayout(const DescriptorSetLayoutInitInfo& init, DescriptorSetLayout& layout);
 	void newDescriptorSetLayout(const DescriptorSetLayoutInitInfo& init, DescriptorSetLayout& layout);
 
 
 	void newDescriptorSet(const DescriptorSetState& init, DescriptorSet& set);
 	void newDescriptorSet(const DescriptorSetState& init, DescriptorSet& set);

+ 6 - 0
src/anki/gr/vulkan/FramebufferImpl.cpp

@@ -55,6 +55,8 @@ Error FramebufferImpl::initFbs(const FramebufferInitInfo& init)
 
 
 			ANKI_VK_CHECK(vkCreateFramebuffer(getDevice(), &ci, nullptr, &m_fbs[i]));
 			ANKI_VK_CHECK(vkCreateFramebuffer(getDevice(), &ci, nullptr, &m_fbs[i]));
 		}
 		}
+
+		m_colorAttachmentMask.set(0);
 	}
 	}
 	else
 	else
 	{
 	{
@@ -75,6 +77,7 @@ Error FramebufferImpl::initFbs(const FramebufferInitInfo& init)
 			}
 			}
 
 
 			m_refs[i] = att.m_texture;
 			m_refs[i] = att.m_texture;
+			m_colorAttachmentMask.set(i);
 		}
 		}
 
 
 		if(hasDepthStencil)
 		if(hasDepthStencil)
@@ -92,6 +95,9 @@ Error FramebufferImpl::initFbs(const FramebufferInitInfo& init)
 				aspect = att.m_aspect;
 				aspect = att.m_aspect;
 			}
 			}
 
 
+			m_depthAttachment = !!(aspect & DepthStencilAspectBit::DEPTH);
+			m_stencilAttachment = !!(aspect & DepthStencilAspectBit::STENCIL);
+
 			attachments[count++] = tex.getOrCreateSingleSurfaceView(att.m_surface, aspect);
 			attachments[count++] = tex.getOrCreateSingleSurfaceView(att.m_surface, aspect);
 
 
 			if(m_width == 0)
 			if(m_width == 0)

+ 12 - 0
src/anki/gr/vulkan/FramebufferImpl.h

@@ -7,6 +7,7 @@
 
 
 #include <anki/gr/vulkan/VulkanObject.h>
 #include <anki/gr/vulkan/VulkanObject.h>
 #include <anki/util/HashMap.h>
 #include <anki/util/HashMap.h>
+#include <anki/util/BitSet.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -46,6 +47,13 @@ public:
 		return m_fbs[frame];
 		return m_fbs[frame];
 	}
 	}
 
 
+	void getAttachmentInfo(BitSet<MAX_COLOR_ATTACHMENTS, U8>& colorAttachments, Bool& depth, Bool& stencil) const
+	{
+		colorAttachments = m_colorAttachmentMask;
+		depth = m_depthAttachment;
+		stencil = m_stencilAttachment;
+	}
+
 private:
 private:
 	class Hasher
 	class Hasher
 	{
 	{
@@ -61,6 +69,10 @@ private:
 
 
 	Bool8 m_defaultFb = false;
 	Bool8 m_defaultFb = false;
 
 
+	BitSet<MAX_COLOR_ATTACHMENTS, U8> m_colorAttachmentMask = {false};
+	Bool8 m_depthAttachment = false;
+	Bool8 m_stencilAttachment = false;
+
 	Array<TexturePtr, MAX_COLOR_ATTACHMENTS + 1> m_refs; ///< @note The pos of every attachment is fixed.
 	Array<TexturePtr, MAX_COLOR_ATTACHMENTS + 1> m_refs; ///< @note The pos of every attachment is fixed.
 	Array<U32, MAX_COLOR_ATTACHMENTS + 1> m_attachedMipLevels = {};
 	Array<U32, MAX_COLOR_ATTACHMENTS + 1> m_attachedMipLevels = {};
 
 

+ 1 - 0
src/anki/gr/vulkan/GrManagerImpl.cpp

@@ -86,6 +86,7 @@ GrManagerImpl::~GrManagerImpl()
 	}
 	}
 
 
 	m_descrFactory.destroy();
 	m_descrFactory.destroy();
+	m_pplineLayoutFactory.destroy();
 }
 }
 
 
 GrAllocator<U8> GrManagerImpl::getAllocator() const
 GrAllocator<U8> GrManagerImpl::getAllocator() const

+ 8 - 0
src/anki/gr/vulkan/GrManagerImpl.h

@@ -13,6 +13,7 @@
 #include <anki/gr/vulkan/DescriptorObject.h>
 #include <anki/gr/vulkan/DescriptorObject.h>
 #include <anki/gr/vulkan/DescriptorSet.h>
 #include <anki/gr/vulkan/DescriptorSet.h>
 #include <anki/gr/vulkan/CommandBufferExtra.h>
 #include <anki/gr/vulkan/CommandBufferExtra.h>
+#include <anki/gr/vulkan/PipelineLayout.h>
 #include <anki/util/HashMap.h>
 #include <anki/util/HashMap.h>
 
 
 namespace anki
 namespace anki
@@ -181,6 +182,11 @@ public:
 		return m_pplineCache;
 		return m_pplineCache;
 	}
 	}
 
 
+	PipelineLayoutFactory& getPipelineLayoutFactory()
+	{
+		return m_pplineLayoutFactory;
+	}
+
 private:
 private:
 	GrManager* m_manager = nullptr;
 	GrManager* m_manager = nullptr;
 
 
@@ -271,6 +277,8 @@ private:
 	GrSemaphoreFactory m_semaphores;
 	GrSemaphoreFactory m_semaphores;
 	/// @}
 	/// @}
 
 
+	PipelineLayoutFactory m_pplineLayoutFactory;
+
 	DescriptorObjectTombstoneGenerator m_descrGen;
 	DescriptorObjectTombstoneGenerator m_descrGen;
 	DescriptorSetFactory m_descrFactory;
 	DescriptorSetFactory m_descrFactory;
 
 

+ 3 - 0
src/anki/gr/vulkan/Pipeline.cpp

@@ -386,6 +386,9 @@ void PipelineFactory::newPipeline(PipelineStateTracker& state, Pipeline& ppline)
 {
 {
 	U64 hash;
 	U64 hash;
 	state.flush(hash);
 	state.flush(hash);
+
+	LockGuard<Mutex> lock(m_pplinesMtx);
+
 	auto it = m_pplines.find(hash);
 	auto it = m_pplines.find(hash);
 	if(it != m_pplines.getEnd())
 	if(it != m_pplines.getEnd())
 	{
 	{

+ 19 - 2
src/anki/gr/vulkan/Pipeline.h

@@ -8,6 +8,8 @@
 #include <anki/gr/vulkan/DescriptorSet.h>
 #include <anki/gr/vulkan/DescriptorSet.h>
 #include <anki/gr/ShaderProgram.h>
 #include <anki/gr/ShaderProgram.h>
 #include <anki/gr/vulkan/ShaderProgramImpl.h>
 #include <anki/gr/vulkan/ShaderProgramImpl.h>
+#include <anki/gr/Framebuffer.h>
+#include <anki/gr/vulkan/FramebufferImpl.h>
 #include <anki/util/HashMap.h>
 #include <anki/util/HashMap.h>
 
 
 namespace anki
 namespace anki
@@ -335,7 +337,21 @@ public:
 		}
 		}
 	}
 	}
 
 
-	void beginRenderPass(FramebufferPtr fb);
+	void beginRenderPass(const FramebufferPtr& fb)
+	{
+		ANKI_ASSERT(m_rpass == VK_NULL_HANDLE);
+		Bool d, s;
+		fb->m_impl->getAttachmentInfo(m_fbColorAttachmentMask, d, s);
+		m_fbDepth = d;
+		m_fbStencil = s;
+		m_rpass = fb->m_impl->getCompatibleRenderPass();
+	}
+
+	void endRenderPass()
+	{
+		ANKI_ASSERT(m_rpass);
+		m_rpass = VK_NULL_HANDLE;
+	}
 
 
 	void setPrimitiveTopology(PrimitiveTopology topology)
 	void setPrimitiveTopology(PrimitiveTopology topology)
 	{
 	{
@@ -465,7 +481,7 @@ public:
 
 
 	void destroy();
 	void destroy();
 
 
-	/// @note Not thread-safe.
+	/// @note Thread-safe.
 	void newPipeline(PipelineStateTracker& state, Pipeline& ppline);
 	void newPipeline(PipelineStateTracker& state, Pipeline& ppline);
 
 
 private:
 private:
@@ -477,6 +493,7 @@ private:
 	VkPipelineCache m_pplineCache = VK_NULL_HANDLE;
 	VkPipelineCache m_pplineCache = VK_NULL_HANDLE;
 
 
 	HashMap<U64, PipelineInternal, Hasher> m_pplines;
 	HashMap<U64, PipelineInternal, Hasher> m_pplines;
+	Mutex m_pplinesMtx;
 };
 };
 /// @}
 /// @}
 
 

+ 5 - 2
src/anki/gr/vulkan/PipelineLayout.cpp

@@ -36,7 +36,8 @@ void PipelineLayoutFactory::destroy()
 	m_layouts.destroy(m_alloc);
 	m_layouts.destroy(m_alloc);
 }
 }
 
 
-void PipelineLayoutFactory::newPipelineLayout(const WeakArray<DescriptorSetLayout>& dsetLayouts, PipelineLayout& layout)
+Error PipelineLayoutFactory::newPipelineLayout(
+	const WeakArray<DescriptorSetLayout>& dsetLayouts, PipelineLayout& layout)
 {
 {
 	U64 hash = 1;
 	U64 hash = 1;
 	Array<VkDescriptorSetLayout, MAX_DESCRIPTOR_SETS> vkDsetLayouts;
 	Array<VkDescriptorSetLayout, MAX_DESCRIPTOR_SETS> vkDsetLayouts;
@@ -72,10 +73,12 @@ void PipelineLayoutFactory::newPipelineLayout(const WeakArray<DescriptorSetLayou
 		ci.pSetLayouts = &vkDsetLayouts[0];
 		ci.pSetLayouts = &vkDsetLayouts[0];
 		ci.setLayoutCount = dsetLayoutCount;
 		ci.setLayoutCount = dsetLayoutCount;
 
 
-		ANKI_VK_CHECKF(vkCreatePipelineLayout(m_dev, &ci, nullptr, &lay->m_handle));
+		ANKI_VK_CHECK(vkCreatePipelineLayout(m_dev, &ci, nullptr, &lay->m_handle));
 
 
 		layout.m_handle = lay->m_handle;
 		layout.m_handle = lay->m_handle;
 	}
 	}
+
+	return ErrorCode::NONE;
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 2 - 1
src/anki/gr/vulkan/PipelineLayout.h

@@ -44,7 +44,8 @@ public:
 
 
 	void destroy();
 	void destroy();
 
 
-	void newPipelineLayout(const WeakArray<DescriptorSetLayout>& dsetLayouts, PipelineLayout& layout);
+	/// @note It's thread-safe.
+	ANKI_USE_RESULT Error newPipelineLayout(const WeakArray<DescriptorSetLayout>& dsetLayouts, PipelineLayout& layout);
 
 
 private:
 private:
 	class Layout;
 	class Layout;

+ 26 - 8
src/anki/gr/vulkan/ShaderProgramImpl.cpp

@@ -32,8 +32,10 @@ Error ShaderProgramImpl::init(const Array<ShaderPtr, U(ShaderType::COUNT)>& shad
 	m_shaders = shaders;
 	m_shaders = shaders;
 
 
 	// Merge bindings
 	// Merge bindings
+	//
 	Array2d<DescriptorBinding, MAX_BINDINGS_PER_DESCRIPTOR_SET, MAX_DESCRIPTOR_SETS> bindings;
 	Array2d<DescriptorBinding, MAX_BINDINGS_PER_DESCRIPTOR_SET, MAX_DESCRIPTOR_SETS> bindings;
 	Array<U, MAX_DESCRIPTOR_SETS> counts = {};
 	Array<U, MAX_DESCRIPTOR_SETS> counts = {};
+	U descriptorSetCount = 0;
 	for(U set = 0; set < MAX_DESCRIPTOR_SETS; ++set)
 	for(U set = 0; set < MAX_DESCRIPTOR_SETS; ++set)
 	{
 	{
 		for(ShaderType stype = ShaderType::FIRST; stype < ShaderType::COUNT; ++stype)
 		for(ShaderType stype = ShaderType::FIRST; stype < ShaderType::COUNT; ++stype)
@@ -73,31 +75,46 @@ Error ShaderProgramImpl::init(const Array<ShaderPtr, U(ShaderType::COUNT)>& shad
 				}
 				}
 			}
 			}
 		}
 		}
+
+		if(counts[set])
+		{
+			descriptorSetCount = set + 1;
+		}
 	}
 	}
 
 
 	// Create the descriptor set layouts
 	// Create the descriptor set layouts
-	for(U set = 0; set < MAX_DESCRIPTOR_SETS; ++set)
+	//
+	for(U set = 0; set < descriptorSetCount; ++set)
 	{
 	{
-		if(counts[set] > 0)
-		{
-			DescriptorSetLayoutInitInfo inf;
-			inf.m_bindings = WeakArray<DescriptorBinding>(&bindings[set][0], counts[set]);
+		DescriptorSetLayoutInitInfo inf;
+		inf.m_bindings = WeakArray<DescriptorBinding>((counts[set]) ? &bindings[set][0] : nullptr, counts[set]);
 
 
-			getGrManagerImpl().getDescriptorSetFactory().newDescriptorSetLayout(inf, m_descriptorSetLayouts[set]);
-		}
+		getGrManagerImpl().getDescriptorSetFactory().newDescriptorSetLayout(inf, m_descriptorSetLayouts[set]);
 	}
 	}
 
 
-	ANKI_ASSERT(!"TODO Pipeline layout");
+	// Create the ppline layout
+	//
+	WeakArray<DescriptorSetLayout> dsetLayouts(
+		(descriptorSetCount) ? &m_descriptorSetLayouts[0] : nullptr, descriptorSetCount);
+	ANKI_CHECK(getGrManagerImpl().getPipelineLayoutFactory().newPipelineLayout(dsetLayouts, m_pplineLayout));
 
 
 	// Get some masks
 	// Get some masks
+	//
 	const Bool graphicsProg = !!(shaderMask & ShaderTypeBit::VERTEX);
 	const Bool graphicsProg = !!(shaderMask & ShaderTypeBit::VERTEX);
 	if(graphicsProg)
 	if(graphicsProg)
 	{
 	{
 		m_attributeMask = shaders[ShaderType::VERTEX]->m_impl->m_attributeMask;
 		m_attributeMask = shaders[ShaderType::VERTEX]->m_impl->m_attributeMask;
 		m_colorAttachmentWritemask = shaders[ShaderType::FRAGMENT]->m_impl->m_colorAttachmentWritemask;
 		m_colorAttachmentWritemask = shaders[ShaderType::FRAGMENT]->m_impl->m_colorAttachmentWritemask;
+
+		const U attachmentCount = m_colorAttachmentWritemask.getEnabledBitCount();
+		for(U i = 0; i < attachmentCount; ++i)
+		{
+			ANKI_ASSERT(m_colorAttachmentWritemask.get(i) && "Should write to all attachments");
+		}
 	}
 	}
 
 
 	// Cache some values
 	// Cache some values
+	//
 	if(graphicsProg)
 	if(graphicsProg)
 	{
 	{
 		for(ShaderType stype = ShaderType::VERTEX; stype <= ShaderType::FRAGMENT; ++stype)
 		for(ShaderType stype = ShaderType::VERTEX; stype <= ShaderType::FRAGMENT; ++stype)
@@ -117,6 +134,7 @@ Error ShaderProgramImpl::init(const Array<ShaderPtr, U(ShaderType::COUNT)>& shad
 	}
 	}
 
 
 	// Create the factory
 	// Create the factory
+	//
 	if(graphicsProg)
 	if(graphicsProg)
 	{
 	{
 		m_pplineFactory = getAllocator().newInstance<PipelineFactory>();
 		m_pplineFactory = getAllocator().newInstance<PipelineFactory>();

+ 1 - 2
src/anki/renderer/Renderer.cpp

@@ -165,10 +165,9 @@ Error Renderer::initInternal(const ConfigSet& config)
 
 
 Error Renderer::render(RenderingContext& ctx)
 Error Renderer::render(RenderingContext& ctx)
 {
 {
-	FrustumComponent& frc = *ctx.m_frustumComponent;
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 
 
-	ANKI_ASSERT(frc.getFrustum().getType() == FrustumType::PERSPECTIVE);
+	ANKI_ASSERT(ctx.m_frustumComponent->getFrustum().getType() == FrustumType::PERSPECTIVE);
 
 
 	// Check if resources got loaded
 	// Check if resources got loaded
 	if(m_prevLoadRequestCount != m_resources->getLoadingRequestCount()
 	if(m_prevLoadRequestCount != m_resources->getLoadingRequestCount()