!B (CE-16353) (Vulkan) Fixes the gamelauncher crash on start. It was crashing since...
[CRYENGINE.git] / Code / CryEngine / RenderDll / XRenderD3D9 / Vulkan / API / VKSwapChain.hpp
blob3ca40b4d32f3f43198fde3454993d7f44795ba43
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #pragma once
5 #include "VKBase.hpp"
6 #include "VKCommandList.hpp"
7 #include "VKAsyncCommandQueue.hpp"
8 #include "VKDevice.hpp"
9 #include "VKImageResource.hpp"
11 namespace NCryVulkan
14 class CSwapChain : public CRefCounted
16 static bool GetSupportedSurfaceFormats(VkPhysicalDevice& physicalDevice, VkSurfaceKHR& surface, std::vector<VkSurfaceFormatKHR>& outFormatsSupported);
17 static bool GetSupportedPresentModes(VkPhysicalDevice& physicalDevice, VkSurfaceKHR& surface, std::vector<VkPresentModeKHR>& outPresentModes);
19 public:
20 static _smart_ptr<CSwapChain> Create(CCommandListPool& commandQueue, VkSwapchainKHR KHRSwapChain, uint32_t numberOfBuffers, uint32_t width, uint32_t height, VkSurfaceKHR surface, VkFormat format, VkPresentModeKHR presentMode, VkImageUsageFlags imageUsage);
21 static _smart_ptr<CSwapChain> Create(CCommandListPool& commandQueue, VkSwapchainKHR KHRSwapChain, uint32_t numberOfBuffers, uint32_t width, uint32_t height, VkSurfaceKHR surface, VkFormat format, VkPresentModeKHR presentMode, VkImageUsageFlags imageUsage, VkSurfaceTransformFlagBitsKHR transform);
22 static _smart_ptr<CSwapChain> Create(CCommandListPool& commandQueue, VkSwapchainCreateInfoKHR* pInfo);
24 protected:
25 CSwapChain(CCommandListPool& commandQueue, VkSurfaceKHR KHRSurface, VkSwapchainKHR KHRSwapChain, VkSwapchainCreateInfoKHR* pInfo);
27 virtual ~CSwapChain();
29 public:
30 ILINE VkSwapchainKHR GetKHRSwapChain() const
32 return m_KHRSwapChain;
35 ILINE VkSurfaceKHR GetKHRSurface() const
37 return m_KHRSurface;
40 ILINE const VkSwapchainCreateInfoKHR& GetKHRSwapChainInfo() const
42 return m_Info;
45 ILINE UINT GetBackBufferCount() const
47 return m_NumBackbuffers;
50 // Get the index of the back-buffer which is to be used for the next Present().
51 // Cache the value for multiple calls between Present()s, as vkAcquireNextImageKHR() will always increment the counter regardless if flips occured.
52 ILINE UINT GetCurrentBackbufferIndex() const
54 if (!m_bChangedBackBufferIndex)
55 return m_nCurrentBackBufferIndex;
57 // Pick a semaphore from the ring-buffer ...
58 auto* const pFence = m_presentFence.GetFence();
59 VkSemaphore Semaphore = pFence->second[m_semaphoreIndex++ % pFence->second.size()];
61 m_asyncQueue.FlushNextPresent(); VK_ASSERT(!IsPresentScheduled(), "Flush didn't dry out all outstanding Present() calls!");
62 VkResult result = vkAcquireNextImageKHR(m_pDevice->GetVkDevice(), m_KHRSwapChain, ~0ULL, Semaphore, VK_NULL_HANDLE, &m_nCurrentBackBufferIndex);
63 VK_ASSERT(result == VK_SUCCESS);
64 m_bChangedBackBufferIndex = false;
66 // ... and inject it as sync-primitive into the core-command-list - which is the one active at the moment of this call (which can be mid-frame)
67 // Adding the semaphore will make the command-list submit even if there are no commands in it, because semaphores can not set/reset from CPU side.
68 m_pDevice->GetScheduler().GetCommandList(CMDQUEUE_GRAPHICS)->WaitForFinishOnGPU(Semaphore);
70 return m_nCurrentBackBufferIndex;
72 ILINE CImageResource& GetBackBuffer(UINT index)
74 return m_BackBuffers[index];
76 ILINE CImageResource& GetCurrentBackBuffer()
78 return m_BackBuffers[GetCurrentBackbufferIndex()];
81 ILINE bool IsPresentScheduled() const
83 return m_asyncQueue.GetQueuedFramesCount() > 0;
86 // Run Present() asynchronuously, which means the next back-buffer index is not queryable within this function.
87 // Instead defer acquiring the next index to the next call of GetCurrentBackbufferIndex().
88 void Present(UINT SyncInterval, UINT Flags, VkSemaphore sem)
90 m_asyncQueue.Present(m_KHRSwapChain, GetCurrentBackbufferIndex(), 1, &sem, &m_presentResult);
91 m_bChangedBackBufferIndex = true;
94 VkResult GetLastPresentReturnValue() { return m_presentResult; }
96 // VkResult ResizeTarget(const DXGI_MODE_DESC* pNewTargetParameters);
97 // VkResult ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
99 void AcquireBuffers();
100 void UnblockBuffers(CCommandList* pCommandList);
101 void VerifyBufferCounters();
102 void ForfeitBuffers();
104 private:
105 CDevice* m_pDevice;
106 CAsyncCommandQueue& m_asyncQueue;
107 CCommandListPool& m_pCommandQueue;
108 CCommandListFence m_presentFence;
110 VkSwapchainCreateInfoKHR m_Info;
111 uint32_t m_NumBackbuffers;
112 mutable bool m_bChangedBackBufferIndex;
113 mutable uint32_t m_nCurrentBackBufferIndex;
114 mutable uint32_t m_semaphoreIndex = 0;
116 VkResult m_presentResult;
117 VkSurfaceKHR m_KHRSurface;
118 VkSwapchainKHR m_KHRSwapChain;
120 std::vector<CImageResource> m_BackBuffers;