You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.h

126 lines
5.5 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/RHI/SwapChain.h>
#include <Atom/RHI.Reflect/SwapChainDescriptor.h>
#include <AzCore/std/containers/list.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/utils.h>
#include <RHI/Semaphore.h>
#include <RHI/Image.h>
#include <RHI/ImageView.h>
#include <RHI/Framebuffer.h>
#include <RHI/RenderPass.h>
#include <RHI/WSISurface.h>
namespace AZ
{
namespace Vulkan
{
class Device;
class CommandQueue;
class SwapChain final
: public RHI::SwapChain
{
using Base = RHI::SwapChain;
public:
AZ_CLASS_ALLOCATOR(SwapChain, AZ::SystemAllocator, 0);
AZ_RTTI(SwapChain, "4AE7AE82-BB25-4665-BF79-85F407255B26", Base);
struct FrameContext
{
Semaphore* m_imageAvailableSemaphore = nullptr;
Semaphore* m_presentableSemaphore = nullptr;
};
static RHI::Ptr<SwapChain> Create();
~SwapChain() = default;
VkSwapchainKHR GetNativeSwapChain() const;
const FrameContext& GetCurrentFrameContext() const;
const WSISurface& GetSurface() const;
const CommandQueue& GetPresentationQueue() const;
void QueueBarrier(const VkPipelineStageFlags src, const VkPipelineStageFlags dst, const VkImageMemoryBarrier& imageBarrier);
void ProcessRecreation() override;
private:
SwapChain() = default;
//////////////////////////////////////////////////////////////////////////
// RHI::Object
void SetNameInternal(const AZStd::string_view& name) override;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// RHI::SwapChain
RHI::ResultCode InitInternal(RHI::Device& device, const RHI::SwapChainDescriptor& descriptor, RHI::SwapChainDimensions* nativeDimensions) override;
void ShutdownInternal() override;
RHI::ResultCode InitImageInternal(const RHI::SwapChain::InitImageRequest& request) override;
RHI::ResultCode ResizeInternal(const RHI::SwapChainDimensions& dimensions, RHI::SwapChainDimensions* nativeDimensions) override;
uint32_t PresentInternal() override;
void SetVerticalSyncIntervalInternal(uint32_t previousVsyncInterval) override;
//////////////////////////////////////////////////////////////////////
RHI::ResultCode BuildSurface(const RHI::SwapChainDescriptor& descriptor);
//! Returns true is the swapchain dimensions are supported by the current surface.
bool ValidateSurfaceDimensions(const RHI::SwapChainDimensions& dimensions);
//! Returns the corresponding Vulkan format that is supported by the surface.
//! If such format is not found, return the first supported format from the surface.
VkSurfaceFormatKHR GetSupportedSurfaceFormat(const RHI::Format format) const;
//! Returns the correct presentation mode.
//! If verticalSyncInterval is non-zero, returns VK_PRESENT_MODE_FIFO_KHR.
//! Otherwise, choose preferred mode if they are supported.
//! If not, the first supported present mode is returned.
VkPresentModeKHR GetSupportedPresentMode(uint32_t verticalSyncInterval) const;
//! Returns the preferred alpha compositing modes if they are supported.
//! If not, error will be reported.
VkCompositeAlphaFlagBitsKHR GetSupportedCompositeAlpha() const;
//! Returns the current surface capabilities.
VkSurfaceCapabilitiesKHR GetSurfaceCapabilities();
//! Create the swapchain when initializing, or
//! swapchain is no longer compatible or is sub-optimal with the surface.
RHI::ResultCode CreateSwapchain();
//! Build underlying Vulkan swapchain.
RHI::ResultCode BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions);
//! Retrieve the index of the next available presentable image.
RHI::ResultCode AcquireNewImage(uint32_t* acquiredImageIndex);
//! Destroy the surface.
void InvalidateSurface();
//! Destroy the old swapchain.
void InvalidateNativeSwapChain();
RHI::Ptr<WSISurface> m_surface;
VkSwapchainKHR m_nativeSwapChain = VK_NULL_HANDLE;
CommandQueue* m_presentationQueue = nullptr;
FrameContext m_currentFrameContext;
//! Swapchain data
VkSurfaceFormatKHR m_surfaceFormat = {};
VkSurfaceCapabilitiesKHR m_surfaceCapabilities = {};
VkPresentModeKHR m_presentMode = {};
VkCompositeAlphaFlagBitsKHR m_compositeAlphaFlagBits = {};
AZStd::vector<VkImage> m_swapchainNativeImages;
RHI::SwapChainDimensions m_dimensions;
struct SwapChainBarrier
{
VkPipelineStageFlags m_srcPipelineStages = 0;
VkPipelineStageFlags m_dstPipelineStages = 0;
VkImageMemoryBarrier m_barrier = {};
bool m_isValid = false;
} m_swapChainBarrier;
};
}
}