namespace Dali::Graphics::Vulkan
{
-namespace
-{
-const auto MAX_SWAPCHAIN_RESOURCE_BUFFERS = 2u;
-}
/**
* SwapchainBuffer stores all per-buffer data
// Determine the number of images
if(surfaceCapabilities.minImageCount > 0 &&
- bufferCount > surfaceCapabilities.minImageCount)
+ bufferCount != surfaceCapabilities.minImageCount)
{
bufferCount = surfaceCapabilities.minImageCount;
}
auto presentModes = surface->GetSurfacePresentModes();
auto found = std::find_if(presentModes.begin(),
presentModes.end(),
- [&](vk::PresentModeKHR mode) {
+ [&](vk::PresentModeKHR mode)
+ {
return presentMode == mode;
});
depthAttachment,
mSwapchainCreateInfoKHR.imageExtent.width,
mSwapchainCreateInfoKHR.imageExtent.height),
- [](FramebufferImpl* framebuffer1) {
+ [](FramebufferImpl* framebuffer1)
+ {
framebuffer1->Destroy();
delete framebuffer1;
});
// on swapchain first create sync primitives if not created yet
if(mSwapchainBuffers.empty())
{
- mSwapchainBuffers.resize(MAX_SWAPCHAIN_RESOURCE_BUFFERS);
+ mSwapchainBuffers.resize(mSwapchainImages.size());
for(auto& buffer : mSwapchainBuffers)
{
buffer.reset(new SwapchainBuffer(mGraphicsDevice));
}
}
-Swapchain* Device::CreateSwapchainForSurface(SurfaceImpl* surface)
+void Device::CreateSwapchainForSurface(SurfaceId surfaceId)
{
- DALI_ASSERT_DEBUG(surface && "Surface ptr must be allocated");
-
- auto surfaceCapabilities = surface->GetCapabilities();
-
- // TODO: propagate the format and presentation mode to higher layers to allow for more control?
- // @todo - for instance, Graphics::RenderTargetCreateInfo?!
- Swapchain* swapchain = CreateSwapchain(surface,
- vk::Format::eB8G8R8A8Unorm,
- vk::PresentModeKHR::eFifo,
- surfaceCapabilities.minImageCount,
- nullptr);
-
// store swapchain in the correct pair
- for(auto&& val : mSurfaceMap)
+ if(auto match = mSurfaceMap.find(surfaceId); match != mSurfaceMap.end())
{
- if(val.second.surface == surface)
- {
- val.second.swapchain = swapchain;
- break;
- }
+ match->second.swapchain = CreateSwapchain(match->second.surface,
+ vk::Format::eB8G8R8A8Unorm,
+ vk::PresentModeKHR::eFifo,
+ nullptr);
+ }
+ else
+ {
+ DALI_LOG_ERROR("Can't find surface: %d\n", surfaceId);
}
-
- return swapchain;
}
-Swapchain* Device::ReplaceSwapchainForSurface(SurfaceImpl* surface, Swapchain*&& oldSwapchain)
+Swapchain* Device::ReplaceSwapchainForSurface(SurfaceId surfaceId, Swapchain*&& oldSwapchain)
{
- auto surfaceCapabilities = surface->GetCapabilities();
-
- mSurfaceResized = false;
-
- auto swapchain = CreateSwapchain(surface,
- vk::Format::eB8G8R8A8Unorm,
- vk::PresentModeKHR::eFifo,
- surfaceCapabilities.minImageCount,
- std::move(oldSwapchain));
-
- // store swapchain in the correct pair
- for(auto&& val : mSurfaceMap)
+ if(auto match = mSurfaceMap.find(surfaceId); match != mSurfaceMap.end())
{
- if(val.second.surface == surface)
- {
- val.second.swapchain = swapchain;
- break;
- }
+ mSurfaceResized = false;
+ match->second.swapchain = CreateSwapchain(match->second.surface,
+ vk::Format::eB8G8R8A8Unorm,
+ vk::PresentModeKHR::eFifo,
+ std::move(oldSwapchain));
+ return match->second.swapchain;
}
- return swapchain;
+ DALI_LOG_ERROR("Can't find surface: %d\n", surfaceId);
+ return nullptr;
}
Swapchain* Device::CreateSwapchain(SurfaceImpl* surface,
vk::Format requestedFormat,
vk::PresentModeKHR presentMode,
- uint32_t& bufferCount,
Swapchain*&& oldSwapchain)
{
auto newSwapchain = Swapchain::NewSwapchain(*this, GetPresentQueue(), oldSwapchain ? oldSwapchain->GetVkHandle() : nullptr, surface, requestedFormat, presentMode, mBufferCount);
if(oldSwapchain)
{
- // prevent destroying the swapchain as it is handled automatically
- // during replacing the swapchain
auto khr = oldSwapchain->GetVkHandle();
oldSwapchain->SetVkHandle(nullptr);
oldSwapchain->Destroy();
mLogicalDevice.destroySwapchainKHR(khr, *mAllocator);
}
- // @todo: Only create framebuffers if no "external" render passes.
FramebufferAttachmentHandle empty;
newSwapchain->CreateFramebuffers(empty); // Note, this may destroy vk swapchain if invalid.
return newSwapchain;
DeviceWaitIdle();
// replace swapchain (only once)
- swapchain = ReplaceSwapchainForSurface(swapchain->GetSurface(), std::move(swapchain));
-
+ swapchain = ReplaceSwapchainForSurface(surfaceId, std::move(swapchain));
// get new valid framebuffer
if(swapchain)
{
.setMipLevels(1);
return new Image(*this, imageCreateInfo, externalImage);
-
- return nullptr;
}
// -------------------------------------------------------------------------------------------------------
{
if(surfaceId == 0)
{
- return mSurfaceMap.begin()
- ->second
- .swapchain;
+ return mSurfaceMap.begin()->second.swapchain;
}
return mSurfaceMap[surfaceId].swapchain;
}
void DestroySurface(Dali::Graphics::SurfaceId surfaceId);
- Swapchain* CreateSwapchainForSurface(SurfaceImpl* surface);
+ void CreateSwapchainForSurface(Dali::Graphics::SurfaceId surfaceId);
- Swapchain* ReplaceSwapchainForSurface(SurfaceImpl* surface, Swapchain*&& oldSwapchain);
-
- Swapchain* CreateSwapchain(SurfaceImpl* surface, vk::Format requestedFormat, vk::PresentModeKHR presentMode, uint32_t& bufferCount, Swapchain*&& oldSwapchain);
+ Swapchain* ReplaceSwapchainForSurface(Dali::Graphics::SurfaceId surfaceId, Swapchain*&& oldSwapchain);
/**
* Ensures that the next available image is retrieved for drawing onto.
void ReleaseCommandPools();
+ Swapchain* CreateSwapchain(SurfaceImpl* surface, vk::Format requestedFormat, vk::PresentModeKHR presentMode, Swapchain*&& oldSwapchain);
+
private: // Members
vk::PhysicalDevice mPhysicalDevice;
vk::Device mLogicalDevice;