2017-04-23 04:44:34 +00:00
|
|
|
// Copyright 2017 Dolphin Emulator Project
|
2021-07-05 01:22:19 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2017-04-23 04:44:34 +00:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <memory>
|
2021-08-28 05:30:05 +00:00
|
|
|
#include <string>
|
|
|
|
#include <string_view>
|
2017-04-23 04:44:34 +00:00
|
|
|
|
2019-02-15 01:59:50 +00:00
|
|
|
#include "VideoBackends/Vulkan/VulkanLoader.h"
|
2018-01-21 10:22:45 +00:00
|
|
|
#include "VideoCommon/AbstractFramebuffer.h"
|
2017-10-21 14:49:40 +00:00
|
|
|
#include "VideoCommon/AbstractStagingTexture.h"
|
2017-04-23 04:44:34 +00:00
|
|
|
#include "VideoCommon/AbstractTexture.h"
|
|
|
|
|
|
|
|
namespace Vulkan
|
|
|
|
{
|
2017-10-21 14:49:40 +00:00
|
|
|
class StagingBuffer;
|
2017-04-23 04:44:34 +00:00
|
|
|
class Texture2D;
|
|
|
|
|
|
|
|
class VKTexture final : public AbstractTexture
|
|
|
|
{
|
|
|
|
public:
|
2019-02-15 01:59:50 +00:00
|
|
|
// Custom image layouts, mainly used for switching to/from compute
|
|
|
|
enum class ComputeImageLayout
|
|
|
|
{
|
|
|
|
Undefined,
|
|
|
|
ReadOnly,
|
|
|
|
WriteOnly,
|
|
|
|
ReadWrite
|
|
|
|
};
|
|
|
|
|
2017-04-23 04:44:34 +00:00
|
|
|
VKTexture() = delete;
|
2022-10-07 21:48:11 +00:00
|
|
|
VKTexture(const TextureConfig& tex_config, VmaAllocation alloc, VkImage image,
|
2021-08-28 05:30:05 +00:00
|
|
|
std::string_view name, VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED,
|
2019-02-15 01:59:50 +00:00
|
|
|
ComputeImageLayout compute_layout = ComputeImageLayout::Undefined);
|
2017-04-23 04:44:34 +00:00
|
|
|
~VKTexture();
|
|
|
|
|
2019-02-15 01:59:50 +00:00
|
|
|
static VkFormat GetLinearFormat(VkFormat format);
|
|
|
|
static VkFormat GetVkFormatForHostTextureFormat(AbstractTextureFormat format);
|
|
|
|
static VkImageAspectFlags GetImageAspectForFormat(AbstractTextureFormat format);
|
2019-07-31 05:33:05 +00:00
|
|
|
static VkImageAspectFlags GetImageViewAspectForFormat(AbstractTextureFormat format);
|
2019-02-15 01:59:50 +00:00
|
|
|
|
2017-10-30 11:51:42 +00:00
|
|
|
void CopyRectangleFromTexture(const AbstractTexture* src,
|
|
|
|
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
|
|
|
|
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,
|
|
|
|
u32 dst_layer, u32 dst_level) override;
|
2018-01-21 05:03:06 +00:00
|
|
|
void ResolveFromTexture(const AbstractTexture* src, const MathUtil::Rectangle<int>& rect,
|
|
|
|
u32 layer, u32 level) override;
|
2023-01-28 00:46:53 +00:00
|
|
|
void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer, size_t buffer_size,
|
|
|
|
u32 layer) override;
|
2019-02-15 01:59:50 +00:00
|
|
|
void FinishedRendering() override;
|
2017-04-23 04:44:34 +00:00
|
|
|
|
2019-02-15 01:59:50 +00:00
|
|
|
VkImage GetImage() const { return m_image; }
|
|
|
|
VkImageView GetView() const { return m_view; }
|
|
|
|
VkImageLayout GetLayout() const { return m_layout; }
|
|
|
|
VkFormat GetVkFormat() const { return GetVkFormatForHostTextureFormat(m_config.format); }
|
2022-10-07 21:48:11 +00:00
|
|
|
bool IsAdopted() const { return m_alloc != VmaAllocation(VK_NULL_HANDLE); }
|
2017-04-23 04:44:34 +00:00
|
|
|
|
2021-08-28 05:30:05 +00:00
|
|
|
static std::unique_ptr<VKTexture> Create(const TextureConfig& tex_config, std::string_view name);
|
2019-02-15 01:59:50 +00:00
|
|
|
static std::unique_ptr<VKTexture>
|
|
|
|
CreateAdopted(const TextureConfig& tex_config, VkImage image,
|
|
|
|
VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
|
|
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED);
|
|
|
|
|
|
|
|
// Used when the render pass is changing the image layout, or to force it to
|
|
|
|
// VK_IMAGE_LAYOUT_UNDEFINED, if the existing contents of the image is
|
|
|
|
// irrelevant and will not be loaded.
|
|
|
|
void OverrideImageLayout(VkImageLayout new_layout);
|
|
|
|
|
|
|
|
void TransitionToLayout(VkCommandBuffer command_buffer, VkImageLayout new_layout) const;
|
|
|
|
void TransitionToLayout(VkCommandBuffer command_buffer, ComputeImageLayout new_layout) const;
|
2017-04-23 04:44:34 +00:00
|
|
|
|
|
|
|
private:
|
2019-02-15 01:59:50 +00:00
|
|
|
bool CreateView(VkImageViewType type);
|
2017-04-23 04:44:34 +00:00
|
|
|
|
2022-10-07 21:48:11 +00:00
|
|
|
VmaAllocation m_alloc;
|
2019-02-15 01:59:50 +00:00
|
|
|
VkImage m_image;
|
|
|
|
VkImageView m_view = VK_NULL_HANDLE;
|
|
|
|
mutable VkImageLayout m_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
|
|
mutable ComputeImageLayout m_compute_layout = ComputeImageLayout::Undefined;
|
2021-08-28 05:30:05 +00:00
|
|
|
std::string m_name;
|
2017-04-23 04:44:34 +00:00
|
|
|
};
|
|
|
|
|
2017-10-21 14:49:40 +00:00
|
|
|
class VKStagingTexture final : public AbstractStagingTexture
|
|
|
|
{
|
2022-09-23 20:45:43 +00:00
|
|
|
struct PrivateTag
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
2017-10-21 14:49:40 +00:00
|
|
|
public:
|
|
|
|
VKStagingTexture() = delete;
|
2022-09-23 20:45:43 +00:00
|
|
|
VKStagingTexture(PrivateTag, StagingTextureType type, const TextureConfig& config,
|
|
|
|
std::unique_ptr<StagingBuffer> buffer, VkImage linear_image,
|
2022-10-07 21:48:11 +00:00
|
|
|
VmaAllocation linear_image_alloc);
|
2022-09-23 20:45:43 +00:00
|
|
|
|
2017-10-21 14:49:40 +00:00
|
|
|
~VKStagingTexture();
|
|
|
|
|
|
|
|
void CopyFromTexture(const AbstractTexture* src, const MathUtil::Rectangle<int>& src_rect,
|
|
|
|
u32 src_layer, u32 src_level,
|
|
|
|
const MathUtil::Rectangle<int>& dst_rect) override;
|
|
|
|
void CopyToTexture(const MathUtil::Rectangle<int>& src_rect, AbstractTexture* dst,
|
|
|
|
const MathUtil::Rectangle<int>& dst_rect, u32 dst_layer,
|
|
|
|
u32 dst_level) override;
|
|
|
|
|
|
|
|
bool Map() override;
|
|
|
|
void Unmap() override;
|
|
|
|
void Flush() override;
|
|
|
|
|
|
|
|
static std::unique_ptr<VKStagingTexture> Create(StagingTextureType type,
|
|
|
|
const TextureConfig& config);
|
|
|
|
|
2022-10-07 21:48:11 +00:00
|
|
|
static std::pair<VkImage, VmaAllocation> CreateLinearImage(StagingTextureType type,
|
|
|
|
const TextureConfig& config);
|
2022-09-23 20:45:43 +00:00
|
|
|
|
2017-10-21 14:49:40 +00:00
|
|
|
private:
|
2022-09-23 20:45:43 +00:00
|
|
|
void CopyFromTextureToLinearImage(const VKTexture* src_tex,
|
|
|
|
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
|
|
|
|
u32 src_level, const MathUtil::Rectangle<int>& dst_rect);
|
2017-10-21 14:49:40 +00:00
|
|
|
|
|
|
|
std::unique_ptr<StagingBuffer> m_staging_buffer;
|
2022-09-23 20:45:43 +00:00
|
|
|
VkImage m_linear_image = VK_NULL_HANDLE;
|
2022-10-07 21:48:11 +00:00
|
|
|
VmaAllocation m_linear_image_alloc = VK_NULL_HANDLE;
|
2019-03-17 05:59:22 +00:00
|
|
|
u64 m_flush_fence_counter = 0;
|
2017-10-21 14:49:40 +00:00
|
|
|
};
|
|
|
|
|
2018-01-21 10:22:45 +00:00
|
|
|
class VKFramebuffer final : public AbstractFramebuffer
|
|
|
|
{
|
|
|
|
public:
|
2019-02-15 01:59:50 +00:00
|
|
|
VKFramebuffer(VKTexture* color_attachment, VKTexture* depth_attachment, u32 width, u32 height,
|
|
|
|
u32 layers, u32 samples, VkFramebuffer fb, VkRenderPass load_render_pass,
|
|
|
|
VkRenderPass discard_render_pass, VkRenderPass clear_render_pass);
|
2018-01-21 10:22:45 +00:00
|
|
|
~VKFramebuffer() override;
|
|
|
|
|
|
|
|
VkFramebuffer GetFB() const { return m_fb; }
|
2019-02-15 01:59:50 +00:00
|
|
|
VkRect2D GetRect() const { return VkRect2D{{0, 0}, {m_width, m_height}}; }
|
|
|
|
|
2018-01-21 10:22:45 +00:00
|
|
|
VkRenderPass GetLoadRenderPass() const { return m_load_render_pass; }
|
|
|
|
VkRenderPass GetDiscardRenderPass() const { return m_discard_render_pass; }
|
|
|
|
VkRenderPass GetClearRenderPass() const { return m_clear_render_pass; }
|
2019-02-15 01:59:50 +00:00
|
|
|
void TransitionForRender();
|
2018-01-21 10:22:45 +00:00
|
|
|
|
2019-02-15 01:59:50 +00:00
|
|
|
static std::unique_ptr<VKFramebuffer> Create(VKTexture* color_attachments,
|
|
|
|
VKTexture* depth_attachment);
|
2018-01-21 10:22:45 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
VkFramebuffer m_fb;
|
|
|
|
VkRenderPass m_load_render_pass;
|
|
|
|
VkRenderPass m_discard_render_pass;
|
|
|
|
VkRenderPass m_clear_render_pass;
|
|
|
|
};
|
|
|
|
|
2017-04-23 04:44:34 +00:00
|
|
|
} // namespace Vulkan
|