Ensure empty render instruction doesn't swap buffers 63/320463/5
authorDavid Steele <david.steele@samsung.com>
Mon, 3 Mar 2025 19:00:01 +0000 (19:00 +0000)
committerDavid Steele <david.steele@samsung.com>
Fri, 21 Mar 2025 11:01:35 +0000 (11:01 +0000)
If we aren't going to draw anything to the surface, then
don't acquire next image or render anything.

SwapBuffers is handled through Swapchain::Present, which maintains
it's own framecount; The current buffer index is retrieved from the
main window's swapchain.

Updated VulkanGraphicsController::PresentRenderTarget to also call
WindowSurface::PostRender; this has a load of handling for partial
rendering that we may need in the future.

Will keep rendering framebuffers, regardless of whether they are drawn
or not.

Change-Id: I8e0b2555647e2ce74d425c9632246f19ea295470

dali/integration-api/adaptor-framework/render-surface-interface.h
dali/internal/adaptor/common/combined-update-render-controller.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-buffer.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-buffer.h
dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.cpp
dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.h
dali/internal/graphics/vulkan/vulkan-device.cpp
dali/internal/graphics/vulkan/vulkan-device.h
dali/internal/graphics/vulkan/vulkan-graphics-impl.cpp
dali/internal/window-system/common/window-render-surface.cpp

index 752960697c1a43dda652353ac983bc5720f9bb47..307b46f2711edc40880e07fd7c710bce4bb0bd2c 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTEGRATION_RENDER_SURFACE_INTERFACE_H
 
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -253,6 +253,11 @@ public:
     mFullSwapNextFrame = true;
   }
 
