Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/drape
diff options
context:
space:
mode:
authorDaria Volvenkova <d.volvenkova@corp.mail.ru>2019-02-19 18:48:27 +0300
committerDaria Volvenkova <d.volvenkova@corp.mail.ru>2019-03-01 10:45:24 +0300
commitc68749eccf8492671a5f9432fcb2c9af95c04111 (patch)
tree7b2b7212c1699e03dfffd20f5bcdc9a7a3cee0ac /drape
parent4f47cac04191d2ba98a6bfe450319447f8258d49 (diff)
[vulkan] Resize framebuffers. Base context refactoring.
Conflicts: drape/vulkan/vulkan_base_context.cpp
Diffstat (limited to 'drape')
-rw-r--r--drape/mesh_object.cpp8
-rw-r--r--drape/mesh_object.hpp4
-rw-r--r--drape/metal/metal_mesh_object_impl.mm4
-rw-r--r--drape/vulkan/vulkan_base_context.cpp795
-rw-r--r--drape/vulkan/vulkan_base_context.hpp39
-rw-r--r--drape/vulkan/vulkan_mesh_object_impl.cpp10
-rw-r--r--drape/vulkan/vulkan_pipeline.cpp8
-rw-r--r--drape/vulkan/vulkan_pipeline.hpp1
-rw-r--r--drape/vulkan/vulkan_texture.cpp5
9 files changed, 458 insertions, 416 deletions
diff --git a/drape/mesh_object.cpp b/drape/mesh_object.cpp
index 1cd82f2f98..d9e1796773 100644
--- a/drape/mesh_object.cpp
+++ b/drape/mesh_object.cpp
@@ -90,6 +90,8 @@ public:
m_VAO = 0;
}
+ void ResetCache(dp::RenderState const & state) override {}
+
void UpdateBuffer(ref_ptr<dp::GraphicsContext> context, uint32_t bufferInd) override
{
UNUSED_VALUE(context);
@@ -204,6 +206,12 @@ void MeshObject::Reset()
m_initialized = false;
}
+void MeshObject::ResetCache(dp::RenderState const & state)
+{
+ CHECK(m_impl != nullptr, ());
+ m_impl->ResetCache(state);
+}
+
void MeshObject::UpdateBuffer(ref_ptr<dp::GraphicsContext> context, uint32_t bufferInd,
std::vector<float> && vertices)
{
diff --git a/drape/mesh_object.hpp b/drape/mesh_object.hpp
index 4e52f49a32..f1893b0012 100644
--- a/drape/mesh_object.hpp
+++ b/drape/mesh_object.hpp
@@ -55,6 +55,8 @@ public:
dp::RenderState const & state, ref_ptr<TParamsSetter> paramsSetter,
TParams const & params)
{
+ ResetCache(state);
+
Bind(context, program);
ApplyState(context, program, state);
@@ -70,6 +72,7 @@ public:
bool IsInitialized() const { return m_initialized; }
void Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program);
void Reset();
+ void ResetCache(dp::RenderState const & state);
static std::vector<float> GenerateNormalsForTriangles(std::vector<float> const & vertices, size_t componentsCount);
@@ -130,6 +133,7 @@ public:
virtual ~MeshObjectImpl() = default;
virtual void Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program) = 0;
virtual void Reset() = 0;
+ virtual void ResetCache(dp::RenderState const & state) = 0;
virtual void UpdateBuffer(ref_ptr<dp::GraphicsContext> context, uint32_t bufferInd) = 0;
virtual void Bind(ref_ptr<dp::GpuProgram> program) = 0;
virtual void Unbind() = 0;
diff --git a/drape/metal/metal_mesh_object_impl.mm b/drape/metal/metal_mesh_object_impl.mm
index 3a75a18902..d3ca9faa4f 100644
--- a/drape/metal/metal_mesh_object_impl.mm
+++ b/drape/metal/metal_mesh_object_impl.mm
@@ -65,7 +65,9 @@ public:
{
m_geometryBuffers.clear();
}
-
+
+ void ResetCache(dp::RenderState const & state) override {}
+
void UpdateBuffer(ref_ptr<dp::GraphicsContext> context, uint32_t bufferInd) override
{
UNUSED_VALUE(context);
diff --git a/drape/vulkan/vulkan_base_context.cpp b/drape/vulkan/vulkan_base_context.cpp
index 31597e15a9..0947797245 100644
--- a/drape/vulkan/vulkan_base_context.cpp
+++ b/drape/vulkan/vulkan_base_context.cpp
@@ -58,10 +58,14 @@ VulkanBaseContext::VulkanBaseContext(VkInstance vulkanInstance, VkPhysicalDevice
//TODO: do it for draw context only.
// Get a graphics queue from the device
vkGetDeviceQueue(m_device, m_renderingQueueFamilyIndex, 0, &m_queue);
+ CreateCommandPool();
+ CreateSyncPrimitives();
}
VulkanBaseContext::~VulkanBaseContext()
{
+ vkDeviceWaitIdle(m_device);
+
if (m_pipeline)
{
m_pipeline->Destroy(m_device);
@@ -70,15 +74,9 @@ VulkanBaseContext::~VulkanBaseContext()
m_defaultStagingBuffer.reset();
- for (auto & fbData : m_framebuffersData)
- {
- for (auto & framebuffer : fbData.second.m_framebuffers)
- vkDestroyFramebuffer(m_device, framebuffer, nullptr);
- vkDestroyRenderPass(m_device, fbData.second.m_renderPass, nullptr);
- }
-
- DestroyDepthTexture();
+ DestroyFramebuffers();
DestroySwapchain();
+ DestroySyncPrimitives();
DestroyCommandBuffers();
DestroyCommandPool();
}
@@ -100,13 +98,76 @@ std::string VulkanBaseContext::GetRendererVersion() const
return ss.str();
}
-bool VulkanBaseContext::Validate()
+void VulkanBaseContext::Init(ApiVersion apiVersion)
{
- return true;
+ m_defaultStagingBuffer = make_unique_dp<VulkanStagingBuffer>(m_objectManager,
+ kDefaultStagingBufferSizeInBytes);
+}
+
+void VulkanBaseContext::SetSurface(VkSurfaceKHR surface, VkSurfaceFormatKHR surfaceFormat,
+ VkSurfaceCapabilitiesKHR surfaceCapabilities, int width, int height)
+{
+ m_surface = surface;
+ m_surfaceFormat = surfaceFormat;
+ m_surfaceCapabilities = surfaceCapabilities;
+ CreateCommandBuffers();
+ RecreateDepthTexture();
+ RecreateSwapchain();
+}
+
+void VulkanBaseContext::ResetSurface()
+{
+ vkDeviceWaitIdle(m_device);
+
+ if (m_pipeline)
+ m_pipeline->ResetCache(m_device);
+
+ DestroyFramebuffers();
+ m_depthTexture.reset();
+
+ DestroyCommandBuffers();
+ DestroySwapchain();
+
+ m_surface.reset();
+
+ if (m_pipeline)
+ m_pipeline->Dump(m_device);
}
void VulkanBaseContext::Resize(int w, int h)
{
+ if (m_depthTexture != nullptr && m_surfaceCapabilities.currentExtent.width == w &&
+ m_surfaceCapabilities.currentExtent.height == h)
+ {
+ return;
+ }
+
+ vkDeviceWaitIdle(m_device);
+
+ m_surfaceCapabilities.currentExtent.width = static_cast<uint32_t>(w);
+ m_surfaceCapabilities.currentExtent.height = static_cast<uint32_t>(h);
+
+ RecreateDepthTexture();
+ RecreateSwapchain();
+}
+
+void VulkanBaseContext::BeginRendering()
+{
+ CHECK_VK_CALL(vkWaitForFences(m_device, 1, &m_fence, VK_TRUE, UINT64_MAX));
+ CHECK_VK_CALL(vkResetFences(m_device, 1, &m_fence));
+
+ VkCommandBufferBeginInfo commandBufferBeginInfo = {};
+ commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+
+ CHECK_VK_CALL(vkBeginCommandBuffer(m_memoryCommandBuffer, &commandBufferBeginInfo));
+ CHECK_VK_CALL(vkBeginCommandBuffer(m_renderingCommandBuffer, &commandBufferBeginInfo));
+
+ VkResult res = vkAcquireNextImageKHR(m_device, m_swapchain, UINT64_MAX, m_presentComplete,
+ (VkFence)nullptr, &m_imageIndex);
+ if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR)
+ RecreateSwapchain();
+ else
+ CHECK_RESULT_VK_CALL(vkAcquireNextImageKHR, res);
}
void VulkanBaseContext::SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer)
@@ -125,7 +186,6 @@ void VulkanBaseContext::SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer)
vkCmdEndRenderPass(m_renderingCommandBuffer);
m_isActiveRenderPass = false;
-
}
m_currentFramebuffer = framebuffer;
@@ -136,46 +196,9 @@ void VulkanBaseContext::ApplyFramebuffer(std::string const & framebufferLabel)
vkCmdSetStencilReference(m_renderingCommandBuffer, VK_STENCIL_FRONT_AND_BACK,
m_stencilReferenceValue);
- auto & fbData = m_framebuffersData[m_currentFramebuffer];
-
- VkAttachmentLoadOp colorLoadOp, depthLoadOp, stencilLoadOp;
- VkAttachmentStoreOp colorStoreOp, depthStoreOp, stencilStoreOp;
- // Here, if we do not clear attachments, we load data ONLY if we store it afterwards, otherwise we use 'DontCare' option
- // to improve performance.
- if (m_clearBits & ClearBits::ColorBit)
- colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- else
- colorLoadOp = (m_storeBits & ClearBits::ColorBit) ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-
- if (m_clearBits & ClearBits::DepthBit)
- depthLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- else
- depthLoadOp = (m_storeBits & ClearBits::DepthBit) ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-
- if (m_clearBits & ClearBits::StencilBit)
- stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- else
- stencilLoadOp = (m_storeBits & ClearBits::StencilBit) ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-
- // Apply storing mode.
- if (m_storeBits & ClearBits::ColorBit)
- colorStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
- else
- colorStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-
- if (m_storeBits & ClearBits::DepthBit)
- depthStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
- else
- depthStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-
- if (m_storeBits & ClearBits::StencilBit)
- stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
- else
- stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-
- m_clearBits = 0;
- m_storeBits = 0;
+ auto attachmentsOp = GetAttachmensOperations();
+ auto & fbData = m_framebuffersData[m_currentFramebuffer];
if (fbData.m_renderPass == VK_NULL_HANDLE)
{
VkFormat colorFormat = {};
@@ -186,14 +209,14 @@ void VulkanBaseContext::ApplyFramebuffer(std::string const & framebufferLabel)
colorFormat = m_surfaceFormat.get().format;
depthFormat = UnpackFormat(TextureFormat::Depth);
- fbData.m_renderPass = CreateRenderPass(2 /* attachmentsCount */,
- colorFormat, VK_ATTACHMENT_LOAD_OP_CLEAR, colorStoreOp,
- VK_IMAGE_LAYOUT_UNDEFINED,
+ attachmentsOp.m_color.m_loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ attachmentsOp.m_depth.m_loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ attachmentsOp.m_stencil.m_loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+
+ fbData.m_renderPass = CreateRenderPass(2 /* attachmentsCount */, attachmentsOp,
+ colorFormat, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
- depthFormat, VK_ATTACHMENT_LOAD_OP_CLEAR, depthStoreOp,
- VK_ATTACHMENT_LOAD_OP_DONT_CARE,
- VK_ATTACHMENT_STORE_OP_DONT_CARE,
- VK_IMAGE_LAYOUT_UNDEFINED,
+ depthFormat, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
else
@@ -205,13 +228,9 @@ void VulkanBaseContext::ApplyFramebuffer(std::string const & framebufferLabel)
if (depthStencilRef != nullptr)
depthFormat = UnpackFormat(depthStencilRef->GetTexture()->GetFormat());
- fbData.m_renderPass = CreateRenderPass(attachmentsCount,
- colorFormat, colorLoadOp, colorStoreOp,
- VK_IMAGE_LAYOUT_UNDEFINED,
+ fbData.m_renderPass = CreateRenderPass(attachmentsCount, attachmentsOp, colorFormat, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- depthFormat, depthLoadOp, depthStoreOp,
- stencilLoadOp, stencilStoreOp,
- VK_IMAGE_LAYOUT_UNDEFINED,
+ depthFormat, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
}
@@ -223,7 +242,7 @@ void VulkanBaseContext::ApplyFramebuffer(std::string const & framebufferLabel)
std::array<VkImageView, 2> attachmentViews = {};
// Depth/Stencil attachment is the same for all swapchain-bound frame buffers.
- attachmentViews[1] = m_depthStencil.m_imageView;
+ attachmentViews[1] = m_depthTexture->GetTextureView();
VkFramebufferCreateInfo frameBufferCreateInfo = {};
frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
@@ -247,6 +266,8 @@ void VulkanBaseContext::ApplyFramebuffer(std::string const & framebufferLabel)
else
{
ref_ptr<dp::Framebuffer> framebuffer = m_currentFramebuffer;
+ framebuffer->SetSize(this, m_surfaceCapabilities.currentExtent.width,
+ m_surfaceCapabilities.currentExtent.height);
auto const depthStencilRef = framebuffer->GetDepthStencilRef();
auto const attachmentsCount = (depthStencilRef != nullptr) ? 2 : 1;
@@ -284,7 +305,7 @@ void VulkanBaseContext::ApplyFramebuffer(std::string const & framebufferLabel)
VkClearValue clearValues[2];
clearValues[0].color = {{m_clearColor.GetRedF(), m_clearColor.GetGreenF(), m_clearColor.GetBlueF(),
m_clearColor.GetAlphaF()}};
- clearValues[1].depthStencil = {1.0f, 0};
+ clearValues[1].depthStencil = {1.0f, m_stencilReferenceValue};
VkRenderPassBeginInfo renderPassBeginInfo = {};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@@ -300,10 +321,99 @@ void VulkanBaseContext::ApplyFramebuffer(std::string const & framebufferLabel)
vkCmdBeginRenderPass(m_renderingCommandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
}
-void VulkanBaseContext::Init(ApiVersion apiVersion)
+void VulkanBaseContext::Present()
{
- m_defaultStagingBuffer = make_unique_dp<VulkanStagingBuffer>(m_objectManager,
- kDefaultStagingBufferSizeInBytes);
+ // Flushing of the default staging buffer must be before submitting the queue.
+ // It guarantees the graphics data coherence.
+ m_defaultStagingBuffer->Flush();
+
+ for (auto const & h : m_handlers[static_cast<uint32_t>(HandlerType::PrePresent)])
+ h.second(make_ref(this));
+
+ CHECK(m_isActiveRenderPass, ());
+ m_isActiveRenderPass = false;
+ vkCmdEndRenderPass(m_renderingCommandBuffer);
+
+ CHECK_VK_CALL(vkEndCommandBuffer(m_memoryCommandBuffer));
+ CHECK_VK_CALL(vkEndCommandBuffer(m_renderingCommandBuffer));
+
+ VkSubmitInfo submitInfo = {};
+ VkPipelineStageFlags const waitStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ VkCommandBuffer commandBuffers[] = {m_memoryCommandBuffer, m_renderingCommandBuffer};
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.pWaitDstStageMask = &waitStageMask;
+ submitInfo.pWaitSemaphores = &m_presentComplete;
+ submitInfo.waitSemaphoreCount = 1;
+ submitInfo.pSignalSemaphores = &m_renderComplete;
+ submitInfo.signalSemaphoreCount = 1;
+ submitInfo.commandBufferCount = 2;
+ submitInfo.pCommandBuffers = commandBuffers;
+
+ CHECK_VK_CALL(vkQueueSubmit(m_queue, 1, &submitInfo, m_fence));
+
+ VkPresentInfoKHR presentInfo = {};
+ presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+ presentInfo.pNext = nullptr;
+ presentInfo.swapchainCount = 1;
+ presentInfo.pSwapchains = &m_swapchain;
+ presentInfo.pImageIndices = &m_imageIndex;
+ presentInfo.pWaitSemaphores = &m_renderComplete;
+ presentInfo.waitSemaphoreCount = 1;
+
+ VkResult res = vkQueuePresentKHR(m_queue, &presentInfo);
+ if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR)
+ {
+ if (res == VK_ERROR_OUT_OF_DATE_KHR)
+ RecreateSwapchain();
+ else
+ CHECK_RESULT_VK_CALL(vkQueuePresentKHR, res);
+ }
+
+ CHECK_VK_CALL(vkQueueWaitIdle(m_queue));
+
+ for (auto const & h : m_handlers[static_cast<uint32_t>(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_defaultStagingBuffer->Reset();
+
+ static uint8_t framesCounter = 0;
+ if (framesCounter % 10 == 0)
+ {
+ framesCounter = 0;
+ DrapeRoutine::Run([this]() { m_objectManager->CollectObjects(); });
+ }
+ else
+ {
+ framesCounter++;
+ }
+
+ m_pipelineKey = {};
+ m_stencilReferenceValue = 1;
+ ClearParamDescriptors();
+}
+
+uint32_t VulkanBaseContext::RegisterHandler(HandlerType handlerType, ContextHandler && handler)
+{
+ static uint32_t counter = 0;
+ CHECK_LESS(counter, std::numeric_limits<uint32_t>::max(), ());
+ ASSERT(handler != nullptr, ());
+ uint32_t const id = ++counter;
+ m_handlers[static_cast<uint32_t>(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<uint8_t, ContextHandler> const & p)
+ {
+ return p.first == id;
+ }), m_handlers[i].end());
+ }
}
void VulkanBaseContext::SetClearColor(Color const & color)
@@ -359,6 +469,52 @@ void VulkanBaseContext::Clear(uint32_t clearBits, uint32_t storeBits)
}
}
+VulkanBaseContext::AttachmentsOperations VulkanBaseContext::GetAttachmensOperations()
+{
+ AttachmentsOperations operations;
+
+ // Here, if we do not clear attachments, we load data ONLY if we store it afterwards, otherwise we use 'DontCare' option
+ // to improve performance.
+ if (m_clearBits & ClearBits::ColorBit)
+ operations.m_color.m_loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ else
+ operations.m_color.m_loadOp = (m_storeBits & ClearBits::ColorBit) ? VK_ATTACHMENT_LOAD_OP_LOAD
+ : VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+
+ if (m_clearBits & ClearBits::DepthBit)
+ operations.m_depth.m_loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ else
+ operations.m_depth.m_loadOp = (m_storeBits & ClearBits::DepthBit) ? VK_ATTACHMENT_LOAD_OP_LOAD
+ : VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+
+ if (m_clearBits & ClearBits::StencilBit)
+ operations.m_stencil.m_loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ else
+ operations.m_stencil.m_loadOp = (m_storeBits & ClearBits::StencilBit) ? VK_ATTACHMENT_LOAD_OP_LOAD
+ : VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+
+ // Apply storing mode.
+ if (m_storeBits & ClearBits::ColorBit)
+ operations.m_color.m_storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ else
+ operations.m_color.m_storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+
+ if (m_storeBits & ClearBits::DepthBit)
+ operations.m_depth.m_storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ else
+ operations.m_depth.m_storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+
+ if (m_storeBits & ClearBits::StencilBit)
+ operations.m_stencil.m_storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ else
+ operations.m_stencil.m_storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+
+ m_clearBits = 0;
+ m_storeBits = 0;
+
+ return operations;
+}
+
void VulkanBaseContext::SetViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
VkViewport viewport = {};
@@ -377,179 +533,119 @@ void VulkanBaseContext::SetViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t
vkCmdSetScissor(m_renderingCommandBuffer, 0, 1, &scissor);
}
-void VulkanBaseContext::SetSurface(VkSurfaceKHR surface, VkSurfaceFormatKHR surfaceFormat,
- VkSurfaceCapabilitiesKHR surfaceCapabilities, int width, int height)
+void VulkanBaseContext::SetDepthTestEnabled(bool enabled)
{
- m_surface = surface;
- if (!m_surfaceFormat.is_initialized() ||
- m_surfaceFormat.get().format != surfaceFormat.format ||
- m_surfaceFormat.get().colorSpace != surfaceFormat.colorSpace)
- {
- if (m_surfaceFormat.is_initialized())
- {
- DestroyCommandBuffers();
- DestroyCommandPool();
- DestroyDepthTexture();
- }
- m_surfaceFormat = surfaceFormat;
- m_surfaceCapabilities = surfaceCapabilities;
- CreateCommandPool();
- CreateCommandBuffers();
- CreateDepthTexture();
- }
- RecreateSwapchain();
+ m_pipelineKey.m_depthStencil.SetDepthTestEnabled(enabled);
}
-void VulkanBaseContext::ResetSurface()
+void VulkanBaseContext::SetDepthTestFunction(TestFunction depthFunction)
{
- vkDeviceWaitIdle(m_device);
-
- for (auto & framebuffer : m_framebuffersData[nullptr].m_framebuffers)
- vkDestroyFramebuffer(m_device, framebuffer, nullptr);
- vkDestroyRenderPass(m_device, m_framebuffersData[nullptr].m_renderPass, nullptr);
- m_framebuffersData[nullptr] = {};
- // TODO(@darina): clear pipeline keys with the same renderPass
- DestroySwapchain();
-
- m_surface.reset();
-
- if (m_pipeline)
- m_pipeline->Dump(m_device);
+ m_pipelineKey.m_depthStencil.SetDepthTestFunction(depthFunction);
}
-void VulkanBaseContext::BeginRendering()
+void VulkanBaseContext::SetStencilTestEnabled(bool enabled)
{
- // Record command buffer.
- // A fence is used to wait until this command buffer has finished execution and is no longer in-flight.
- // Command buffers can only be re-recorded or destroyed if they are not in-flight.
- CHECK_VK_CALL(vkWaitForFences(m_device, 1, &m_fence, VK_TRUE, UINT64_MAX));
- CHECK_VK_CALL(vkResetFences(m_device, 1, &m_fence));
-
- VkCommandBufferBeginInfo commandBufferBeginInfo = {};
- commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- CHECK_VK_CALL(vkBeginCommandBuffer(m_memoryCommandBuffer, &commandBufferBeginInfo));
- CHECK_VK_CALL(vkBeginCommandBuffer(m_renderingCommandBuffer, &commandBufferBeginInfo));
-
- // 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.
- VkResult res = vkAcquireNextImageKHR(m_device, m_swapchain, UINT64_MAX, m_presentComplete,
- (VkFence)nullptr, &m_imageIndex);
- if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR)
- {
- // Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE)
- // or no longer optimal for presentation (SUBOPTIMAL).
- RecreateSwapchain();
- }
- else
- {
- CHECK_RESULT_VK_CALL(vkAcquireNextImageKHR, res);
- }
+ m_pipelineKey.m_depthStencil.SetStencilTestEnabled(enabled);
}
-void VulkanBaseContext::Present()
+void VulkanBaseContext::SetStencilFunction(StencilFace face, TestFunction stencilFunction)
{
- // Flushing of the default staging buffer must be before submitting the queue.
- // It guarantees the graphics data coherence.
- m_defaultStagingBuffer->Flush();
-
- for (auto const & h : m_handlers[static_cast<uint32_t>(HandlerType::PrePresent)])
- h.second(make_ref(this));
+ m_pipelineKey.m_depthStencil.SetStencilFunction(face, stencilFunction);
+}
- CHECK(m_isActiveRenderPass, ());
- m_isActiveRenderPass = false;
- vkCmdEndRenderPass(m_renderingCommandBuffer);
+void VulkanBaseContext::SetStencilActions(StencilFace face, StencilAction stencilFailAction,
+ StencilAction depthFailAction, StencilAction passAction)
+{
+ m_pipelineKey.m_depthStencil.SetStencilActions(face, stencilFailAction, depthFailAction, passAction);
+}
- CHECK_VK_CALL(vkEndCommandBuffer(m_memoryCommandBuffer));
- CHECK_VK_CALL(vkEndCommandBuffer(m_renderingCommandBuffer));
+void VulkanBaseContext::SetStencilReferenceValue(uint32_t stencilReferenceValue)
+{
+ m_stencilReferenceValue = stencilReferenceValue;
+}
- // Pipeline stage at which the queue submission will wait (via pWaitSemaphores).
- VkPipelineStageFlags const waitStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+void VulkanBaseContext::SetPrimitiveTopology(VkPrimitiveTopology topology)
+{
+ m_pipelineKey.m_primitiveTopology = topology;
+}
- VkSubmitInfo submitInfo = {};
- VkCommandBuffer commandBuffers[] = {m_memoryCommandBuffer, m_renderingCommandBuffer};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pWaitDstStageMask = &waitStageMask;
- submitInfo.pWaitSemaphores = &m_presentComplete;
- submitInfo.waitSemaphoreCount = 1;
- submitInfo.pSignalSemaphores = &m_renderComplete;
- submitInfo.signalSemaphoreCount = 1;
- submitInfo.commandBufferCount = 2;
- submitInfo.pCommandBuffers = commandBuffers;
+void VulkanBaseContext::SetBindingInfo(BindingInfoArray const & bindingInfo, uint8_t bindingInfoCount)
+{
+ std::copy(bindingInfo.begin(), bindingInfo.begin() + bindingInfoCount,
+ m_pipelineKey.m_bindingInfo.begin());
+ m_pipelineKey.m_bindingInfoCount = bindingInfoCount;
+}
- CHECK_VK_CALL(vkQueueSubmit(m_queue, 1, &submitInfo, m_fence));
+void VulkanBaseContext::SetProgram(ref_ptr<VulkanGpuProgram> program)
+{
+ m_pipelineKey.m_program = program;
+}
- // Queue an image for presentation.
- VkPresentInfoKHR presentInfo = {};
- presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
- presentInfo.pNext = nullptr;
- presentInfo.swapchainCount = 1;
- presentInfo.pSwapchains = &m_swapchain;
- presentInfo.pImageIndices = &m_imageIndex;
- // Check if a wait semaphore has been specified to wait for before presenting the image.
- presentInfo.pWaitSemaphores = &m_renderComplete;
- presentInfo.waitSemaphoreCount = 1;
+void VulkanBaseContext::SetBlendingEnabled(bool blendingEnabled)
+{
+ m_pipelineKey.m_blendingEnabled = blendingEnabled;
+}
- VkResult res = vkQueuePresentKHR(m_queue, &presentInfo);
- if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR)
+void VulkanBaseContext::ApplyParamDescriptor(ParamDescriptor && descriptor)
+{
+ if (descriptor.m_type == ParamDescriptor::Type::DynamicUniformBuffer)
{
- if (res == VK_ERROR_OUT_OF_DATE_KHR)
- {
- // Swap chain is no longer compatible with the surface and needs to be recreated.
- RecreateSwapchain();
- }
- else
+ for (auto & param : m_paramDescriptors)
{
- CHECK_RESULT_VK_CALL(vkQueuePresentKHR, res);
+ if (param.m_type == ParamDescriptor::Type::DynamicUniformBuffer)
+ {
+ param = std::move(descriptor);
+ return;
+ }
}
}
- CHECK_VK_CALL(vkQueueWaitIdle(m_queue));
-
- for (auto const & h : m_handlers[static_cast<uint32_t>(HandlerType::PostPresent)])
- h.second(make_ref(this));
+ m_paramDescriptors.push_back(std::move(descriptor));
+}
- // Resetting of the default staging buffer and collecting destroyed objects must be
- // only after the finishing of rendering. It prevents data collisions.
- m_defaultStagingBuffer->Reset();
+void VulkanBaseContext::ClearParamDescriptors()
+{
+ m_paramDescriptors.clear();
+}
- static uint8_t framesCounter = 0;
- if (framesCounter % 10 == 0)
- {
- framesCounter = 0;
- DrapeRoutine::Run([this]() { m_objectManager->CollectObjects(); });
- }
- else
- {
- framesCounter++;
- }
+VkPipeline VulkanBaseContext::GetCurrentPipeline()
+{
+ return m_pipeline->GetPipeline(m_device, m_pipelineKey);
+}
- m_pipelineKey = {};
- m_stencilReferenceValue = 1;
- ClearParamDescriptors();
+DescriptorSetGroup VulkanBaseContext::GetCurrentDescriptorSetGroup()
+{
+ CHECK(m_pipelineKey.m_program != nullptr, ());
+ CHECK(!m_paramDescriptors.empty(), ("Shaders parameters are not set."));
+ return m_objectManager->CreateDescriptorSetGroup(m_pipelineKey.m_program, m_paramDescriptors);
}
-uint32_t VulkanBaseContext::RegisterHandler(HandlerType handlerType, ContextHandler && handler)
+VkPipelineLayout VulkanBaseContext::GetCurrentPipelineLayout() const
{
- static uint32_t counter = 0;
- CHECK_LESS(counter, std::numeric_limits<uint32_t>::max(), ());
- ASSERT(handler != nullptr, ());
- uint32_t const id = ++counter;
- m_handlers[static_cast<uint32_t>(handlerType)].emplace_back(std::make_pair(id, std::move(handler)));
- return id;
+ CHECK(m_pipelineKey.m_program != nullptr, ());
+ return m_pipelineKey.m_program->GetPipelineLayout();
}
-void VulkanBaseContext::UnregisterHandler(uint32_t id)
+uint32_t VulkanBaseContext::GetCurrentDynamicBufferOffset() const
{
- for (size_t i = 0; i < m_handlers.size(); ++i)
+ for (auto const & p : m_paramDescriptors)
{
- m_handlers[i].erase(std::remove_if(m_handlers[i].begin(), m_handlers[i].end(),
- [id](std::pair<uint8_t, ContextHandler> const & p)
- {
- return p.first == id;
- }), m_handlers[i].end());
+ if (p.m_type == ParamDescriptor::Type::DynamicUniformBuffer)
+ return p.m_bufferDynamicOffset;
}
+ CHECK(false, ("Shaders parameters are not set."));
+ return 0;
}
+VkSampler VulkanBaseContext::GetSampler(SamplerKey const & key)
+{
+ return m_objectManager->GetSampler(key);
+}
+
+ref_ptr<VulkanStagingBuffer> VulkanBaseContext::GetDefaultStagingBuffer() const
+{
+ return make_ref(m_defaultStagingBuffer);
+}
+
void VulkanBaseContext::RecreateSwapchain()
{
CHECK(m_surface.is_initialized(), ());
@@ -557,49 +653,46 @@ void VulkanBaseContext::RecreateSwapchain()
VkSwapchainKHR oldSwapchain = m_swapchain;
- VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
- swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
- swapchainCreateInfo.pNext = nullptr;
- swapchainCreateInfo.surface = m_surface.get();
- swapchainCreateInfo.minImageCount = std::min(m_surfaceCapabilities.minImageCount + 1,
- m_surfaceCapabilities.maxImageCount);
- swapchainCreateInfo.imageFormat = m_surfaceFormat.get().format;
- swapchainCreateInfo.imageColorSpace = m_surfaceFormat.get().colorSpace;
- swapchainCreateInfo.imageExtent = m_surfaceCapabilities.currentExtent;
-
- swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
-
+ VkSwapchainCreateInfoKHR swapchainCI = {};
+ swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ swapchainCI.pNext = nullptr;
+ swapchainCI.surface = m_surface.get();
+ swapchainCI.minImageCount = std::min(m_surfaceCapabilities.minImageCount + 1,
+ m_surfaceCapabilities.maxImageCount);
+ swapchainCI.imageFormat = m_surfaceFormat.get().format;
+ swapchainCI.imageColorSpace = m_surfaceFormat.get().colorSpace;
+ swapchainCI.imageExtent = m_surfaceCapabilities.currentExtent;
+
+ swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
if (m_surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
- swapchainCreateInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
-
+ swapchainCI.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
if (m_surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
- swapchainCreateInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ swapchainCI.imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
CHECK(m_surfaceCapabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, ());
- swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+ swapchainCI.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
- swapchainCreateInfo.imageArrayLayers = 1;
- swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
- swapchainCreateInfo.queueFamilyIndexCount = 0;
- swapchainCreateInfo.pQueueFamilyIndices = nullptr;
+ swapchainCI.imageArrayLayers = 1;
+ swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ swapchainCI.queueFamilyIndexCount = 0;
+ swapchainCI.pQueueFamilyIndices = nullptr;
CHECK(m_surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, ());
- swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
+ swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
// This mode waits for the vertical blank ("v-sync").
- swapchainCreateInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
+ swapchainCI.presentMode = VK_PRESENT_MODE_FIFO_KHR;
+ swapchainCI.oldSwapchain = oldSwapchain;
+ swapchainCI.clipped = VK_TRUE;
- swapchainCreateInfo.oldSwapchain = oldSwapchain;
- // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the surface area.
- swapchainCreateInfo.clipped = VK_TRUE;
-
- CHECK_VK_CALL(vkCreateSwapchainKHR(m_device, &swapchainCreateInfo, nullptr, &m_swapchain));
+ CHECK_VK_CALL(vkCreateSwapchainKHR(m_device, &swapchainCI, nullptr, &m_swapchain));
if (oldSwapchain != VK_NULL_HANDLE)
{
for (auto const & imageView : m_swapchainImageViews)
vkDestroyImageView(m_device, imageView, nullptr);
m_swapchainImageViews.clear();
+ m_swapchainImages.clear();
}
// Create swapchain image views.
@@ -612,19 +705,19 @@ void VulkanBaseContext::RecreateSwapchain()
m_swapchainImageViews.resize(swapchainImageCount);
for (size_t i = 0; i < m_swapchainImageViews.size(); ++i)
{
- VkImageViewCreateInfo colorAttachmentImageView = {};
- colorAttachmentImageView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- colorAttachmentImageView.image = m_swapchainImages[i];
- colorAttachmentImageView.viewType = VK_IMAGE_VIEW_TYPE_2D;
- colorAttachmentImageView.format = m_surfaceFormat.get().format;
- colorAttachmentImageView.components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
- VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
- colorAttachmentImageView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- colorAttachmentImageView.subresourceRange.baseMipLevel = 0;
- colorAttachmentImageView.subresourceRange.levelCount = 1;
- colorAttachmentImageView.subresourceRange.baseArrayLayer = 0;
- colorAttachmentImageView.subresourceRange.layerCount = 1;
- CHECK_VK_CALL(vkCreateImageView(m_device, &colorAttachmentImageView, nullptr,
+ VkImageViewCreateInfo swapchainImageViewCI = {};
+ swapchainImageViewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ swapchainImageViewCI.image = m_swapchainImages[i];
+ swapchainImageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ swapchainImageViewCI.format = m_surfaceFormat.get().format;
+ swapchainImageViewCI.components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
+ VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
+ swapchainImageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ swapchainImageViewCI.subresourceRange.baseMipLevel = 0;
+ swapchainImageViewCI.subresourceRange.levelCount = 1;
+ swapchainImageViewCI.subresourceRange.baseArrayLayer = 0;
+ swapchainImageViewCI.subresourceRange.layerCount = 1;
+ CHECK_VK_CALL(vkCreateImageView(m_device, &swapchainImageViewCI, nullptr,
&m_swapchainImageViews[i]));
}
}
@@ -634,10 +727,22 @@ void VulkanBaseContext::DestroySwapchain()
for (auto const & imageView : m_swapchainImageViews)
vkDestroyImageView(m_device, imageView, nullptr);
m_swapchainImageViews.clear();
+ m_swapchainImages.clear();
vkDestroySwapchainKHR(m_device, m_swapchain, nullptr);
m_swapchain = VK_NULL_HANDLE;
}
+void VulkanBaseContext::DestroyFramebuffers()
+{
+ for (auto & fbData : m_framebuffersData)
+ {
+ for (auto & framebuffer : fbData.second.m_framebuffers)
+ vkDestroyFramebuffer(m_device, framebuffer, nullptr);
+ vkDestroyRenderPass(m_device, fbData.second.m_renderPass, nullptr);
+ }
+ m_framebuffersData.clear();
+}
+
void VulkanBaseContext::CreateCommandPool()
{
VkCommandPoolCreateInfo commandPoolCI = {};
@@ -655,69 +760,72 @@ void VulkanBaseContext::DestroyCommandPool()
void VulkanBaseContext::CreateCommandBuffers()
{
+ VkCommandBufferAllocateInfo cmdBufAllocateInfo = {};
+ cmdBufAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ cmdBufAllocateInfo.commandPool = m_commandPool;
+ cmdBufAllocateInfo.commandBufferCount = 1;
+ cmdBufAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ CHECK_VK_CALL(vkAllocateCommandBuffers(m_device, &cmdBufAllocateInfo, &m_memoryCommandBuffer));
+ CHECK_VK_CALL(vkAllocateCommandBuffers(m_device, &cmdBufAllocateInfo, &m_renderingCommandBuffer));
+}
+
+void VulkanBaseContext::DestroyCommandBuffers()
+{
+ vkFreeCommandBuffers(m_device, m_commandPool, 1, &m_memoryCommandBuffer);
+ vkFreeCommandBuffers(m_device, m_commandPool, 1, &m_renderingCommandBuffer);
+}
+
+void VulkanBaseContext::CreateSyncPrimitives()
+{
// A fence is need to check for command buffer completion before we can recreate it.
VkFenceCreateInfo fenceCI = {};
fenceCI.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCI.flags = VK_FENCE_CREATE_SIGNALED_BIT;
CHECK_VK_CALL(vkCreateFence(m_device, &fenceCI, nullptr, &m_fence));
- // Semaphores are used to order queue submissions.
VkSemaphoreCreateInfo semaphoreCI = {};
semaphoreCI.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
CHECK_VK_CALL(vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_presentComplete));
CHECK_VK_CALL(vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_renderComplete));
-
- // Create a single command buffer that is recorded every frame.
- VkCommandBufferAllocateInfo cmdBufAllocateInfo = {};
- cmdBufAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- cmdBufAllocateInfo.commandPool = m_commandPool;
- cmdBufAllocateInfo.commandBufferCount = 1;
- cmdBufAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- CHECK_VK_CALL(vkAllocateCommandBuffers(m_device, &cmdBufAllocateInfo, &m_memoryCommandBuffer));
- CHECK_VK_CALL(vkAllocateCommandBuffers(m_device, &cmdBufAllocateInfo, &m_renderingCommandBuffer));
}
-void VulkanBaseContext::DestroyCommandBuffers()
+void VulkanBaseContext::DestroySyncPrimitives()
{
vkDestroyFence(m_device, m_fence, nullptr);
vkDestroySemaphore(m_device, m_presentComplete, nullptr);
vkDestroySemaphore(m_device, m_renderComplete, nullptr);
- vkFreeCommandBuffers(m_device, m_commandPool, 1, &m_memoryCommandBuffer);
- vkFreeCommandBuffers(m_device, m_commandPool, 1, &m_renderingCommandBuffer);
}
-void VulkanBaseContext::CreateDepthTexture()
+void VulkanBaseContext::RecreateDepthTexture()
{
- CHECK(m_depthStencil.m_image == VK_NULL_HANDLE, ());
- m_depthStencil = m_objectManager->CreateImage(
- VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
- UnpackFormat(TextureFormat::Depth),
- VK_IMAGE_ASPECT_DEPTH_BIT,
- m_surfaceCapabilities.currentExtent.width, m_surfaceCapabilities.currentExtent.height);
-}
+ Texture::Params params;
+ params.m_width = m_surfaceCapabilities.currentExtent.width;
+ params.m_height = m_surfaceCapabilities.currentExtent.height;
+ params.m_format = TextureFormat::Depth;
+ params.m_allocator = GetDefaultAllocator(this);
+ params.m_isRenderTarget = true;
-void VulkanBaseContext::DestroyDepthTexture()
-{
- if (m_depthStencil.m_image != VK_NULL_HANDLE)
- m_objectManager->DestroyObject(m_depthStencil);
+ m_depthTexture = make_unique_dp<VulkanTexture>(params.m_allocator);
+ m_depthTexture->Create(this, params, nullptr);
+
+ //m_depthTexture = m_objectManager->CreateImage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+ // UnpackFormat(TextureFormat::Depth), VK_IMAGE_ASPECT_DEPTH_BIT,
+ // m_surfaceCapabilities.currentExtent.width,
+ // m_surfaceCapabilities.currentExtent.height);
}
-VkRenderPass VulkanBaseContext::CreateRenderPass(uint32_t attachmentsCount, VkFormat colorFormat,
- VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp,
- VkImageLayout initLayout, VkImageLayout finalLayout,
- VkFormat depthFormat, VkAttachmentLoadOp depthLoadOp,
- VkAttachmentStoreOp depthStoreOp, VkAttachmentLoadOp stencilLoadOp,
- VkAttachmentStoreOp stencilStoreOp, VkImageLayout depthInitLayout,
- VkImageLayout depthFinalLayout)
+VkRenderPass VulkanBaseContext::CreateRenderPass(uint32_t attachmentsCount, AttachmentsOperations const & attachmentsOp,
+ VkFormat colorFormat, VkImageLayout initLayout,
+ VkImageLayout finalLayout, VkFormat depthFormat,
+ VkImageLayout depthInitLayout, VkImageLayout depthFinalLayout)
{
std::vector<VkAttachmentDescription> attachments(attachmentsCount);
- // Color attachment.
attachments[0].format = colorFormat;
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
- attachments[0].loadOp = loadOp;
- attachments[0].storeOp = storeOp;
+ attachments[0].loadOp = attachmentsOp.m_color.m_loadOp;
+ attachments[0].storeOp = attachmentsOp.m_color.m_storeOp;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = initLayout;
@@ -725,13 +833,12 @@ VkRenderPass VulkanBaseContext::CreateRenderPass(uint32_t attachmentsCount, VkFo
if (attachmentsCount == 2)
{
- // Depth attachment.
attachments[1].format = depthFormat;
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
- attachments[1].loadOp = depthLoadOp;
- attachments[1].storeOp = depthStoreOp;
- attachments[1].stencilLoadOp = stencilLoadOp;
- attachments[1].stencilStoreOp = stencilStoreOp;
+ attachments[1].loadOp = attachmentsOp.m_depth.m_loadOp;
+ attachments[1].storeOp = attachmentsOp.m_depth.m_storeOp;
+ attachments[1].stencilLoadOp = attachmentsOp.m_stencil.m_loadOp;
+ attachments[1].stencilStoreOp = attachmentsOp.m_stencil.m_storeOp;
attachments[1].initialLayout = depthInitLayout;
attachments[1].finalLayout = depthFinalLayout;
}
@@ -755,7 +862,6 @@ VkRenderPass VulkanBaseContext::CreateRenderPass(uint32_t attachmentsCount, VkFo
subpassDescription.pPreserveAttachments = nullptr;
subpassDescription.pResolveAttachments = nullptr;
- // Subpass dependencies for layout transitions.
std::array<VkSubpassDependency, 2> dependencies = {};
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
@@ -788,118 +894,5 @@ VkRenderPass VulkanBaseContext::CreateRenderPass(uint32_t attachmentsCount, VkFo
return renderPass;
}
-
-void VulkanBaseContext::SetDepthTestEnabled(bool enabled)
-{
- m_pipelineKey.m_depthStencil.SetDepthTestEnabled(enabled);
-}
-
-void VulkanBaseContext::SetDepthTestFunction(TestFunction depthFunction)
-{
- m_pipelineKey.m_depthStencil.SetDepthTestFunction(depthFunction);
-}
-
-void VulkanBaseContext::SetStencilTestEnabled(bool enabled)
-{
- m_pipelineKey.m_depthStencil.SetStencilTestEnabled(enabled);
-}
-
-void VulkanBaseContext::SetStencilFunction(StencilFace face, TestFunction stencilFunction)
-{
- m_pipelineKey.m_depthStencil.SetStencilFunction(face, stencilFunction);
-}
-
-void VulkanBaseContext::SetStencilActions(StencilFace face, StencilAction stencilFailAction,
- StencilAction depthFailAction, StencilAction passAction)
-{
- m_pipelineKey.m_depthStencil.SetStencilActions(face, stencilFailAction, depthFailAction, passAction);
-}
-
-void VulkanBaseContext::SetStencilReferenceValue(uint32_t stencilReferenceValue)
-{
- m_stencilReferenceValue = stencilReferenceValue;
-}
-
-void VulkanBaseContext::SetPrimitiveTopology(VkPrimitiveTopology topology)
-{
- m_pipelineKey.m_primitiveTopology = topology;
-}
-
-void VulkanBaseContext::SetBindingInfo(BindingInfoArray const & bindingInfo, uint8_t bindingInfoCount)
-{
- std::copy(bindingInfo.begin(), bindingInfo.begin() + bindingInfoCount,
- m_pipelineKey.m_bindingInfo.begin());
- m_pipelineKey.m_bindingInfoCount = bindingInfoCount;
-}
-
-void VulkanBaseContext::SetProgram(ref_ptr<VulkanGpuProgram> program)
-{
- m_pipelineKey.m_program = program;
-}
-
-void VulkanBaseContext::SetBlendingEnabled(bool blendingEnabled)
-{
- m_pipelineKey.m_blendingEnabled = blendingEnabled;
-}
-
-void VulkanBaseContext::ApplyParamDescriptor(ParamDescriptor && descriptor)
-{
- if (descriptor.m_type == ParamDescriptor::Type::DynamicUniformBuffer)
- {
- for (auto & param : m_paramDescriptors)
- {
- if (param.m_type == ParamDescriptor::Type::DynamicUniformBuffer)
- {
- param = std::move(descriptor);
- return;
- }
- }
- }
- m_paramDescriptors.push_back(std::move(descriptor));
-}
-
-void VulkanBaseContext::ClearParamDescriptors()
-{
- m_paramDescriptors.clear();
-}
-
-VkPipeline VulkanBaseContext::GetCurrentPipeline()
-{
- return m_pipeline->GetPipeline(m_device, m_pipelineKey);
-}
-
-DescriptorSetGroup VulkanBaseContext::GetCurrentDescriptorSetGroup()
-{
- CHECK(m_pipelineKey.m_program != nullptr, ());
- CHECK(!m_paramDescriptors.empty(), ("Shaders parameters are not set."));
- return m_objectManager->CreateDescriptorSetGroup(m_pipelineKey.m_program, m_paramDescriptors);
-}
-
-VkPipelineLayout VulkanBaseContext::GetCurrentPipelineLayout() const
-{
- CHECK(m_pipelineKey.m_program != nullptr, ());
- return m_pipelineKey.m_program->GetPipelineLayout();
-}
-
-uint32_t VulkanBaseContext::GetCurrentDynamicBufferOffset() const
-{
- for (auto const & p : m_paramDescriptors)
- {
- if (p.m_type == ParamDescriptor::Type::DynamicUniformBuffer)
- return p.m_bufferDynamicOffset;
- }
- CHECK(false, ("Shaders parameters are not set."));
- return 0;
-}
-
-VkSampler VulkanBaseContext::GetSampler(SamplerKey const & key)
-{
- return m_objectManager->GetSampler(key);
-}
-
-ref_ptr<VulkanStagingBuffer> VulkanBaseContext::GetDefaultStagingBuffer() const
-{
- return make_ref(m_defaultStagingBuffer);
-}
} // namespace vulkan
} // namespace dp
diff --git a/drape/vulkan/vulkan_base_context.hpp b/drape/vulkan/vulkan_base_context.hpp
index 4d99c5c8c7..e6877a2d0a 100644
--- a/drape/vulkan/vulkan_base_context.hpp
+++ b/drape/vulkan/vulkan_base_context.hpp
@@ -5,9 +5,11 @@
#include "drape/vulkan/vulkan_gpu_program.hpp"
#include "drape/vulkan/vulkan_object_manager.hpp"
#include "drape/vulkan/vulkan_pipeline.hpp"
+#include "drape/vulkan/vulkan_texture.hpp"
#include "drape/vulkan/vulkan_utils.hpp"
#include "geometry/point2d.hpp"
+#include "vulkan_texture.hpp"
#include <vulkan_wrapper.h>
#include <vulkan/vulkan.h>
@@ -40,7 +42,7 @@ public:
void Present() override;
void MakeCurrent() override {};
void DoneCurrent() override {};
- bool Validate() override;
+ bool Validate() override { return true; }
void Resize(int w, int h) override;
void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override;
void ApplyFramebuffer(std::string const & framebufferLabel) override;
@@ -117,16 +119,31 @@ protected:
void CreateCommandBuffers();
void DestroyCommandBuffers();
- void CreateDepthTexture();
- void DestroyDepthTexture();
+ void CreateSyncPrimitives();
+ void DestroySyncPrimitives();
- VkRenderPass CreateRenderPass(uint32_t attachmentsCount, VkFormat colorFormat,
- VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp,
- VkImageLayout initLayout, VkImageLayout finalLayout,
- VkFormat depthFormat, VkAttachmentLoadOp depthLoadOp,
- VkAttachmentStoreOp depthStoreOp, VkAttachmentLoadOp stencilLoadOp,
- VkAttachmentStoreOp stencilStoreOp, VkImageLayout depthInitLayout,
- VkImageLayout depthFinalLayout);
+ void DestroyFramebuffers();
+
+ void RecreateDepthTexture();
+
+ struct AttachmentOp
+ {
+ VkAttachmentLoadOp m_loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ VkAttachmentStoreOp m_storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ };
+
+ struct AttachmentsOperations
+ {
+ AttachmentOp m_color;
+ AttachmentOp m_depth;
+ AttachmentOp m_stencil;
+ };
+
+ AttachmentsOperations GetAttachmensOperations();
+
+ VkRenderPass CreateRenderPass(uint32_t attachmentsCount, AttachmentsOperations const & attachmentsOp,
+ VkFormat colorFormat, VkImageLayout initLayout, VkImageLayout finalLayout,
+ VkFormat depthFormat, VkImageLayout depthInitLayout, VkImageLayout depthFinalLayout);
VkInstance const m_vulkanInstance;
VkPhysicalDevice const m_gpu;
@@ -159,7 +176,7 @@ protected:
std::vector<VkImage> m_swapchainImages;
uint32_t m_imageIndex = 0;
- VulkanObject m_depthStencil;
+ drape_ptr<VulkanTexture> m_depthTexture;
uint32_t m_clearBits;
uint32_t m_storeBits;
diff --git a/drape/vulkan/vulkan_mesh_object_impl.cpp b/drape/vulkan/vulkan_mesh_object_impl.cpp
index 2128fb4681..09f161ac38 100644
--- a/drape/vulkan/vulkan_mesh_object_impl.cpp
+++ b/drape/vulkan/vulkan_mesh_object_impl.cpp
@@ -82,6 +82,15 @@ public:
m_geometryBuffers.clear();
}
+ void ResetCache(dp::RenderState const & state) override
+ {
+ if (state.GetColorTexture() != m_lastColorTexture)
+ {
+ m_lastColorTexture == state.GetColorTexture();
+ ResetDescriptorSetGroup();
+ }
+ }
+
void UpdateBuffer(ref_ptr<dp::GraphicsContext> context, uint32_t bufferInd) override
{
CHECK_LESS(bufferInd, static_cast<uint32_t>(m_geometryBuffers.size()), ());
@@ -190,6 +199,7 @@ private:
BindingInfoArray m_bindingInfo;
uint8_t m_bindingInfoCount = 0;
DescriptorSetGroup m_descriptorSetGroup;
+ ref_ptr<dp::Texture> m_lastColorTexture;
};
} // namespace vulkan
diff --git a/drape/vulkan/vulkan_pipeline.cpp b/drape/vulkan/vulkan_pipeline.cpp
index a5a3aa6f80..532901bb4b 100644
--- a/drape/vulkan/vulkan_pipeline.cpp
+++ b/drape/vulkan/vulkan_pipeline.cpp
@@ -227,6 +227,14 @@ void VulkanPipeline::Dump(VkDevice device)
}
}
+void VulkanPipeline::ResetCache(VkDevice device)
+{
+ for (auto const & p : m_pipelineCache)
+ vkDestroyPipeline(device, p.second, nullptr);
+ m_pipelineCache.clear();
+ m_isChanged = true;
+}
+
void VulkanPipeline::Destroy(VkDevice device)
{
Dump(device);
diff --git a/drape/vulkan/vulkan_pipeline.hpp b/drape/vulkan/vulkan_pipeline.hpp
index 486705a5e2..40af008e38 100644
--- a/drape/vulkan/vulkan_pipeline.hpp
+++ b/drape/vulkan/vulkan_pipeline.hpp
@@ -52,6 +52,7 @@ public:
VulkanPipeline(VkDevice device, int appVersionCode);
void Dump(VkDevice device);
void Destroy(VkDevice device);
+ void ResetCache(VkDevice device);
VkPipeline GetPipeline(VkDevice device, PipelineKey const & key);
diff --git a/drape/vulkan/vulkan_texture.cpp b/drape/vulkan/vulkan_texture.cpp
index ce67cd8af9..2173c847f3 100644
--- a/drape/vulkan/vulkan_texture.cpp
+++ b/drape/vulkan/vulkan_texture.cpp
@@ -116,14 +116,13 @@ void VulkanTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const &
VkImageAspectFlags const aspect =
params.m_format == TextureFormat::DepthStencil ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
: VK_IMAGE_ASPECT_DEPTH_BIT;
- m_textureObject = m_objectManager->CreateImage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+ m_textureObject = m_objectManager->CreateImage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
format, aspect, params.m_width, params.m_height);
}
else
{
m_textureObject = m_objectManager->CreateImage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
- format,
- VK_IMAGE_ASPECT_COLOR_BIT,
+ format, VK_IMAGE_ASPECT_COLOR_BIT,
params.m_width, params.m_height);
}
}