From df4fe61d87e410e4e34d213217ffa35b4326aef9 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 13 Feb 2019 11:28:03 +0300 Subject: [PATCH] [vulkan] Small refactoring and bugfixes --- drape/vertex_array_buffer.cpp | 32 +++- drape/vertex_array_buffer.hpp | 7 +- drape/vulkan/vulkan_base_context.cpp | 112 +------------ drape/vulkan/vulkan_base_context.hpp | 5 - drape/vulkan/vulkan_mesh_object_impl.cpp | 16 +- drape/vulkan/vulkan_object_manager.cpp | 158 +++++++++++++++++- drape/vulkan/vulkan_object_manager.hpp | 12 ++ drape/vulkan/vulkan_texture.cpp | 2 - drape/vulkan/vulkan_utils.cpp | 20 --- drape/vulkan/vulkan_utils.hpp | 3 - .../vulkan_vertex_array_buffer_impl.cpp | 52 ++---- 11 files changed, 222 insertions(+), 197 deletions(-) diff --git a/drape/vertex_array_buffer.cpp b/drape/vertex_array_buffer.cpp index d847072e30..4375b404c1 100644 --- a/drape/vertex_array_buffer.cpp +++ b/drape/vertex_array_buffer.cpp @@ -11,6 +11,8 @@ #include "std/target_os.hpp" +#include + namespace dp { namespace @@ -215,7 +217,8 @@ void VertexArrayBuffer::Build(ref_ptr context, ref_ptr context, BindingInfo buffer = GetOrCreateStaticBuffer(bindingInfo); else buffer = GetOrCreateDynamicBuffer(bindingInfo); - m_impl->AddBindingInfo(bindingInfo); + + // For Vulkan rendering we have to know the whole collection of binding info. + if (context->GetApiVersion() == dp::ApiVersion::Vulkan && !m_impl) + CollectBindingInfo(bindingInfo); if (count > 0) m_isChanged = true; @@ -427,4 +433,26 @@ ref_ptr VertexArrayBuffer::GetIndexBuffer() const CHECK(m_indexBuffer != nullptr, ()); return m_indexBuffer->GetBuffer(); } + +void VertexArrayBuffer::CollectBindingInfo(dp::BindingInfo const & bindingInfo) +{ + auto const id = bindingInfo.GetID(); + auto const it = std::find_if(m_bindingInfo.begin(), m_bindingInfo.end(), + [id](dp::BindingInfo const & info) + { + return info.GetID() == id; + }); + if (it != m_bindingInfo.end()) + { + CHECK(*it == bindingInfo, ("Incorrect binding info.")); + return; + } + + m_bindingInfo.push_back(bindingInfo); + std::sort(m_bindingInfo.begin(), m_bindingInfo.end(), + [](dp::BindingInfo const & info1, dp::BindingInfo const & info2) + { + return info1.GetID() < info2.GetID(); + }); +} } // namespace dp diff --git a/drape/vertex_array_buffer.hpp b/drape/vertex_array_buffer.hpp index f3fad3a647..0dff3c7ec1 100644 --- a/drape/vertex_array_buffer.hpp +++ b/drape/vertex_array_buffer.hpp @@ -9,6 +9,7 @@ #include "drape/pointers.hpp" #include +#include namespace dp { @@ -100,12 +101,15 @@ private: void PreflushImpl(ref_ptr context); + void CollectBindingInfo(dp::BindingInfo const & bindingInfo); + // Definition of this method is in a .mm-file. drape_ptr CreateImplForMetal(ref_ptr buffer); // Definition of this method is in a separate .cpp-file. drape_ptr CreateImplForVulkan(ref_ptr context, - ref_ptr buffer); + ref_ptr buffer, + std::vector && bindingInfo); uint32_t const m_dataBufferSize; uint64_t const m_batcherHash; @@ -119,5 +123,6 @@ private: bool m_isPreflushed = false; bool m_moveToGpuOnBuild = false; bool m_isChanged = false; + std::vector m_bindingInfo; }; } // namespace dp diff --git a/drape/vulkan/vulkan_base_context.cpp b/drape/vulkan/vulkan_base_context.cpp index 1e04b8dcad..8d17d60385 100644 --- a/drape/vulkan/vulkan_base_context.cpp +++ b/drape/vulkan/vulkan_base_context.cpp @@ -39,11 +39,6 @@ VulkanBaseContext::~VulkanBaseContext() m_pipeline.reset(); } - for (auto const & s : m_samplers) - vkDestroySampler(m_device, s.second, nullptr); - m_samplers.clear(); - - DestroyDescriptorPools(); DestroyDefaultFramebuffer(); DestroyDepthTexture(); DestroySwapchain(); @@ -158,9 +153,6 @@ void VulkanBaseContext::SetSurface(VkSurfaceKHR surface, VkSurfaceFormatKHR surf } RecreateSwapchain(); CreateDefaultFramebuffer(); - - if (m_descriptorPools.empty()) - CreateDescriptorPool(); } void VulkanBaseContext::ResetSurface() @@ -195,8 +187,6 @@ void VulkanBaseContext::Present() for (auto const & h : m_handlers[static_cast(HandlerType::PrePresent)]) h.second(make_ref(this)); - // TODO: wait for all map-memory operations. - // Prepare frame. Acquire next image. // By setting timeout to UINT64_MAX we will always wait until the next image has been acquired or an actual // error is thrown. With that we don't have to handle VK_NOT_READY @@ -576,32 +566,6 @@ 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_pipelineKey.m_depthStencil.SetDepthTestEnabled(enabled); @@ -670,67 +634,9 @@ VkPipeline VulkanBaseContext::GetCurrentPipeline() DescriptorSetGroup VulkanBaseContext::GetCurrentDescriptorSetGroup() { - CHECK(!m_descriptorPools.empty(), ()); CHECK(m_pipelineKey.m_program != nullptr, ()); CHECK(!m_paramDescriptors.empty(), ("Shaders parameters are not set.")); - - DescriptorSetGroup s; - VkDescriptorSetLayout layout = m_pipelineKey.m_program->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; + return m_objectManager->CreateDescriptorSetGroup(m_pipelineKey.m_program, m_paramDescriptors); } VkPipelineLayout VulkanBaseContext::GetCurrentPipelineLayout() const @@ -752,21 +658,7 @@ uint32_t VulkanBaseContext::GetCurrentDynamicBufferOffset() const VkSampler VulkanBaseContext::GetSampler(SamplerKey const & key) { - auto const it = m_samplers.find(key); - if (it != m_samplers.end()) - return it->second; - - VkSamplerCreateInfo samplerCreateInfo = {}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.magFilter = samplerCreateInfo.minFilter = GetVulkanFilter(key.GetTextureFilter()); - samplerCreateInfo.addressModeU = GetVulkanSamplerAddressMode(key.GetWrapSMode()); - samplerCreateInfo.addressModeV = GetVulkanSamplerAddressMode(key.GetWrapTMode()); - - VkSampler sampler; - CHECK_VK_CALL(vkCreateSampler(m_device, &samplerCreateInfo, nullptr, &sampler)); - - m_samplers.insert(std::make_pair(key, sampler)); - return sampler; + return m_objectManager->GetSampler(key); } } // namespace vulkan } // namespace dp diff --git a/drape/vulkan/vulkan_base_context.hpp b/drape/vulkan/vulkan_base_context.hpp index 2d7563895c..9ebc177c9d 100644 --- a/drape/vulkan/vulkan_base_context.hpp +++ b/drape/vulkan/vulkan_base_context.hpp @@ -122,9 +122,6 @@ protected: void CreateRenderPass(); void DestroyRenderPass(); - void CreateDescriptorPool(); - void DestroyDescriptorPools(); - VkInstance const m_vulkanInstance; VkPhysicalDevice const m_gpu; VkPhysicalDeviceProperties const m_gpuProperties; @@ -144,7 +141,6 @@ protected: // Command buffer submission and execution VkSemaphore m_renderComplete; - std::vector m_descriptorPools; VkFence m_fence; ref_ptr m_objectManager; @@ -169,7 +165,6 @@ protected: VulkanPipeline::PipelineKey m_pipelineKey; std::vector m_paramDescriptors; uint32_t m_stencilReferenceValue = 1; - std::map m_samplers; }; } // namespace vulkan } // namespace dp diff --git a/drape/vulkan/vulkan_mesh_object_impl.cpp b/drape/vulkan/vulkan_mesh_object_impl.cpp index 0b012c757c..6a1c6dbbb4 100644 --- a/drape/vulkan/vulkan_mesh_object_impl.cpp +++ b/drape/vulkan/vulkan_mesh_object_impl.cpp @@ -44,7 +44,6 @@ public: VkDevice device = vulkanContext->GetDevice(); ResetDescriptorSetGroup(); - m_pipeline = {}; m_geometryBuffers.resize(m_mesh->m_buffers.size()); m_bindingInfo.resize(m_mesh->m_buffers.size()); @@ -84,7 +83,6 @@ public: void Reset() override { ResetDescriptorSetGroup(); - m_pipeline = {}; for (auto const & b : m_geometryBuffers) m_objectManager->DestroyObject(b); @@ -159,14 +157,8 @@ public: VkCommandBuffer commandBuffer = vulkanContext->GetCurrentCommandBuffer(); CHECK(commandBuffer != nullptr, ()); - if (!m_pipeline) - { - vulkanContext->SetPrimitiveTopology(GetPrimitiveType(m_mesh->m_drawPrimitive)); - vulkanContext->SetBindingInfo(m_bindingInfo); - m_pipeline = vulkanContext->GetCurrentPipeline(); - if (!m_pipeline) - return; - } + vulkanContext->SetPrimitiveTopology(GetPrimitiveType(m_mesh->m_drawPrimitive)); + vulkanContext->SetBindingInfo(m_bindingInfo); if (!m_descriptorSetGroup) m_descriptorSetGroup = vulkanContext->GetCurrentDescriptorSetGroup(); @@ -176,7 +168,8 @@ public: vulkanContext->GetCurrentPipelineLayout(), 0, 1, &m_descriptorSetGroup.m_descriptorSet, 1, &dynamicOffset); - vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + vulkanContext->GetCurrentPipeline()); VkDeviceSize offsets[1] = {0}; for (uint32_t i = 0; i < static_cast(m_geometryBuffers.size()); ++i) @@ -204,7 +197,6 @@ private: ref_ptr m_objectManager; std::vector m_geometryBuffers; std::vector m_bindingInfo; - VkPipeline m_pipeline = {}; DescriptorSetGroup m_descriptorSetGroup; }; } // namespace vulkan diff --git a/drape/vulkan/vulkan_object_manager.cpp b/drape/vulkan/vulkan_object_manager.cpp index be309269cd..b72683599c 100644 --- a/drape/vulkan/vulkan_object_manager.cpp +++ b/drape/vulkan/vulkan_object_manager.cpp @@ -1,14 +1,39 @@ #include "drape/vulkan/vulkan_object_manager.hpp" #include "drape/vulkan/vulkan_staging_buffer.hpp" +#include "base/macros.hpp" + #include namespace dp { namespace vulkan { +namespace +{ uint32_t constexpr kDefaultStagingBufferSizeInBytes = 10 * 1024 * 1024; +VkSamplerAddressMode GetVulkanSamplerAddressMode(TextureWrapping wrapping) +{ + switch (wrapping) + { + case TextureWrapping::ClampToEdge: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case TextureWrapping::Repeat: return VK_SAMPLER_ADDRESS_MODE_REPEAT; + } + UNREACHABLE(); +} + +VkFilter GetVulkanFilter(TextureFilter filter) +{ + switch (filter) + { + case TextureFilter::Linear: return VK_FILTER_LINEAR; + case TextureFilter::Nearest: return VK_FILTER_NEAREST; + } + UNREACHABLE(); +} +} // namespace + VulkanObjectManager::VulkanObjectManager(VkDevice device, VkPhysicalDeviceLimits const & deviceLimits, VkPhysicalDeviceMemoryProperties const & memoryProperties, uint32_t queueFamilyIndex) @@ -17,14 +42,22 @@ VulkanObjectManager::VulkanObjectManager(VkDevice device, VkPhysicalDeviceLimits , m_memoryManager(device, deviceLimits, memoryProperties) { m_queueToDestroy.reserve(50); + m_descriptorsToDestroy.reserve(50); m_defaultStagingBuffer = make_unique_dp(make_ref(this), kDefaultStagingBufferSizeInBytes); + CreateDescriptorPool(); } VulkanObjectManager::~VulkanObjectManager() { - m_defaultStagingBuffer.reset(); CollectObjects(); + + for (auto const & s : m_samplers) + vkDestroySampler(m_device, s.second, nullptr); + m_samplers.clear(); + + m_defaultStagingBuffer.reset(); + DestroyDescriptorPools(); } VulkanObject VulkanObjectManager::CreateBuffer(VulkanMemoryManager::ResourceType resourceType, @@ -39,14 +72,22 @@ VulkanObject VulkanObjectManager::CreateBuffer(VulkanMemoryManager::ResourceType info.flags = 0; info.size = sizeInBytes; if (resourceType == VulkanMemoryManager::ResourceType::Geometry) + { info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT; + VK_BUFFER_USAGE_TRANSFER_DST_BIT; + } else if (resourceType == VulkanMemoryManager::ResourceType::Uniform) + { info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + } else if (resourceType == VulkanMemoryManager::ResourceType::Staging) + { info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + } else + { CHECK(false, ("Unsupported resource type.")); + } info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.queueFamilyIndexCount = 1; @@ -108,6 +149,72 @@ VulkanObject VulkanObjectManager::CreateImage(VkImageUsageFlags usageFlags, VkFo return result; } +DescriptorSetGroup VulkanObjectManager::CreateDescriptorSetGroup(ref_ptr program, + std::vector const & descriptors) +{ + std::lock_guard lock(m_mutex); + + CHECK(!m_descriptorPools.empty(), ()); + + DescriptorSetGroup s; + VkDescriptorSetLayout layout = program->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(descriptors.size()); + for (size_t i = 0; i < writeDescriptorSets.size(); ++i) + { + auto const & p = descriptors[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; +} + void VulkanObjectManager::DestroyObject(VulkanObject object) { std::lock_guard lock(m_mutex); @@ -206,5 +313,52 @@ void VulkanObjectManager::Unmap(VulkanObject object) vkUnmapMemory(m_device, object.GetMemory()); object.m_allocation->m_memoryBlock->m_isBlocked = false; } + +void VulkanObjectManager::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 = 500; // Approximately equal to doubled maximum VAO per frame. + + VkDescriptorPool descriptorPool; + CHECK_VK_CALL(vkCreateDescriptorPool(m_device, &descriptorPoolInfo, nullptr, &descriptorPool)); + m_descriptorPools.push_back(descriptorPool); +} + +void VulkanObjectManager::DestroyDescriptorPools() +{ + for (auto & pool : m_descriptorPools) + vkDestroyDescriptorPool(m_device, pool, nullptr); +} + +VkSampler VulkanObjectManager::GetSampler(SamplerKey const & key) +{ + std::lock_guard lock(m_mutex); + + auto const it = m_samplers.find(key); + if (it != m_samplers.end()) + return it->second; + + VkSamplerCreateInfo samplerCreateInfo = {}; + samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerCreateInfo.magFilter = samplerCreateInfo.minFilter = GetVulkanFilter(key.GetTextureFilter()); + samplerCreateInfo.addressModeU = GetVulkanSamplerAddressMode(key.GetWrapSMode()); + samplerCreateInfo.addressModeV = GetVulkanSamplerAddressMode(key.GetWrapTMode()); + + VkSampler sampler; + CHECK_VK_CALL(vkCreateSampler(m_device, &samplerCreateInfo, nullptr, &sampler)); + + m_samplers.insert(std::make_pair(key, sampler)); + return sampler; +} } // namespace vulkan } // namespace dp diff --git a/drape/vulkan/vulkan_object_manager.hpp b/drape/vulkan/vulkan_object_manager.hpp index f056c14f8f..e9e41aacc9 100644 --- a/drape/vulkan/vulkan_object_manager.hpp +++ b/drape/vulkan/vulkan_object_manager.hpp @@ -1,6 +1,7 @@ #pragma once #include "drape/pointers.hpp" +#include "drape/vulkan/vulkan_gpu_program.hpp" #include "drape/vulkan/vulkan_memory_manager.hpp" #include "drape/vulkan/vulkan_utils.hpp" @@ -10,6 +11,7 @@ #include #include +#include #include #include #include @@ -59,6 +61,8 @@ public: uint32_t sizeInBytes, uint64_t batcherHash); VulkanObject CreateImage(VkImageUsageFlags usageFlags, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t width, uint32_t height); + DescriptorSetGroup CreateDescriptorSetGroup(ref_ptr program, + std::vector const & descriptors); uint8_t * Map(VulkanObject object); void Flush(VulkanObject object, uint32_t offset = 0, uint32_t size = 0); @@ -74,16 +78,24 @@ public: VkDevice GetDevice() const { return m_device; } VulkanMemoryManager const & GetMemoryManager() const { return m_memoryManager; }; + VkSampler GetSampler(SamplerKey const & key); private: + void CreateDescriptorPool(); + void DestroyDescriptorPools(); + VkDevice const m_device; uint32_t const m_queueFamilyIndex; VulkanMemoryManager m_memoryManager; std::vector m_queueToDestroy; + + std::vector m_descriptorPools; std::vector m_descriptorsToDestroy; drape_ptr m_defaultStagingBuffer; + std::map m_samplers; + std::mutex m_mutex; }; } // namespace vulkan diff --git a/drape/vulkan/vulkan_texture.cpp b/drape/vulkan/vulkan_texture.cpp index 79ac2937d7..78f7845860 100644 --- a/drape/vulkan/vulkan_texture.cpp +++ b/drape/vulkan/vulkan_texture.cpp @@ -151,8 +151,6 @@ void VulkanTexture::Create(ref_ptr context, Params const & m_textureObject = m_objectManager->CreateImage(VK_IMAGE_USAGE_SAMPLED_BIT, format, VK_IMAGE_ASPECT_COLOR_BIT, params.m_width, params.m_height); - //CHECK_VK_CALL(vkBindImageMemory(vulkanContext->GetDevice(), m_textureObject.m_image, - // m_textureObject.GetMemory(), m_textureObject.GetAlignedOffset())); } } diff --git a/drape/vulkan/vulkan_utils.cpp b/drape/vulkan/vulkan_utils.cpp index 63ec23cb37..2e48da845e 100644 --- a/drape/vulkan/vulkan_utils.cpp +++ b/drape/vulkan/vulkan_utils.cpp @@ -87,25 +87,5 @@ bool SamplerKey::operator<(SamplerKey const & rhs) const { return m_sampler < rhs.m_sampler; } - -VkSamplerAddressMode GetVulkanSamplerAddressMode(TextureWrapping wrapping) -{ - switch (wrapping) - { - case TextureWrapping::ClampToEdge: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - case TextureWrapping::Repeat: return VK_SAMPLER_ADDRESS_MODE_REPEAT; - } - UNREACHABLE(); -} - -VkFilter GetVulkanFilter(TextureFilter filter) -{ - switch (filter) - { - case TextureFilter::Linear: return VK_FILTER_LINEAR; - case TextureFilter::Nearest: return VK_FILTER_NEAREST; - } - UNREACHABLE(); -} } // namespace vulkan } // namespace dp diff --git a/drape/vulkan/vulkan_utils.hpp b/drape/vulkan/vulkan_utils.hpp index d27d4f6468..5a142a5969 100644 --- a/drape/vulkan/vulkan_utils.hpp +++ b/drape/vulkan/vulkan_utils.hpp @@ -71,9 +71,6 @@ struct SamplerKey uint32_t m_sampler = 0; }; - -extern VkSamplerAddressMode GetVulkanSamplerAddressMode(TextureWrapping wrapping); -extern VkFilter GetVulkanFilter(TextureFilter filter); } // namespace vulkan } // namespace dp diff --git a/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp b/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp index 8fb75c1463..786e4c2e30 100644 --- a/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp +++ b/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -24,9 +23,11 @@ class VulkanVertexArrayBufferImpl : public VertexArrayBufferImpl { public: VulkanVertexArrayBufferImpl(ref_ptr buffer, - ref_ptr objectManager) + ref_ptr objectManager, + std::vector && bindingInfo) : m_vertexArrayBuffer(std::move(buffer)) , m_objectManager(std::move(objectManager)) + , m_bindingInfo(std::move(bindingInfo)) {} ~VulkanVertexArrayBufferImpl() override @@ -48,28 +49,6 @@ public: void Unbind() override {} void BindBuffers(dp::BuffersMap const & buffers) const override {} - void AddBindingInfo(dp::BindingInfo const & bindingInfo) override - { - auto const id = bindingInfo.GetID(); - auto const it = std::find_if(m_bindingInfo.begin(), m_bindingInfo.end(), - [id](dp::BindingInfo const & info) - { - return info.GetID() == id; - }); - if (it != m_bindingInfo.end()) - { - CHECK(*it == bindingInfo, ("Incorrect binding info.")); - return; - } - - m_bindingInfo.push_back(bindingInfo); - std::sort(m_bindingInfo.begin(), m_bindingInfo.end(), - [](dp::BindingInfo const & info1, dp::BindingInfo const & info2) - { - return info1.GetID() < info2.GetID(); - }); - } - void RenderRange(ref_ptr context, bool drawAsLine, IndicesRange const & range) override { @@ -77,17 +56,9 @@ public: VkCommandBuffer commandBuffer = vulkanContext->GetCurrentCommandBuffer(); CHECK(commandBuffer != nullptr, ()); - if (!m_pipeline || (m_lastDrawAsLine != drawAsLine)) - { - m_lastDrawAsLine = drawAsLine; - - vulkanContext->SetPrimitiveTopology(drawAsLine ? VK_PRIMITIVE_TOPOLOGY_LINE_LIST : - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); - vulkanContext->SetBindingInfo(m_bindingInfo); - m_pipeline = vulkanContext->GetCurrentPipeline(); - if (!m_pipeline) - return; - } + vulkanContext->SetPrimitiveTopology(drawAsLine ? VK_PRIMITIVE_TOPOLOGY_LINE_LIST : + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + vulkanContext->SetBindingInfo(m_bindingInfo); if (!m_descriptorSetGroup) m_descriptorSetGroup = vulkanContext->GetCurrentDescriptorSetGroup(); @@ -97,7 +68,8 @@ public: vulkanContext->GetCurrentPipelineLayout(), 0, 1, &m_descriptorSetGroup.m_descriptorSet, 1, &dynamicOffset); - vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + vulkanContext->GetCurrentPipeline()); VkDeviceSize offsets[1] = {0}; uint32_t bufferIndex = 0; @@ -130,16 +102,16 @@ private: ref_ptr m_vertexArrayBuffer; ref_ptr m_objectManager; std::vector m_bindingInfo; - VkPipeline m_pipeline = {}; - bool m_lastDrawAsLine = false; DescriptorSetGroup m_descriptorSetGroup; }; } // namespace vulkan drape_ptr VertexArrayBuffer::CreateImplForVulkan(ref_ptr context, - ref_ptr buffer) + ref_ptr buffer, + std::vector && bindingInfo) { ref_ptr vulkanContext = context; - return make_unique_dp(buffer, vulkanContext->GetObjectManager()); + return make_unique_dp(buffer, vulkanContext->GetObjectManager(), + std::move(bindingInfo)); } } // namespace dp