// 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