+  bool GetFullSwapNextFrame() const
+  {
+    return mFullSwapNextFrame;
+  }
+
 private:
   /**
    * @brief Undefined copy constructor. RenderSurface cannot be copied
index 8a11eeb54974cc5b1c78fcb87f447198b81ce8db..76b276c854a4855c524d0163413eebf3f64531a7 100644 (file)
@@ -862,7 +862,8 @@ void CombinedUpdateRenderController::UpdateRenderThread()
           mDamagedRects.clear();
 
           // Collect damage rects
-          bool willRender = mCore.PreRender(scene, mDamagedRects);
+          bool willRender = mCore.PreRender(scene, mDamagedRects) || windowSurface->GetFullSwapNextFrame();
+          ;
           if(willRender)
           {
             graphics.AcquireNextImage(windowSurface);
@@ -871,13 +872,16 @@ void CombinedUpdateRenderController::UpdateRenderThread()
           // Render off-screen frame buffers first if any
           mCore.RenderScene(windowRenderStatus, scene, true);
 
-          Rect<int> clippingRect; // Empty for fbo rendering
+          if(willRender)
+          {
+            Rect<int> clippingRect; // Empty for fbo rendering
 
-          // Ensure surface can be drawn to; merge damaged areas for previous frames
-          windowSurface->PreRender(sceneSurfaceResized > 0u, mDamagedRects, clippingRect);
+            // Ensure surface can be drawn to; merge damaged areas for previous frames
+            windowSurface->PreRender(sceneSurfaceResized > 0u, mDamagedRects, clippingRect);
 
-          // Render the surface
-          mCore.RenderScene(windowRenderStatus, scene, false, clippingRect);
+            // Render the surface (Present & SwapBuffers)
+            mCore.RenderScene(windowRenderStatus, scene, false, clippingRect);
+          }
 
           // If surface is resized, the surface resized count is decreased.
           if(DALI_UNLIKELY(sceneSurfaceResized > 0u))
index 471cdde6ef57dc53bffc56116406b9e8ad8f2191..a149fbed66e2fa52ae80f7bf384f4d3d1039cb47 100644 (file)
@@ -85,10 +85,11 @@ void CommandBuffer::Begin(const Graphics::CommandBufferBeginInfo& info)
   mRenderTarget        = ConstGraphicsCast<Vulkan::RenderTarget, Graphics::RenderTarget>(info.renderTarget);
   uint32_t bufferIndex = mController.GetGraphicsDevice().GetCurrentBufferIndex();
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size());
+  DALI_LOG_INFO(gLogCmdBufferFilter, Debug::Verbose, "CommandBuffer::Begin: ptr:%p bufferIndex=%d\n", GetImpl(), bufferIndex);
+  mCmdCount++; // Debug info
 
   if(mCommandBufferImpl[bufferIndex])
   {
-    DALI_LOG_INFO(gLogCmdBufferFilter, Debug::Verbose, "CommandBuffer::Begin: ptr:%p bufferIndex=%d", this, bufferIndex);
     vk::CommandBufferInheritanceInfo inheritanceInfo{};
     if(info.renderPass)
     {
@@ -112,19 +113,22 @@ void CommandBuffer::End()
 {
   uint32_t bufferIndex = mController.GetGraphicsDevice().GetCurrentBufferIndex();
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
+  DALI_LOG_INFO(gLogCmdBufferFilter, Debug::Verbose, "CommandBuffer::End: ptr:%p bufferIndex=%d\n", GetImpl(), bufferIndex);
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->End();
 }
 
 void CommandBuffer::Reset()
 {
   uint32_t bufferIndex = mController.GetGraphicsDevice().GetCurrentBufferIndex();
-  DALI_LOG_INFO(gLogCmdBufferFilter, Debug::Verbose, "CommandBuffer::Reset: ptr:%p bufferIndex=%d", this, bufferIndex);
+  DALI_LOG_INFO(gLogCmdBufferFilter, Debug::Verbose, "CommandBuffer::Reset: ptr:%p bufferIndex=%d", GetImpl(), bufferIndex);
 
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
   mCommandBufferImpl[bufferIndex]->Reset();
 
   mDynamicStateMask = CommandBuffer::INITIAL_DYNAMIC_MASK_VALUE;
   mRenderTarget     = nullptr;
+  mCmdCount         = 1;
 }
 
 void CommandBuffer::BindVertexBuffers(uint32_t                                    firstBinding,
@@ -139,6 +143,7 @@ void CommandBuffer::BindVertexBuffers(uint32_t
     buffers.push_back(ConstGraphicsCast<Buffer, Graphics::Buffer>(gfxBuffer)->GetImpl());
   }
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->BindVertexBuffers(firstBinding, buffers, offsets);
 }
 
@@ -152,6 +157,7 @@ void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& gfxBuffer,
   auto indexBuffer = ConstGraphicsCast<Buffer, Graphics::Buffer>(&gfxBuffer);
   DALI_ASSERT_DEBUG(indexBuffer && indexBuffer->GetImpl());
 
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->BindIndexBuffer(*indexBuffer->GetImpl(), offset, format);
 }
 
@@ -169,6 +175,7 @@ void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
   const uint32_t bufferIndex = mController.GetGraphicsDevice().GetCurrentBufferIndex();
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
 
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->BindPipeline(&pipeline);
 }
 
@@ -179,6 +186,7 @@ void CommandBuffer::BindTextures(const std::vector<TextureBinding>& textureBindi
 
   mCommandBufferImpl[bufferIndex]->BindTextures(textureBindings);
 
+  mCmdCount++; // Debug info
   mController.CheckTextureDependencies(textureBindings, mRenderTarget);
 }
 
@@ -187,6 +195,7 @@ void CommandBuffer::BindSamplers(const std::vector<SamplerBinding>& samplerBindi
   const uint32_t bufferIndex = mController.GetGraphicsDevice().GetCurrentBufferIndex();
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
 
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->BindSamplers(samplerBindings);
 }
 
@@ -246,6 +255,7 @@ void CommandBuffer::BeginRenderPass(Graphics::RenderPass*          gfxRenderPass
     }
   }
 
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->BeginRenderPass(vk::RenderPassBeginInfo{}
                                                      .setFramebuffer(framebuffer->GetVkHandle())
                                                      .setRenderPass(renderPassImpl->GetVkHandle())
@@ -260,6 +270,7 @@ void CommandBuffer::EndRenderPass(Graphics::SyncObject* syncObject)
   const uint32_t bufferIndex = mController.GetGraphicsDevice().GetCurrentBufferIndex();
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
 
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->EndRenderPass();
 }
 
@@ -269,6 +280,7 @@ void CommandBuffer::ReadPixels(uint8_t* buffer)
 
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
 
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->ReadPixels(buffer);
 }
 
@@ -283,6 +295,7 @@ void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuf
   {
     vkCommandBuffers.push_back(ConstGraphicsCast<CommandBuffer, Graphics::CommandBuffer>(gfxCmdBuf)->GetImpl()->GetVkHandle());
   }
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->ExecuteCommandBuffers(vkCommandBuffers);
 }
 
@@ -294,6 +307,7 @@ void CommandBuffer::Draw(uint32_t vertexCount,
   const uint32_t bufferIndex = mController.GetGraphicsDevice().GetCurrentBufferIndex();
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
 
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->Draw(vertexCount, instanceCount, firstVertex, firstInstance);
 }
 
@@ -306,6 +320,7 @@ void CommandBuffer::DrawIndexed(uint32_t indexCount,
   const uint32_t bufferIndex = mController.GetGraphicsDevice().GetCurrentBufferIndex();
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
 
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->DrawIndexed(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
 }
 
@@ -318,6 +333,7 @@ void CommandBuffer::DrawIndexedIndirect(Graphics::Buffer& gfxBuffer,
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
 
   auto buffer = ConstGraphicsCast<Buffer, Graphics::Buffer>(&gfxBuffer)->GetImpl();
+  mCmdCount++; // Debug info
   mCommandBufferImpl[bufferIndex]->DrawIndexedIndirect(*buffer, offset, drawCount, stride);
 }
 
@@ -334,6 +350,7 @@ void CommandBuffer::SetScissor(Rect2D value)
 
   if(SetDynamicState(mDynamicState.scissor, value, DynamicStateMaskBits::SCISSOR))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetScissor(value);
   }
 }
@@ -359,6 +376,7 @@ void CommandBuffer::SetViewport(Viewport value)
 
   if(SetDynamicState(mDynamicState.viewport, correctedValue, DynamicStateMaskBits::VIEWPORT))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetViewport(correctedValue);
   }
 }
@@ -390,6 +408,7 @@ void CommandBuffer::SetStencilTestEnable(bool stencilEnable)
 
   if(SetDynamicState(mDynamicState.stencilTest, stencilEnable, DynamicStateMaskBits::STENCIL_TEST))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetStencilTestEnable(stencilEnable);
   }
 }
@@ -401,6 +420,7 @@ void CommandBuffer::SetStencilWriteMask(uint32_t writeMask)
 
   if(SetDynamicState(mDynamicState.stencilWriteMask, writeMask, DynamicStateMaskBits::STENCIL_WRITE_MASK))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack, writeMask);
   }
 }
@@ -417,10 +437,12 @@ void CommandBuffer::SetStencilState(Graphics::CompareOp compareOp,
 
   if(SetDynamicState(mDynamicState.stencilCompareMask, compareMask, DynamicStateMaskBits::STENCIL_COMP_MASK))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack, compareMask);
   }
   if(SetDynamicState(mDynamicState.stencilReference, reference, DynamicStateMaskBits::STENCIL_REF))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetStencilReference(vk::StencilFaceFlagBits::eFrontAndBack, reference);
   }
 
@@ -429,6 +451,7 @@ void CommandBuffer::SetStencilState(Graphics::CompareOp compareOp,
      SetDynamicState(mDynamicState.stencilDepthFailOp, depthFailOp, DynamicStateMaskBits::STENCIL_OP_DEPTH_FAIL) ||
      SetDynamicState(mDynamicState.stencilCompareOp, compareOp, DynamicStateMaskBits::STENCIL_OP_COMP))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetStencilOp(vk::StencilFaceFlagBits::eFrontAndBack,
                                                   VkStencilOpType(failOp).op,
                                                   VkStencilOpType(passOp).op,
@@ -443,6 +466,7 @@ void CommandBuffer::SetDepthCompareOp(Graphics::CompareOp compareOp)
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
   if(SetDynamicState(mDynamicState.depthCompareOp, compareOp, DynamicStateMaskBits::DEPTH_OP_COMP))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetDepthCompareOp(VkCompareOpType(compareOp).op);
   }
 }
@@ -453,6 +477,7 @@ void CommandBuffer::SetDepthTestEnable(bool depthTestEnable)
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
   if(SetDynamicState(mDynamicState.depthTest, depthTestEnable, DynamicStateMaskBits::DEPTH_TEST))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetDepthTestEnable(depthTestEnable);
   }
 }
@@ -463,6 +488,7 @@ void CommandBuffer::SetDepthWriteEnable(bool depthWriteEnable)
   DALI_ASSERT_ALWAYS(bufferIndex < mCommandBufferImpl.size() && mCommandBufferImpl[bufferIndex]);
   if(SetDynamicState(mDynamicState.depthWrite, depthWriteEnable, DynamicStateMaskBits::DEPTH_WRITE))
   {
+    mCmdCount++; // Debug info
     mCommandBufferImpl[bufferIndex]->SetDepthWriteEnable(depthWriteEnable);
   }
 }
index 9d8916fa87cc486bc32e7e785e03c028fdeb9c00..99a091484905b98a08f3c4beffec52e16b61dd67 100644 (file)
@@ -423,6 +423,7 @@ private:
   std::vector<CommandBufferImpl*> mCommandBufferImpl; ///< There are as many elements as there are swapchain images
   RenderTarget*                   mRenderTarget{nullptr};
   Swapchain*                      mLastSwapchain{nullptr};
+  uint32_t                        mCmdCount{0u};
 };
 
 } // namespace Dali::Graphics::Vulkan
index dc908ad3557347d0fcb617cafc91caa655b6851b..947aaa5abf0c489f055e80b5957ba8d4d384d100 100644 (file)
@@ -220,8 +220,7 @@ struct VulkanGraphicsController::Impl
     if(!mTextureStagingBuffer ||
        mTextureStagingBuffer->GetImpl()->GetSize() < size)
     {
-      auto workerFunc = [&, size](auto workerIndex)
-      {
+      auto workerFunc = [&, size](auto workerIndex) {
         Graphics::BufferCreateInfo createInfo{};
         createInfo.SetSize(size)
           .SetUsage(0u | Dali::Graphics::BufferUsage::TRANSFER_SRC);
@@ -311,8 +310,7 @@ struct VulkanGraphicsController::Impl
         }
         assert(image);
 
-        auto predicate = [&](auto& item) -> bool
-        {
+        auto predicate = [&](auto& item) -> bool {
           return image->GetVkHandle() == item.image.GetVkHandle();
         };
         auto it = std::find_if(requestMap.begin(), requestMap.end(), predicate);
@@ -531,8 +529,9 @@ Integration::GraphicsConfig& VulkanGraphicsController::GetGraphicsConfig()
 void VulkanGraphicsController::FrameStart()
 {
   mImpl->mDependencyChecker.Reset(); // Clean down the dependency graph.
-
   mImpl->mCapacity = 0;
+
+  DALI_LOG_INFO(gVulkanFilter, Debug::Verbose, "FrameStart: bufferIndex:%u\n", mImpl->mGraphicsDevice->GetCurrentBufferIndex());
   // Check the size of the discard queues.
   auto bufferCount = mImpl->mGraphicsDevice->GetBufferCount();
   mImpl->mDiscardQueues.Resize(bufferCount);
@@ -559,6 +558,7 @@ void VulkanGraphicsController::SetResourceBindingHints(const std::vector<SceneRe
 void VulkanGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo)
 {
   std::vector<SubmissionData> submitData;
+  DALI_LOG_INFO(gVulkanFilter, Debug::Verbose, "SubmitCommandBuffers() bufferIndex:%d\n", mImpl->mGraphicsDevice->GetCurrentBufferIndex());
 
   // Gather all command buffers targeting frame buffers into a single Submit request
   for(auto gfxCmdBuffer : submitInfo.cmdBuffer)
@@ -568,10 +568,14 @@ void VulkanGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo
     DALI_ASSERT_DEBUG(renderTarget && "Cmd buffer has no render target set.");
     if(renderTarget && renderTarget->GetSurface() == nullptr)
     {
+      DALI_LOG_INFO(gVulkanFilter, Debug::Verbose, "CreateSubmissionData: FBO CmdBuffer:%p\n", cmdBuffer->GetImpl());
       renderTarget->CreateSubmissionData(cmdBuffer, submitData);
     }
   }
-  mImpl->mGraphicsDevice->GetGraphicsQueue(0).Submit(submitData, nullptr);
+  if(!submitData.empty())
+  {
+    mImpl->mGraphicsDevice->GetGraphicsQueue(0).Submit(submitData, nullptr);
+  }
 
   // Submit each scene's cmd buffer separately, as these use EndOfFrameFence.
   for(auto gfxCmdBuffer : submitInfo.cmdBuffer)
@@ -586,6 +590,7 @@ void VulkanGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo
       auto surfaceId = static_cast<Internal::Adaptor::WindowRenderSurface*>(surface)->GetSurfaceId();
       auto swapchain = GetGraphicsDevice().GetSwapchainForSurfaceId(surfaceId);
 
+      DALI_LOG_INFO(gVulkanFilter, Debug::Verbose, "CreateSubmissionData: Surface CmdBuffer:%p\n", cmdBuffer->GetImpl());
       renderTarget->CreateSubmissionData(cmdBuffer, submitData);
       swapchain->GetQueue()->Submit(submitData, swapchain->GetEndOfFrameFence());
     }
@@ -600,11 +605,12 @@ void VulkanGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo
 
 void VulkanGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget)
 {
-  if(const auto surface = static_cast<Vulkan::RenderTarget*>(renderTarget)->GetSurface())
+  if(auto surface = static_cast<Vulkan::RenderTarget*>(renderTarget)->GetSurface())
   {
     const auto surfaceId = static_cast<Internal::Adaptor::WindowRenderSurface*>(surface)->GetSurfaceId();
     auto       swapchain = mImpl->mGraphicsDevice->GetSwapchainForSurfaceId(surfaceId);
     swapchain->Present();
+    surface->PostRender();
   }
   // else no presentation required for framebuffer render target.
 }
@@ -714,8 +720,7 @@ void VulkanGraphicsController::UpdateTextures(
 
         if(destTexture->GetProperties().directWriteAccessEnabled)
         {
-          auto taskLambda = [pInfo, sourcePtr, sourceInfoPtr, texture](auto workerIndex)
-          {
+          auto taskLambda = [pInfo, sourcePtr, sourceInfoPtr, texture](auto workerIndex) {
             const auto& properties = texture->GetProperties();
 
             if(properties.emulated)
@@ -750,8 +755,7 @@ void VulkanGraphicsController::UpdateTextures(
           // The staging buffer is not allocated yet. The task knows pointer to the pointer which will point
           // at staging buffer right before executing tasks. The function will either perform direct copy
           // or will do suitable conversion if source format isn't supported and emulation is available.
-          auto taskLambda = [ppStagingMemory, currentOffset, pInfo, sourcePtr, texture](auto workerThread)
-          {
+          auto taskLambda = [ppStagingMemory, currentOffset, pInfo, sourcePtr, texture](auto workerThread) {
             char* pStagingMemory = reinterpret_cast<char*>(*ppStagingMemory);
 
             // Try to initialise` texture resources explicitly if they are not yet initialised
@@ -789,8 +793,7 @@ void VulkanGraphicsController::UpdateTextures(
   for(auto& item : updateMap)
   {
     auto pUpdates = &item.second;
-    auto task     = [pUpdates](auto workerIndex)
-    {
+    auto task     = [pUpdates](auto workerIndex) {
       for(auto& update : *pUpdates)
       {
         update.copyTask(workerIndex);
index 6fab50ecdf1f755d8d48d8caa89b926fe10339ec..bc5b2cc1fbdb24929cb847913011fd3082bbcae1 100644 (file)
@@ -33,7 +33,6 @@ extern Debug::Filter* gVulkanFilter;
 
 namespace Dali::Graphics::Vulkan
 {
-
 /**
  * SwapchainBuffer stores all per-buffer data
  */
