suyu/src/video_core/renderer_vulkan/vk_texture_cache.h

229 lines
6.7 KiB
C++
Raw Normal View History

// Copyright 2019 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <unordered_map>
#include "common/common_types.h"
#include "video_core/renderer_vulkan/vk_image.h"
#include "video_core/renderer_vulkan/vk_memory_manager.h"
#include "video_core/renderer_vulkan/vk_scheduler.h"
2020-03-27 05:33:21 +01:00
#include "video_core/renderer_vulkan/wrapper.h"
#include "video_core/texture_cache/surface_base.h"
#include "video_core/texture_cache/texture_cache.h"
namespace Core {
class System;
}
namespace VideoCore {
class RasterizerInterface;
}
namespace Vulkan {
class RasterizerVulkan;
class VKDevice;
class VKResourceManager;
class VKScheduler;
class VKStagingBufferPool;
class CachedSurfaceView;
class CachedSurface;
using Surface = std::shared_ptr<CachedSurface>;
using View = std::shared_ptr<CachedSurfaceView>;
using TextureCacheBase = VideoCommon::TextureCache<Surface, View>;
using VideoCommon::SurfaceParams;
using VideoCommon::ViewParams;
class CachedSurface final : public VideoCommon::SurfaceBase<View> {
friend CachedSurfaceView;
public:
explicit CachedSurface(Core::System& system, const VKDevice& device,
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
VKScheduler& scheduler, VKStagingBufferPool& staging_pool,
GPUVAddr gpu_addr, const SurfaceParams& params);
~CachedSurface();
void UploadTexture(const std::vector<u8>& staging_buffer) override;
void DownloadTexture(std::vector<u8>& staging_buffer) override;
2020-03-27 05:33:21 +01:00
void FullTransition(VkPipelineStageFlags new_stage_mask, VkAccessFlags new_access,
VkImageLayout new_layout) {
image->Transition(0, static_cast<u32>(params.GetNumLayers()), 0, params.num_levels,
new_stage_mask, new_access, new_layout);
}
void Transition(u32 base_layer, u32 num_layers, u32 base_level, u32 num_levels,
2020-03-27 05:33:21 +01:00
VkPipelineStageFlags new_stage_mask, VkAccessFlags new_access,
VkImageLayout new_layout) {
image->Transition(base_layer, num_layers, base_level, num_levels, new_stage_mask,
new_access, new_layout);
}
VKImage& GetImage() {
return *image;
}
const VKImage& GetImage() const {
return *image;
}
2020-03-27 05:33:21 +01:00
VkImage GetImageHandle() const {
return *image->GetHandle();
}
2020-03-27 05:33:21 +01:00
VkImageAspectFlags GetAspectMask() const {
return image->GetAspectMask();
}
2020-03-27 05:33:21 +01:00
VkBufferView GetBufferViewHandle() const {
return *buffer_view;
}
protected:
void DecorateSurfaceName();
View CreateView(const ViewParams& params) override;
private:
void UploadBuffer(const std::vector<u8>& staging_buffer);
void UploadImage(const std::vector<u8>& staging_buffer);
2020-03-27 05:33:21 +01:00
VkBufferImageCopy GetBufferImageCopy(u32 level) const;
2020-03-27 05:33:21 +01:00
VkImageSubresourceRange GetImageSubresourceRange() const;
Core::System& system;
const VKDevice& device;
VKResourceManager& resource_manager;
VKMemoryManager& memory_manager;
VKScheduler& scheduler;
VKStagingBufferPool& staging_pool;
std::optional<VKImage> image;
2020-03-27 05:33:21 +01:00
vk::Buffer buffer;
vk::BufferView buffer_view;
VKMemoryCommit commit;
2020-03-27 05:33:21 +01:00
VkFormat format = VK_FORMAT_UNDEFINED;
};
class CachedSurfaceView final : public VideoCommon::ViewBase {
public:
explicit CachedSurfaceView(const VKDevice& device, CachedSurface& surface,
const ViewParams& params);
~CachedSurfaceView();
VkImageView GetImageView(Tegra::Texture::SwizzleSource x_source,
Tegra::Texture::SwizzleSource y_source,
Tegra::Texture::SwizzleSource z_source,
Tegra::Texture::SwizzleSource w_source);
VkImageView GetAttachment();
2020-01-16 22:23:10 +01:00
bool IsSameSurface(const CachedSurfaceView& rhs) const {
return &surface == &rhs.surface;
}
u32 GetWidth() const {
return params.GetMipWidth(base_level);
}
u32 GetHeight() const {
return params.GetMipHeight(base_level);
}
u32 GetNumLayers() const {
return num_layers;
}
bool IsBufferView() const {
return buffer_view;
}
2020-03-27 05:33:21 +01:00
VkImage GetImage() const {
return image;
}
2020-03-27 05:33:21 +01:00
VkBufferView GetBufferView() const {
return buffer_view;
}
2020-03-27 05:33:21 +01:00
VkImageSubresourceRange GetImageSubresourceRange() const {
return {aspect_mask, base_level, num_levels, base_layer, num_layers};
}
2020-03-27 05:33:21 +01:00
VkImageSubresourceLayers GetImageSubresourceLayers() const {
return {surface.GetAspectMask(), base_level, base_layer, num_layers};
}
2020-03-27 05:33:21 +01:00
void Transition(VkImageLayout new_layout, VkPipelineStageFlags new_stage_mask,
VkAccessFlags new_access) const {
surface.Transition(base_layer, num_layers, base_level, num_levels, new_stage_mask,
new_access, new_layout);
}
void MarkAsModified(u64 tick) {
surface.MarkAsModified(true, tick);
}
private:
// Store a copy of these values to avoid double dereference when reading them
const SurfaceParams params;
2020-03-27 05:33:21 +01:00
const VkImage image;
const VkBufferView buffer_view;
const VkImageAspectFlags aspect_mask;
const VKDevice& device;
CachedSurface& surface;
const u32 base_level;
const u32 num_levels;
2020-03-27 05:33:21 +01:00
const VkImageViewType image_view_type;
u32 base_layer = 0;
u32 num_layers = 0;
u32 base_slice = 0;
u32 num_slices = 0;
2020-03-27 05:33:21 +01:00
VkImageView last_image_view = nullptr;
u32 last_swizzle = 0;
vk::ImageView render_target;
2020-03-27 05:33:21 +01:00
std::unordered_map<u32, vk::ImageView> view_cache;
};
class VKTextureCache final : public TextureCacheBase {
public:
explicit VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
const VKDevice& device, VKResourceManager& resource_manager,
VKMemoryManager& memory_manager, VKScheduler& scheduler,
VKStagingBufferPool& staging_pool);
~VKTextureCache();
private:
Surface CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) override;
void ImageCopy(Surface& src_surface, Surface& dst_surface,
const VideoCommon::CopyParams& copy_params) override;
void ImageBlit(View& src_view, View& dst_view,
const Tegra::Engines::Fermi2D::Config& copy_config) override;
void BufferCopy(Surface& src_surface, Surface& dst_surface) override;
const VKDevice& device;
VKResourceManager& resource_manager;
VKMemoryManager& memory_manager;
VKScheduler& scheduler;
VKStagingBufferPool& staging_pool;
};
} // namespace Vulkan