From 03328bb7b87504d8ba408e506977a2afde53f374 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Tue, 12 Feb 2019 15:33:13 +0300 Subject: [PATCH] [vulkan] Added descriptor set --- drape/vulkan/vulkan_base_context.cpp | 105 ++++++++++++++++++++++++++- drape/vulkan/vulkan_base_context.hpp | 13 +++- drape/vulkan/vulkan_utils.hpp | 6 ++ 3 files changed, 116 insertions(+), 8 deletions(-) diff --git a/drape/vulkan/vulkan_base_context.cpp b/drape/vulkan/vulkan_base_context.cpp index 8fdabe610e..215faac3f5 100644 --- a/drape/vulkan/vulkan_base_context.cpp +++ b/drape/vulkan/vulkan_base_context.cpp @@ -39,7 +39,8 @@ VulkanBaseContext::~VulkanBaseContext() m_pipeline->Destroy(m_device); m_pipeline.reset(); } - + + DestroyDescriptorPools(); DestroyDefaultFramebuffer(); DestroyDepthTexture(); DestroySwapchain(); @@ -152,6 +153,9 @@ void VulkanBaseContext::SetSurface(VkSurfaceKHR surface, VkSurfaceFormatKHR surf } RecreateSwapchain(); CreateDefaultFramebuffer(); + + if (m_descriptorPools.empty()) + CreateDescriptorPool(); } void VulkanBaseContext::ResetSurface() @@ -563,6 +567,32 @@ void VulkanBaseContext::DestroyRenderPass() vkDestroyRenderPass(m_device, m_renderPass, nullptr); } +void VulkanBaseContext::CreateDescriptorPool() +{ + std::vector poolSizes = + { + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1}, // Maximum uniform buffers count per draw call. + {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3}, // Maximum textures count per draw call. + }; + + VkDescriptorPoolCreateInfo descriptorPoolInfo = {}; + descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptorPoolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + descriptorPoolInfo.poolSizeCount = static_cast(poolSizes.size()); + descriptorPoolInfo.pPoolSizes = poolSizes.data(); + descriptorPoolInfo.maxSets = 250; // Approximately equal to draw calls count. + + VkDescriptorPool descriptorPool; + CHECK_VK_CALL(vkCreateDescriptorPool(m_device, &descriptorPoolInfo, nullptr, &descriptorPool)); + m_descriptorPools.push_back(descriptorPool); +} + +void VulkanBaseContext::DestroyDescriptorPools() +{ + for (auto & pool : m_descriptorPools) + vkDestroyDescriptorPool(m_device, pool, nullptr); +} + void VulkanBaseContext::SetDepthTestEnabled(bool enabled) { m_depthEnabled = enabled; @@ -610,7 +640,7 @@ void VulkanBaseContext::SetBindingInfo(std::vector const & bind void VulkanBaseContext::SetProgram(ref_ptr program) { - //TODO + m_currentProgram = program; } void VulkanBaseContext::SetBlendingEnabled(bool blendingEnabled) @@ -620,17 +650,84 @@ void VulkanBaseContext::SetBlendingEnabled(bool blendingEnabled) void VulkanBaseContext::ApplyParamDescriptor(ParamDescriptor && descriptor) { - //TODO + m_paramDescriptors.push_back(std::move(descriptor)); } void VulkanBaseContext::ClearParamDescriptors() { - //TODO + m_paramDescriptors.clear(); } VkPipeline VulkanBaseContext::GetCurrentPipeline() { + //TODO return {}; } + +DescriptorSet VulkanBaseContext::GetCurrentDescriptorSet() +{ + CHECK(!m_descriptorPools.empty(), ()); + CHECK(m_currentProgram != nullptr, ()); + CHECK(!m_paramDescriptors.empty(), ()); + + DescriptorSet s; + VkDescriptorSetLayout layout = m_currentProgram->GetDescriptorSetLayout(); + VkDescriptorSetAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocInfo.descriptorPool = s.m_descriptorPool = m_descriptorPools.front(); + allocInfo.pSetLayouts = &layout; + allocInfo.descriptorSetCount = 1; + + auto result = vkAllocateDescriptorSets(m_device, &allocInfo, &s.m_descriptorSet); + if (result != VK_SUCCESS) + { + for (size_t i = 1; i < m_descriptorPools.size(); ++i) + { + allocInfo.descriptorPool = s.m_descriptorPool = m_descriptorPools[i]; + result = vkAllocateDescriptorSets(m_device, &allocInfo, &s.m_descriptorSet); + if (result == VK_SUCCESS) + break; + } + + if (s.m_descriptorSet == VK_NULL_HANDLE) + { + CreateDescriptorPool(); + allocInfo.descriptorPool = s.m_descriptorPool = m_descriptorPools.back(); + CHECK_VK_CALL(vkAllocateDescriptorSets(m_device, &allocInfo, &s.m_descriptorSet)); + } + } + + std::vector writeDescriptorSets(m_paramDescriptors.size()); + for (size_t i = 0; i < writeDescriptorSets.size(); ++i) + { + auto const & p = m_paramDescriptors[i]; + + writeDescriptorSets[i] = {}; + writeDescriptorSets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSets[i].dstSet = s.m_descriptorSet; + writeDescriptorSets[i].descriptorCount = 1; + if (p.m_type == ParamDescriptor::Type::DynamicUniformBuffer) + { + writeDescriptorSets[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + writeDescriptorSets[i].dstBinding = 0; + writeDescriptorSets[i].pBufferInfo = &p.m_bufferDescriptor; + } + else if (p.m_type == ParamDescriptor::Type::Texture) + { + writeDescriptorSets[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writeDescriptorSets[i].dstBinding = static_cast(p.m_textureSlot); + writeDescriptorSets[i].pImageInfo = &p.m_imageDescriptor; + } + else + { + CHECK(false, ("Unsupported param descriptor type.")); + } + } + + vkUpdateDescriptorSets(m_device, static_cast(writeDescriptorSets.size()), + writeDescriptorSets.data(), 0, nullptr); + + return s; +} } // namespace vulkan } // namespace dp diff --git a/drape/vulkan/vulkan_base_context.hpp b/drape/vulkan/vulkan_base_context.hpp index edab1f7ef1..b080ed4094 100644 --- a/drape/vulkan/vulkan_base_context.hpp +++ b/drape/vulkan/vulkan_base_context.hpp @@ -77,7 +77,6 @@ public: void ResetSurface(); VkPhysicalDevice const GetPhysicalDevice() const { return m_gpu; } - VkDevice GetDevice() const { return m_device; } VkPhysicalDeviceProperties const & GetGpuProperties() const { return m_gpuProperties; } @@ -86,8 +85,8 @@ public: ref_ptr GetObjectManager() const { return m_objectManager; } VkCommandBuffer GetCurrentCommandBuffer() const { return m_commandBuffer; } - VkPipeline GetCurrentPipeline(); + DescriptorSet GetCurrentDescriptorSet(); enum class HandlerType : uint8_t { @@ -118,6 +117,9 @@ protected: void CreateRenderPass(); void DestroyRenderPass(); + void CreateDescriptorPool(); + void DestroyDescriptorPools(); + VkInstance const m_vulkanInstance; VkPhysicalDevice const m_gpu; VkPhysicalDeviceProperties const m_gpuProperties; @@ -137,7 +139,7 @@ protected: // Command buffer submission and execution VkSemaphore m_renderComplete; - VkDescriptorPool m_descriptorPool = VK_NULL_HANDLE; + std::vector m_descriptorPools; VkFence m_fence; ref_ptr m_objectManager; @@ -147,7 +149,7 @@ protected: VkSurfaceCapabilitiesKHR m_surfaceCapabilities; boost::optional m_surfaceFormat; - VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; + VkSwapchainKHR m_swapchain = {}; std::vector m_swapchainImageViews; uint32_t m_imageIndex = 0; @@ -169,6 +171,9 @@ protected: StencilAction m_depthFailAction = {}; StencilAction m_passAction = {}; uint32_t m_stencilReferenceValue = 1; + + ref_ptr m_currentProgram; + std::vector m_paramDescriptors; }; } // namespace vulkan } // namespace dp diff --git a/drape/vulkan/vulkan_utils.hpp b/drape/vulkan/vulkan_utils.hpp index f98b80176e..b80be21119 100644 --- a/drape/vulkan/vulkan_utils.hpp +++ b/drape/vulkan/vulkan_utils.hpp @@ -30,6 +30,12 @@ struct ParamDescriptor VkDescriptorImageInfo m_imageDescriptor = {}; int8_t m_textureSlot = 0; }; + +struct DescriptorSet +{ + VkDescriptorSet m_descriptorSet = {}; + VkDescriptorPool m_descriptorPool = {}; +}; } // namespace vulkan } // namespace dp