@@ -162,8 +161,7 @@ void Swapchain::CreateVkSwapchain(
   auto presentModes = surface->GetSurfacePresentModes();
   auto found        = std::find_if(presentModes.begin(),
                             presentModes.end(),
-                            [&](vk::PresentModeKHR mode)
-                            {
+                            [&](vk::PresentModeKHR mode) {
                               return presentMode == mode;
                             });
 
@@ -270,8 +268,7 @@ void Swapchain::CreateFramebuffers(FramebufferAttachmentHandle depthAttachment)
                            depthAttachment,
                            mSwapchainCreateInfoKHR.imageExtent.width,
                            mSwapchainCreateInfoKHR.imageExtent.height),
-      [](FramebufferImpl* framebuffer1)
-      {
+      [](FramebufferImpl* framebuffer1) {
         framebuffer1->Destroy();
         delete framebuffer1;
       });
@@ -306,7 +303,7 @@ FramebufferImpl* Swapchain::AcquireNextFramebuffer(bool shouldCollectGarbageNow)
   // prevent from using invalid swapchain
   if(!mIsValid)
   {
-    DALI_LOG_INFO(gVulkanFilter, Debug::General, "Attempt to present invalid/expired swapchain: %p\n", static_cast<VkSwapchainKHR>(mSwapchainKHR));
+    DALI_LOG_INFO(gVulkanFilter, Debug::General, "Attempt to acquire from invalid/expired swapchain: %p\n", static_cast<VkSwapchainKHR>(mSwapchainKHR));
     return nullptr;
   }
 
@@ -326,7 +323,7 @@ FramebufferImpl* Swapchain::AcquireNextFramebuffer(bool shouldCollectGarbageNow)
 
   constexpr auto TIMEOUT = 1'000'000'000; //'
 
-  auto& swapchainBuffer = mSwapchainBuffers[mGraphicsDevice.GetCurrentBufferIndex()];
+  auto& swapchainBuffer = mSwapchainBuffers[GetCurrentBufferIndex()];
 
   // First frames don't need waiting as they haven't been submitted
   // yet. Note, that waiting on the fence without resetting it may
@@ -382,7 +379,7 @@ Queue* Swapchain::GetQueue()
 
 FenceImpl* Swapchain::GetEndOfFrameFence()
 {
-  auto& swapchainBuffer = mSwapchainBuffers[mGraphicsDevice.GetCurrentBufferIndex()];
+  auto& swapchainBuffer = mSwapchainBuffers[GetCurrentBufferIndex()];
   return swapchainBuffer->endOfFrameFence.get();
 }
 
@@ -392,7 +389,7 @@ void Swapchain::CreateSubmissionData(
   std::vector<vk::PipelineStageFlags>& waitDstStageMask,
   std::vector<SubmissionData>&         submissionData)
 {
-  auto& swapchainBuffer = mSwapchainBuffers[mGraphicsDevice.GetCurrentBufferIndex()];
+  auto& swapchainBuffer = mSwapchainBuffers[GetCurrentBufferIndex()];
 
   swapchainBuffer->endOfFrameFence->Reset();
   swapchainBuffer->submitted = true;
@@ -403,6 +400,11 @@ void Swapchain::CreateSubmissionData(
   submissionData.emplace_back(SubmissionData{waitSemaphores, waitDstStageMask, {commandBuffer}, {swapchainBuffer->submitSemaphore}});
 }
 
+uint32_t Swapchain::GetCurrentBufferIndex() const
+{
+  return mSwapchainBuffers.empty() ? 0 : mFrameCounter % mSwapchainBuffers.size();
+}
+
 void Swapchain::Present()
 {
   // prevent from using invalid swapchain
@@ -411,7 +413,9 @@ void Swapchain::Present()
     return;
   }
 
-  auto& swapchainBuffer = mSwapchainBuffers[mGraphicsDevice.GetCurrentBufferIndex()];
+  auto& swapchainBuffer = mSwapchainBuffers[GetCurrentBufferIndex()];
+
+  DALI_LOG_INFO(gVulkanFilter, Debug::Verbose, "Vulkan::Swapchain::Present() work submitted:%s\n", swapchainBuffer->submitted ? "True" : "False");
 
   // Only present if we've submitted work
   if(swapchainBuffer->submitted)
index 222cf474ef2e57620da9b490f761719d3a409052..c334833840cc07778b0bd6b5b5fdc88c4baf7c89 100644 (file)
@@ -157,6 +157,8 @@ public:
     return mSurface;
   }
 
+  [[nodiscard]] uint32_t GetCurrentBufferIndex() const;
+
 private:
   void CreateVkSwapchain(
     vk::SwapchainKHR   oldSwapchain,
@@ -170,8 +172,6 @@ private:
   Queue*       mQueue;
   SurfaceImpl* mSurface{};
 
-  uint32_t mSwapchainImageIndex{}; ///< Swapchain image index returned by vkAcquireNextImageKHR
-
   vk::SwapchainKHR           mSwapchainKHR;
   vk::SwapchainCreateInfoKHR mSwapchainCreateInfoKHR{};
 
@@ -187,7 +187,8 @@ private:
    * Array of swapchain buffers
    */
   std::vector<std::unique_ptr<SwapchainBuffer>> mSwapchainBuffers;
-  uint32_t                                      mFrameCounter{0u}; ///< Current frame number
+  uint32_t                                      mFrameCounter{0u};      ///< Current frame number
+  uint32_t                                      mSwapchainImageIndex{}; ///< Swapchain image index returned by vkAcquireNextImageKHR
 
   bool mIsValid; // indicates whether the swapchain is still valid or requires to be recreated
 };
index 5d861ced70f95d437b49e80dffa5348ee7f5486e..f327aeed7b4bef2a460b0ccb9e040ae8071ec2a4 100644 (file)
@@ -100,7 +100,6 @@ Device::~Device()
   }
   mSurfaceMap.clear();
 
