From 68c2eab4fc8a8c1ce0de94b02b75c394b5310940 Mon Sep 17 00:00:00 2001 From: Roman Kuznetsov Date: Sun, 27 Jan 2019 22:19:55 +0300 Subject: [PATCH] [vulkan] Added uniform buffers --- drape/vulkan/vulkan_base_context.cpp | 32 +++++ drape/vulkan/vulkan_base_context.hpp | 21 +++- drape/vulkan/vulkan_gpu_buffer_impl.cpp | 15 ++- drape/vulkan/vulkan_memory_manager.cpp | 2 +- drape/vulkan/vulkan_object_manager.cpp | 29 ++--- drape/vulkan/vulkan_object_manager.hpp | 1 - drape_frontend/frontend_renderer.cpp | 5 +- shaders/program_manager.cpp | 24 +++- shaders/program_manager.hpp | 2 + shaders/vulkan_program_params.cpp | 154 +++++++++++++++++++++--- shaders/vulkan_program_params.hpp | 43 +++++++ shaders/vulkan_program_pool.cpp | 26 ++-- shaders/vulkan_program_pool.hpp | 8 +- 13 files changed, 296 insertions(+), 66 deletions(-) diff --git a/drape/vulkan/vulkan_base_context.cpp b/drape/vulkan/vulkan_base_context.cpp index d3925628a1..ab0d64e580 100644 --- a/drape/vulkan/vulkan_base_context.cpp +++ b/drape/vulkan/vulkan_base_context.cpp @@ -4,6 +4,8 @@ #include "base/assert.hpp" +#include +#include #include namespace dp @@ -67,12 +69,42 @@ void VulkanBaseContext::Present() // It guarantees the graphics data coherence. m_objectManager->FlushDefaultStagingBuffer(); + for (auto const & h : m_handlers[static_cast(HandlerType::PrePresent)]) + h.second(make_ref(this)); + + // TODO: wait for all map-memory operations. + // TODO: submit queue, wait for finishing of rendering. + for (auto const & h : m_handlers[static_cast(HandlerType::PostPresent)]) + h.second(make_ref(this)); + // Resetting of the default staging buffer and collecting destroyed objects must be // only after the finishing of rendering. It prevents data collisions. m_objectManager->ResetDefaultStagingBuffer(); m_objectManager->CollectObjects(); } + +uint32_t VulkanBaseContext::RegisterHandler(HandlerType handlerType, ContextHandler && handler) +{ + static uint32_t counter = 0; + CHECK_LESS(counter, std::numeric_limits::max(), ()); + ASSERT(handler != nullptr, ()); + uint32_t const id = ++counter; + m_handlers[static_cast(handlerType)].emplace_back(std::make_pair(id, std::move(handler))); + return id; +} + +void VulkanBaseContext::UnregisterHandler(uint32_t id) +{ + for (size_t i = 0; i < m_handlers.size(); ++i) + { + m_handlers[i].erase(std::remove_if(m_handlers[i].begin(), m_handlers[i].end(), + [id](std::pair const & p) + { + return p.first == id; + }), m_handlers[i].end()); + } +} } // namespace vulkan } // namespace dp diff --git a/drape/vulkan/vulkan_base_context.hpp b/drape/vulkan/vulkan_base_context.hpp index fc40c5493c..2a84daeb53 100644 --- a/drape/vulkan/vulkan_base_context.hpp +++ b/drape/vulkan/vulkan_base_context.hpp @@ -12,7 +12,10 @@ #include +#include #include +#include +#include namespace dp { @@ -26,6 +29,8 @@ public: VkDevice device, uint32_t renderingQueueFamilyIndex, ref_ptr objectManager); + using ContextHandler = std::function)>; + void Present() override; void MakeCurrent() override {} void DoneCurrent() override {} @@ -69,18 +74,30 @@ public: VkCommandBuffer GetCurrentCommandBuffer() const { CHECK(false, ("Implement me")); return nullptr; } + enum class HandlerType : uint8_t + { + PrePresent = 0, + PostPresent, + + Count + }; + uint32_t RegisterHandler(HandlerType handlerType, ContextHandler && handler); + void UnregisterHandler(uint32_t id); + protected: VkInstance const m_vulkanInstance; VkPhysicalDevice const m_gpu; VkPhysicalDeviceProperties const m_gpuProperties; VkDevice const m_device; uint32_t const m_renderingQueueFamilyIndex; + ref_ptr m_objectManager; - std::shared_ptr m_deviceHolder; - boost::optional m_surface; + std::array>, + static_cast(HandlerType::Count)> m_handlers; + uint32_t m_stencilReferenceValue = 1; }; } // namespace vulkan diff --git a/drape/vulkan/vulkan_gpu_buffer_impl.cpp b/drape/vulkan/vulkan_gpu_buffer_impl.cpp index a3caef156b..7114c79dd1 100644 --- a/drape/vulkan/vulkan_gpu_buffer_impl.cpp +++ b/drape/vulkan/vulkan_gpu_buffer_impl.cpp @@ -97,12 +97,15 @@ void VulkanGPUBuffer::Unmap(ref_ptr context) CHECK(m_temporaryStagingBuffer.m_buffer != 0, ()); stagingBuffer = m_temporaryStagingBuffer.m_buffer; - VkMappedMemoryRange mappedRange = {}; - mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedRange.memory = m_temporaryStagingBuffer.m_allocation->m_memory; - mappedRange.offset = m_temporaryStagingBuffer.m_allocation->m_alignedOffset; - mappedRange.size = m_temporaryStagingBuffer.m_allocation->m_alignedSize; - CHECK_VK_CALL(vkFlushMappedMemoryRanges(device, 1, &mappedRange)); + if (!m_temporaryStagingBuffer.m_allocation->m_isCoherent) + { + VkMappedMemoryRange mappedRange = {}; + mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + mappedRange.memory = m_temporaryStagingBuffer.m_allocation->m_memory; + mappedRange.offset = m_temporaryStagingBuffer.m_allocation->m_alignedOffset; + mappedRange.size = m_temporaryStagingBuffer.m_allocation->m_alignedSize; + CHECK_VK_CALL(vkFlushMappedMemoryRanges(device, 1, &mappedRange)); + } vkUnmapMemory(device, m_temporaryStagingBuffer.m_allocation->m_memory); CHECK_VK_CALL(vkBindBufferMemory(device, m_temporaryStagingBuffer.m_buffer, m_temporaryStagingBuffer.m_allocation->m_memory, diff --git a/drape/vulkan/vulkan_memory_manager.cpp b/drape/vulkan/vulkan_memory_manager.cpp index 6aceb99f1d..df60cd11fc 100644 --- a/drape/vulkan/vulkan_memory_manager.cpp +++ b/drape/vulkan/vulkan_memory_manager.cpp @@ -17,7 +17,7 @@ namespace std::array const kMinBlockSizeInBytes = { 64 * 1024, // Geometry - 4 * 1024, // Uniform + 32 * 1024, // Uniform 0, // Staging 0, // Image }; diff --git a/drape/vulkan/vulkan_object_manager.cpp b/drape/vulkan/vulkan_object_manager.cpp index 52c8da6fbf..dc4788c015 100644 --- a/drape/vulkan/vulkan_object_manager.cpp +++ b/drape/vulkan/vulkan_object_manager.cpp @@ -1,6 +1,8 @@ #include "drape/vulkan/vulkan_object_manager.hpp" #include "drape/vulkan/vulkan_utils.hpp" +#include + namespace dp { namespace vulkan @@ -30,9 +32,6 @@ VulkanObjectManager::VulkanObjectManager(VkDevice device, VkPhysicalDeviceLimits m_defaultStagingBuffer.m_allocation->m_alignedOffset, m_defaultStagingBuffer.m_allocation->m_alignedSize, 0, reinterpret_cast(&m_defaultStagingBufferPtr))); - - if (!m_defaultStagingBuffer.m_allocation->m_isCoherent) - m_regionsToFlush.reserve(10); } VulkanObjectManager::~VulkanObjectManager() @@ -135,20 +134,11 @@ VulkanObjectManager::StagingPointer VulkanObjectManager::GetDefaultStagingBuffer auto const alignedOffset = m_defaultStagingBufferOffset; uint8_t * ptr = m_defaultStagingBufferPtr + alignedOffset; - if (!m_defaultStagingBuffer.m_allocation->m_isCoherent) - { - VkMappedMemoryRange mappedRange = {}; - mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedRange.memory = m_defaultStagingBuffer.m_allocation->m_memory; - mappedRange.offset = alignedOffset; - mappedRange.size = alignedSize; - m_regionsToFlush.push_back(std::move(mappedRange)); - } - // Update offset and align it. m_defaultStagingBufferOffset += alignedSize; auto const alignment = m_memoryManager.GetOffsetAlignment(VulkanMemoryManager::ResourceType::Staging); - m_defaultStagingBufferOffset = m_memoryManager.GetAligned(m_defaultStagingBufferOffset, alignment); + m_defaultStagingBufferOffset = std::min(m_memoryManager.GetAligned(m_defaultStagingBufferOffset, alignment), + m_defaultStagingBuffer.m_allocation->m_alignedSize); StagingPointer stagingDataPtr; stagingDataPtr.m_stagingData.m_stagingBuffer = m_defaultStagingBuffer.m_buffer; @@ -201,12 +191,15 @@ VulkanObjectManager::StagingData VulkanObjectManager::CopyWithTemporaryStagingBu void VulkanObjectManager::FlushDefaultStagingBuffer() { std::lock_guard lock(m_mutex); - if (m_defaultStagingBuffer.m_allocation->m_isCoherent) + if (m_defaultStagingBuffer.m_allocation->m_isCoherent || m_defaultStagingBufferOffset == 0) return; - CHECK_VK_CALL(vkFlushMappedMemoryRanges(m_device, static_cast(m_regionsToFlush.size()), - m_regionsToFlush.data())); - m_regionsToFlush.clear(); + VkMappedMemoryRange mappedRange = {}; + mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + mappedRange.memory = m_defaultStagingBuffer.m_allocation->m_memory; + mappedRange.offset = m_defaultStagingBuffer.m_allocation->m_alignedOffset; + mappedRange.size = mappedRange.offset + m_defaultStagingBufferOffset; + CHECK_VK_CALL(vkFlushMappedMemoryRanges(m_device, 1, &mappedRange)); } void VulkanObjectManager::ResetDefaultStagingBuffer() diff --git a/drape/vulkan/vulkan_object_manager.hpp b/drape/vulkan/vulkan_object_manager.hpp index 4907bf52e6..6ee1a6f112 100644 --- a/drape/vulkan/vulkan_object_manager.hpp +++ b/drape/vulkan/vulkan_object_manager.hpp @@ -69,7 +69,6 @@ private: uint8_t * m_defaultStagingBufferPtr = nullptr; uint32_t m_defaultStagingBufferAlignment = 0; uint32_t m_defaultStagingBufferOffset = 0; - std::vector m_regionsToFlush; std::mutex m_mutex; }; diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 3c36d6eeee..4d78afe808 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -2125,11 +2125,13 @@ void FrontendRenderer::OnContextDestroy() m_transitBackground.reset(); m_debugRectRenderer.reset(); + + CHECK(m_context != nullptr, ()); + m_gpuProgramManager->Destroy(m_context); m_gpuProgramManager.reset(); // Here we have to erase weak pointer to the context, since it // can be destroyed after this method. - CHECK(m_context != nullptr, ()); m_context->DoneCurrent(); m_context = nullptr; @@ -2279,7 +2281,6 @@ void FrontendRenderer::ReleaseResources() m_transitSchemeRenderer.reset(); m_postprocessRenderer.reset(); m_transitBackground.reset(); - m_gpuProgramManager.reset(); // Here m_context can be nullptr, so call the method diff --git a/shaders/program_manager.cpp b/shaders/program_manager.cpp index 6b4057f5c1..181fec9dab 100644 --- a/shaders/program_manager.cpp +++ b/shaders/program_manager.cpp @@ -38,11 +38,18 @@ void ProgramManager::Init(ref_ptr context) CHECK(false, ("Unsupported API version.")); } } + +void ProgramManager::Destroy(ref_ptr context) +{ + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::Vulkan) + DestroyForVulkan(context); +} void ProgramManager::InitForOpenGL(ref_ptr context) { std::string globalDefines; - + // This feature is not supported on some Android devices (especially on Android 4.x version). // Since we can't predict on which devices it'll work fine, we have to turn off for all devices. #if !defined(OMIM_OS_ANDROID) @@ -69,10 +76,17 @@ void ProgramManager::InitForOpenGL(ref_ptr context) void ProgramManager::InitForVulkan(ref_ptr context) { - ASSERT(dynamic_cast(context.get()) != nullptr, ()); - ref_ptr vulkanContext = context; - m_pool = make_unique_dp(vulkanContext->GetDeviceHolder()); - m_paramsSetter = make_unique_dp(); + m_pool = make_unique_dp(context); + m_paramsSetter = make_unique_dp(context); +} + +void ProgramManager::DestroyForVulkan(ref_ptr context) +{ + ASSERT(dynamic_cast(m_paramsSetter.get()) != nullptr, ()); + static_cast(m_paramsSetter.get())->Destroy(context); + + ASSERT(dynamic_cast(m_pool.get()) != nullptr, ()); + static_cast(m_pool.get())->Destroy(context); } ref_ptr ProgramManager::GetProgram(Program program) diff --git a/shaders/program_manager.hpp b/shaders/program_manager.hpp index 7f0ee37554..7ff99fbf84 100644 --- a/shaders/program_manager.hpp +++ b/shaders/program_manager.hpp @@ -21,6 +21,7 @@ public: ProgramManager() = default; void Init(ref_ptr context); + void Destroy(ref_ptr context); ref_ptr GetProgram(Program program); ref_ptr GetParamsSetter() const; @@ -28,6 +29,7 @@ public: private: void InitForOpenGL(ref_ptr context); void InitForVulkan(ref_ptr context); + void DestroyForVulkan(ref_ptr context); #if defined(OMIM_METAL_AVAILABLE) // Definition of this method is in a .mm-file. diff --git a/shaders/vulkan_program_params.cpp b/shaders/vulkan_program_params.cpp index 44bfcb5a67..89e927237f 100644 --- a/shaders/vulkan_program_params.cpp +++ b/shaders/vulkan_program_params.cpp @@ -2,6 +2,7 @@ #include "drape/vulkan/vulkan_base_context.hpp" #include "drape/vulkan/vulkan_gpu_program.hpp" +#include "drape/vulkan/vulkan_utils.hpp" namespace gpu { @@ -9,85 +10,204 @@ namespace vulkan { namespace { -template -void ApplyBytes(ref_ptr context, ref_ptr program, - T const & params) +uint32_t constexpr kUniformBufferSizeInBytes = 32 * 1024; + +VulkanProgramParamsSetter::UniformBuffer CreateUniformBuffer(VkDevice device, + ref_ptr objectManager, + uint32_t & offsetAlignment, uint32_t & sizeAlignment) { - ref_ptr vulkanContext = context; - ref_ptr p = program; - //TODO(@rokuz, @darina): Implement. - CHECK(false, ()); + using namespace dp::vulkan; + auto constexpr kUniformBuffer = VulkanMemoryManager::ResourceType::Uniform; + + VulkanProgramParamsSetter::UniformBuffer result; + result.m_object = objectManager->CreateBuffer(kUniformBuffer, kUniformBufferSizeInBytes, 0 /* batcherHash */); + VkMemoryRequirements memReqs = {}; + vkGetBufferMemoryRequirements(device, result.m_object.m_buffer, &memReqs); + sizeAlignment = objectManager->GetMemoryManager().GetSizeAlignment(memReqs); + offsetAlignment = objectManager->GetMemoryManager().GetOffsetAlignment(kUniformBuffer); + + CHECK_VK_CALL(vkBindBufferMemory(device, result.m_object.m_buffer, + result.m_object.m_allocation->m_memory, + result.m_object.m_allocation->m_alignedOffset)); + + CHECK_VK_CALL(vkMapMemory(device, result.m_object.m_allocation->m_memory, + result.m_object.m_allocation->m_alignedOffset, + result.m_object.m_allocation->m_alignedSize, 0, + reinterpret_cast(&result.m_pointer))); + return result; } } // namespace + +VulkanProgramParamsSetter::VulkanProgramParamsSetter(ref_ptr context) +{ + using namespace dp::vulkan; + m_objectManager = context->GetObjectManager(); + m_uniformBuffers.emplace_back(CreateUniformBuffer(context->GetDevice(), m_objectManager, + m_sizeAlignment, m_offsetAlignment)); + + m_flushHandlerId = context->RegisterHandler(VulkanBaseContext::HandlerType::PrePresent, + [this](ref_ptr c) + { + Flush(c); + }); + m_finishHandlerId = context->RegisterHandler(VulkanBaseContext::HandlerType::PostPresent, + [this](ref_ptr) + { + Finish(); + }); +} + +VulkanProgramParamsSetter::~VulkanProgramParamsSetter() +{ + ASSERT_EQUAL(m_uniformBuffers.size(), 0, ()); +} + +void VulkanProgramParamsSetter::Destroy(ref_ptr context) +{ + VkDevice device = context->GetDevice(); + for (auto & b : m_uniformBuffers) + { + vkUnmapMemory(device, b.m_object.m_allocation->m_memory); + m_objectManager->DestroyObject(b.m_object); + } + m_uniformBuffers.clear(); + context->UnregisterHandler(m_finishHandlerId); + context->UnregisterHandler(m_flushHandlerId); +} + +void VulkanProgramParamsSetter::Flush(ref_ptr context) +{ + VkDevice device = context->GetDevice(); + for (auto & ub : m_uniformBuffers) + { + if (ub.m_object.m_allocation->m_isCoherent || ub.m_freeOffset == 0) + continue; + + VkMappedMemoryRange mappedRange = {}; + mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + mappedRange.memory = ub.m_object.m_allocation->m_memory; + mappedRange.offset = ub.m_object.m_allocation->m_alignedOffset; + mappedRange.size = mappedRange.offset + ub.m_freeOffset; + CHECK_VK_CALL(vkFlushMappedMemoryRanges(device, 1, &mappedRange)); + } +} + +void VulkanProgramParamsSetter::Finish() +{ + for (auto & b : m_uniformBuffers) + b.m_freeOffset = 0; +} + +void VulkanProgramParamsSetter::ApplyBytes(ref_ptr context, + ref_ptr program, + void const * data, uint32_t sizeInBytes) +{ + auto const & mm = m_objectManager->GetMemoryManager(); + auto const alignedSize = mm.GetAligned(sizeInBytes, m_sizeAlignment); + + int index = -1; + for (int i = 0; i < static_cast(m_uniformBuffers.size()); ++i) + { + if (m_uniformBuffers[i].m_freeOffset + alignedSize <= kUniformBufferSizeInBytes) + { + index = i; + break; + } + } + if (index < 0) + { + uint32_t sizeAlignment, offsetAlignment; + m_uniformBuffers.emplace_back(CreateUniformBuffer(context->GetDevice(), m_objectManager, + sizeAlignment, offsetAlignment)); + CHECK_EQUAL(m_sizeAlignment, sizeAlignment, ()); + CHECK_EQUAL(m_offsetAlignment, offsetAlignment, ()); + index = static_cast(m_uniformBuffers.size()) - 1; + } + CHECK_LESS_OR_EQUAL(m_uniformBuffers[index].m_freeOffset + alignedSize, kUniformBufferSizeInBytes, ()); + + auto const alignedOffset = m_uniformBuffers[index].m_freeOffset; + uint8_t * ptr = m_uniformBuffers[index].m_pointer + alignedOffset; + + // Update offset and align it. + m_uniformBuffers[index].m_freeOffset += alignedSize; + m_uniformBuffers[index].m_freeOffset = + std::min(mm.GetAligned(m_uniformBuffers[index].m_freeOffset, m_offsetAlignment), + m_uniformBuffers[index].m_object.m_allocation->m_alignedSize); + + memcpy(ptr, data, sizeInBytes); + + //TODO: setup descriptor to alignedOffset for m_uniformBuffers[index]. + CHECK(false, ()); +} void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, MapProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, RouteProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, TrafficProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, TransitProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, GuiProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, ShapesProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, Arrow3dProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, DebugRectProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, ScreenQuadProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } void VulkanProgramParamsSetter::Apply(ref_ptr context, ref_ptr program, SMAAProgramParams const & params) { - ApplyBytes(context, program, params); + ApplyImpl(context, program, params); } } // namespace vulkan } // namespace gpu diff --git a/shaders/vulkan_program_params.hpp b/shaders/vulkan_program_params.hpp index 1a41a283f5..b884426a0b 100644 --- a/shaders/vulkan_program_params.hpp +++ b/shaders/vulkan_program_params.hpp @@ -2,6 +2,16 @@ #include "shaders/program_params.hpp" +#include "drape/vulkan/vulkan_base_context.hpp" +#include "drape/vulkan/vulkan_gpu_program.hpp" +#include "drape/vulkan/vulkan_object_manager.hpp" + +#include +#include + +#include +#include + namespace gpu { namespace vulkan @@ -9,6 +19,20 @@ namespace vulkan class VulkanProgramParamsSetter : public ProgramParamsSetter { public: + struct UniformBuffer + { + dp::vulkan::VulkanObject m_object; + uint8_t * m_pointer = nullptr; + uint32_t m_freeOffset = 0; + }; + + explicit VulkanProgramParamsSetter(ref_ptr context); + ~VulkanProgramParamsSetter() override; + + void Destroy(ref_ptr context); + void Flush(ref_ptr context); + void Finish(); + void Apply(ref_ptr context, ref_ptr program, MapProgramParams const & params) override; void Apply(ref_ptr context, ref_ptr program, @@ -29,6 +53,25 @@ public: ScreenQuadProgramParams const & params) override; void Apply(ref_ptr context, ref_ptr program, SMAAProgramParams const & params) override; + +private: + template + void ApplyImpl(ref_ptr context, ref_ptr program, + T const & params) + { + ApplyBytes(context, program, reinterpret_cast(¶ms), sizeof(params)); + } + + void ApplyBytes(ref_ptr context, + ref_ptr program, + void const * data, uint32_t sizeInBytes); + + ref_ptr m_objectManager; + std::vector m_uniformBuffers; + uint32_t m_offsetAlignment = 0; + uint32_t m_sizeAlignment = 0; + uint32_t m_flushHandlerId = 0; + uint32_t m_finishHandlerId = 0; }; } // namespace vulkan } // namespace gpu diff --git a/shaders/vulkan_program_pool.cpp b/shaders/vulkan_program_pool.cpp index 49e33d8722..35420bd7a0 100644 --- a/shaders/vulkan_program_pool.cpp +++ b/shaders/vulkan_program_pool.cpp @@ -1,6 +1,7 @@ #include "shaders/vulkan_program_pool.hpp" #include "shaders/program_params.hpp" +#include "drape/vulkan/vulkan_base_context.hpp" #include "drape/vulkan/vulkan_utils.hpp" #include "platform/platform.hpp" @@ -115,11 +116,11 @@ VkShaderModule LoadShaderModule(VkDevice device, std::string const & filename) } } // namespace -VulkanProgramPool::VulkanProgramPool(dp::vulkan::DeviceHolderPtr deviceHolder) - : m_deviceHolder(deviceHolder) +VulkanProgramPool::VulkanProgramPool(ref_ptr context) { - auto devicePtr = m_deviceHolder.lock(); - CHECK(devicePtr != nullptr, ()); + ref_ptr vulkanContext = context; + VkDevice device = vulkanContext->GetDevice(); + auto reflection = ReadReflectionFile(base::JoinPath(kShadersDir, kShadersReflecton)); CHECK_EQUAL(reflection.size(), static_cast(Program::ProgramsCount), ()); for (size_t i = 0; i < static_cast(Program::ProgramsCount); ++i) @@ -128,8 +129,8 @@ VulkanProgramPool::VulkanProgramPool(dp::vulkan::DeviceHolderPtr deviceHolder) m_programs[i] = make_unique_dp( programName, std::move(reflection[i]), - LoadShaderModule(devicePtr->m_device, base::JoinPath(kShadersDir, programName + ".vert.spv")), - LoadShaderModule(devicePtr->m_device, base::JoinPath(kShadersDir, programName + ".frag.spv"))); + LoadShaderModule(device, base::JoinPath(kShadersDir, programName + ".vert.spv")), + LoadShaderModule(device, base::JoinPath(kShadersDir, programName + ".frag.spv"))); } ProgramParams::Init(); @@ -138,17 +139,22 @@ VulkanProgramPool::VulkanProgramPool(dp::vulkan::DeviceHolderPtr deviceHolder) VulkanProgramPool::~VulkanProgramPool() { ProgramParams::Destroy(); + ASSERT(m_programs.front() == nullptr, ()); +} - auto devicePtr = m_deviceHolder.lock(); - CHECK(devicePtr != nullptr, ()); +void VulkanProgramPool::Destroy(ref_ptr context) +{ + ref_ptr vulkanContext = context; + VkDevice device = vulkanContext->GetDevice(); for (auto & p : m_programs) { if (p != nullptr) { - vkDestroyShaderModule(devicePtr->m_device, p->GetVertexShader(), nullptr); - vkDestroyShaderModule(devicePtr->m_device, p->GetFragmentShader(), nullptr); + vkDestroyShaderModule(device, p->GetVertexShader(), nullptr); + vkDestroyShaderModule(device, p->GetFragmentShader(), nullptr); } + p.reset(); } } diff --git a/shaders/vulkan_program_pool.hpp b/shaders/vulkan_program_pool.hpp index 477404f52d..a0ba3ca5a8 100644 --- a/shaders/vulkan_program_pool.hpp +++ b/shaders/vulkan_program_pool.hpp @@ -2,9 +2,9 @@ #include "shaders/program_pool.hpp" -#include "drape/vulkan/vulkan_device_holder.hpp" -#include "drape/vulkan/vulkan_gpu_program.hpp" +#include "drape/graphics_context.hpp" #include "drape/pointers.hpp" +#include "drape/vulkan/vulkan_gpu_program.hpp" #include #include @@ -18,13 +18,13 @@ namespace vulkan class VulkanProgramPool : public ProgramPool { public: - explicit VulkanProgramPool(dp::vulkan::DeviceHolderPtr deviceHolder); + explicit VulkanProgramPool(ref_ptr context); ~VulkanProgramPool() override; + void Destroy(ref_ptr context); drape_ptr Get(Program program) override; private: - dp::vulkan::DeviceHolderPtr m_deviceHolder; std::array, static_cast(Program::ProgramsCount)> m_programs; };