// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Graphics/GPUSwapChain.h" #include "GPUDeviceVulkan.h" #include "GPUTextureVulkan.h" #if GRAPHICS_API_VULKAN /// /// Represents a Vulkan swap chain back buffer wrapper object. /// class BackBufferVulkan : public ResourceOwnerVulkan { public: /// /// The device. /// GPUDeviceVulkan* Device; /// /// The image acquired semaphore handle. /// SemaphoreVulkan* ImageAcquiredSemaphore; /// /// The rendering done semaphore handle. /// SemaphoreVulkan* RenderingDoneSemaphore; /// /// The render target surface handle. /// GPUTextureViewVulkan Handle; public: void Setup(GPUSwapChainVulkan* window, VkImage backbuffer, PixelFormat format, VkExtent3D extent); void Release(); public: // [ResourceOwnerVulkan] GPUResource* AsGPUResource() const override { return nullptr; } }; /// /// Window swap chain for Vulkan backend. /// class GPUSwapChainVulkan : public GPUResourceVulkan, public ResourceOwnerVulkan { friend class GPUContextVulkan; friend GPUDeviceVulkan; private: VkSurfaceKHR _surface; VkSwapchainKHR _swapChain; int32 _currentImageIndex; int32 _semaphoreIndex; int32 _acquiredImageIndex; Array> _backBuffers; SemaphoreVulkan* _acquiredSemaphore; public: GPUSwapChainVulkan(GPUDeviceVulkan* device, Window* window); public: /// /// Gets the Vulkan surface. /// /// The surface object. FORCE_INLINE VkSurfaceKHR GetSurface() const { return _surface; } /// /// Gets the Vulkan surface swap chain. /// /// The swap chain object. FORCE_INLINE VkSwapchainKHR GetSwapChain() const { return _swapChain; } public: enum class Status { Ok = 0, Outdated = -1, LostSurface = -2, }; Status Present(QueueVulkan* presentQueue, SemaphoreVulkan* backBufferRenderingDoneSemaphore); static int32 DoAcquireImageIndex(GPUSwapChainVulkan* viewport, void* customData); static int32 DoPresent(GPUSwapChainVulkan* viewport, void* customData); int32 TryPresent(Function job, void* customData = nullptr, bool skipOnOutOfDate = false); int32 AcquireNextImage(SemaphoreVulkan** outSemaphore); private: void ReleaseBackBuffer(); bool CreateSwapChain(int32 width, int32 height); public: // [GPUSwapChain] bool IsFullscreen() override; void SetFullscreen(bool isFullscreen) override; GPUTextureView* GetBackBufferView() override; void Present(bool vsync) override; bool Resize(int32 width, int32 height) override; void CopyBackbuffer(GPUContext* context, GPUTexture* dst) override; // [ResourceOwnerVulkan] GPUResource* AsGPUResource() const override { return (GPUResource*)this; } protected: // [GPUResourceVulkan] void OnReleaseGPU() override; }; #endif