-  SwapBuffers();
   ReleaseCommandPools();
 
   if(mVmaAllocator)
@@ -620,7 +619,13 @@ void Device::SurfaceResized(unsigned int width, unsigned int height)
 
 uint32_t Device::GetCurrentBufferIndex() const
 {
-  return mCurrentBufferIndex;
+  uint32_t bufferIndex = 0;
+  if(!mSurfaceMap.empty())
+  {
+    // Use the main window's buffer index.
+    bufferIndex = mSurfaceMap.begin()->second.swapchain->GetCurrentBufferIndex();
+  }
+  return bufferIndex;
 }
 
 uint32_t Device::GetBufferCount() const
@@ -628,13 +633,6 @@ uint32_t Device::GetBufferCount() const
   return mBufferCount;
 }
 
-uint32_t Device::SwapBuffers()
-{
-  // Increase the current buffer index. This should match the number of swapchain images in the main window.
-  mCurrentBufferIndex = (mCurrentBufferIndex + 1) % mBufferCount;
-  return mCurrentBufferIndex;
-}
-
 void Device::CreateInstance(const std::vector<const char*>& extensions,
                             const std::vector<const char*>& validationLayers)
 {
index a15f51a0aa9d91411d05b6d735943f591914df98..f22753c5f15992c501b14bf9a34d5ec9b364b4ba 100644 (file)
@@ -133,8 +133,6 @@ public: // Getters
 
   uint32_t GetBufferCount() const;
 
-  uint32_t SwapBuffers();
-
   const vk::PhysicalDeviceMemoryProperties& GetMemoryProperties() const
   {
     return mPhysicalDeviceMemoryProperties;
@@ -194,7 +192,6 @@ private: // Members
   Graphics::SurfaceId                                           mBaseSurfaceId{0u};
 
   Platform   mPlatform{Platform::UNDEFINED};
-  uint32_t   mCurrentBufferIndex{0u};
   uint32_t   mBufferCount{2};
   std::mutex mMutex;
 
index aea6dd5a2669707f03b4e3ad750224b59a874e88..724178a1a657686d4469b12fb762f3f7876324da 100644 (file)
@@ -129,7 +129,6 @@ void VulkanGraphics::AcquireNextImage(Integration::RenderSurfaceInterface* surfa
 
 void VulkanGraphics::PostRender()
 {
-  mGraphicsDevice.SwapBuffers();
 }
 
 void VulkanGraphics::Shutdown()
@@ -167,12 +166,10 @@ void VulkanGraphics::SetDamageRegion(Graphics::SurfaceId, std::vector<Rect<int>>
 
 void VulkanGraphics::SwapBuffers(Graphics::SurfaceId surfaceId)
 {
-  // Swapchain update comes from a different place in Vulkan backend
 }
 
 void VulkanGraphics::SwapBuffers(Graphics::SurfaceId surfaceId, const std::vector<Rect<int>>& damageRects)
 {
-  // Swapchain update comes from a different place in Vulkan backend
 }
 
 Dali::Graphics::Controller& VulkanGraphics::GetController()
index 8ea6f1c22754a5dc90c1064d87d5ee7ff6d96067..842aaa57286904c40d2897c3b229198161e63e70 100644 (file)
@@ -775,8 +775,7 @@ void WindowRenderSurface::OnFileDescriptorEventDispatched(FileDescriptorMonitor:
   {
     Dali::Mutex::ScopedLock lock(mMutex);
 
-    auto frameCallbackInfo = std::find_if(mFrameCallbackInfoContainer.begin(), mFrameCallbackInfoContainer.end(), [fileDescriptor](std::unique_ptr<FrameCallbackInfo>& callbackInfo)
-                                          { return callbackInfo->fileDescriptor == fileDescriptor; });
+    auto frameCallbackInfo = std::find_if(mFrameCallbackInfoContainer.begin(), mFrameCallbackInfoContainer.end(), [fileDescriptor](std::unique_ptr<FrameCallbackInfo>& callbackInfo) { return callbackInfo->fileDescriptor == fileDescriptor; });
     if(frameCallbackInfo != mFrameCallbackInfoContainer.end())
     {
       callbackInfo = std::move(*frameCallbackInfo);
@@ -893,8 +892,6 @@ void WindowRenderSurface::SetBufferDamagedRects(const std::vector<Rect<int>>& da
 
 void WindowRenderSurface::SwapBuffers(const std::vector<Rect<int>>& damagedRects)
 {
-  // @todo Need to do this differently as Vulkan does not need this; it's only required for GLES
-
   if(Integration::PartialUpdateAvailable::FALSE == mGraphics->GetPartialUpdateRequired() ||
      mFullSwapNextFrame)
   {