Browse Source

Vulkan: Pipeline layout and descriptor layout

Panagiotis Christopoulos Charitos 9 năm trước cách đây
mục cha
commit
e24fac927a

+ 3 - 0
include/anki/gr/vulkan/Common.h

@@ -11,6 +11,9 @@
 namespace anki
 {
 
+// Forward
+class GrManagerImpl;
+
 /// @addtogroup vulkan
 /// @{
 

+ 7 - 0
include/anki/gr/vulkan/GrManagerImpl.h

@@ -20,6 +20,8 @@ public:
 	VkInstance m_instance = VK_NULL_HANDLE;
 	VkDevice m_device = VK_NULL_HANDLE;
 	VkQueue m_queue = VK_NULL_HANDLE;
+	VkDescriptorSetLayout m_globalDescriptorSetLayout = VK_NULL_HANDLE;
+	VkPipelineLayout m_globalPipelineLayout = VK_NULL_HANDLE;
 
 	GrManagerImpl(GrManager* manager)
 		: m_manager(manager)
@@ -29,6 +31,8 @@ public:
 
 	~GrManagerImpl();
 
+	ANKI_USE_RESULT Error init();
+
 	/// Get or create a compatible render pass for a pipeline.
 	VkRenderPass getOrCreateCompatibleRenderPass(const PipelineInitInfo& init);
 
@@ -39,6 +43,9 @@ private:
 	/// Map for compatible render passes.
 	class CompatibleRenderPassHashMap;
 	CompatibleRenderPassHashMap* m_renderPasses = nullptr;
+
+	void initGlobalDsetLayout();
+	void initGlobalPplineLayout();
 };
 /// @}
 

+ 2 - 0
include/anki/gr/vulkan/VulkanObject.h

@@ -31,6 +31,8 @@ public:
 
 	GrAllocator<U8> getAllocator() const;
 
+	GrManagerImpl& getGrManagerImpl();
+
 protected:
 	GrManager* m_manager = nullptr;
 };

+ 90 - 0
src/gr/vulkan/GrManagerImpl.cpp

@@ -68,6 +68,96 @@ public:
 // GrManagerImpl                                                               =
 //==============================================================================
 
+//==============================================================================
+Error GrManagerImpl::init()
+{
+	initGlobalDsetLayout();
+	initGlobalPplineLayout();
+
+	return ErrorCode::NONE;
+}
+
+//==============================================================================
+void GrManagerImpl::initGlobalDsetLayout()
+{
+	VkDescriptorSetLayoutCreateInfo ci;
+	ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+	ci.pNext = nullptr;
+	ci.flags = 0;
+
+	const U BINDING_COUNT = MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS 
+		+ MAX_STORAGE_BUFFER_BINDINGS;
+	ci.bindingCount = BINDING_COUNT;
+
+	Array<VkDescriptorSetLayoutBinding, BINDING_COUNT> bindings;
+	ci.pBindings = &bindings[0];
+
+	U count = 0;
+
+	// Combined image samplers
+	for(U i = 0; i < MAX_TEXTURE_BINDINGS; ++i)
+	{
+		VkDescriptorSetLayoutBinding& binding = bindings[count];
+		binding.binding = count;
+		binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+		binding.descriptorCount = 1;
+		binding.stageFlags = VK_SHADER_STAGE_ALL;
+		binding.pImmutableSamplers = nullptr;
+
+		++count;
+	}
+
+	// Uniform buffers
+	for(U i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
+	{
+		VkDescriptorSetLayoutBinding& binding = bindings[count];
+		binding.binding = count;
+		binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
+		binding.descriptorCount = 1;
+		binding.stageFlags = VK_SHADER_STAGE_ALL;
+		binding.pImmutableSamplers = nullptr;
+
+		++count;
+	}
+
+	// Storage buffers
+	for(U i = 0; i < MAX_STORAGE_BUFFER_BINDINGS; ++i)
+	{
+		VkDescriptorSetLayoutBinding& binding = bindings[count];
+		binding.binding = count;
+		binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
+		binding.descriptorCount = 1;
+		binding.stageFlags = VK_SHADER_STAGE_ALL;
+		binding.pImmutableSamplers = nullptr;
+
+		++count;
+	}
+
+	ANKI_ASSERT(count == BINDING_COUNT);
+
+	ANKI_VK_CHECK(vkCreateDescriptorSetLayout(
+		m_device, &ci, nullptr, &m_globalDescriptorSetLayout));
+}
+
+//==============================================================================
+void GrManagerImpl::initGlobalPplineLayout()
+{
+	Array<VkDescriptorSetLayout, MAX_RESOURCE_GROUPS> sets = {{
+		m_globalDescriptorSetLayout, m_globalDescriptorSetLayout}};
+
+	VkPipelineLayoutCreateInfo ci;
+	ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+	ci.pNext = nullptr;
+	ci.flags = 0;
+	ci.setLayoutCount = MAX_RESOURCE_GROUPS;
+	ci.pSetLayouts = &sets[0];
+	ci.pushConstantRangeCount = 0;
+	ci.pPushConstantRanges = nullptr;
+
+	ANKI_VK_CHECK(vkCreatePipelineLayout(
+		m_device, &ci, nullptr, &m_globalPipelineLayout));
+}
+
 //==============================================================================
 VkRenderPass GrManagerImpl::getOrCreateCompatibleRenderPass(
 	const PipelineInitInfo& init)

+ 3 - 2
src/gr/vulkan/PipelineImpl.cpp

@@ -6,6 +6,7 @@
 #include <anki/gr/vulkan/PipelineImpl.h>
 #include <anki/gr/Pipeline.h>
 #include <anki/gr/vulkan/ShaderImpl.h>
+#include <anki/gr/vulkan/GrManagerImpl.h>
 
 namespace anki
 {
@@ -83,8 +84,8 @@ Error PipelineImpl::initGraphics(const PipelineInitInfo& init)
 
 	ci.pVertexInputState = initVertexStage(init.m_vertex, ci.m_vertex);
 
-	ci.layout = 0; // XXX
-	ci.renderPass = 0; // XXX
+	ci.layout = getGrManagerImpl().m_globalPipelineLayout;
+	ci.renderPass = getGrManagerImpl().getOrCreateCompatibleRenderPass(init);
 	ci.basePipelineHandle = VK_NULL_HANDLE;
 
 	return ErrorCode::NONE;

+ 6 - 0
src/gr/vulkan/VulkanObject.cpp

@@ -16,4 +16,10 @@ VkDevice VulkanObject::getDevice() const
 	return m_manager->getImplementation().m_device;
 }
 
+//==============================================================================
+GrManagerImpl& VulkanObject::getGrManagerImpl()
+{
+	return m_manager->getImplementation();
+}
+
 } // end namespace anki