summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan/vk_texture_cache.h
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2020-01-14 00:36:03 +0100
committerReinUsesLisp <reinuseslisp@airmail.cc>2020-01-14 00:37:50 +0100
commit09e17fbb0ff70a62b4cff1cafae0ab579956c648 (patch)
tree3a38559009287af0f4b08ed13bc245868cf627a0 /src/video_core/renderer_vulkan/vk_texture_cache.h
parenttexture_cache/surface_params: Make GetNumLayers public (diff)
downloadyuzu-09e17fbb0ff70a62b4cff1cafae0ab579956c648.tar
yuzu-09e17fbb0ff70a62b4cff1cafae0ab579956c648.tar.gz
yuzu-09e17fbb0ff70a62b4cff1cafae0ab579956c648.tar.bz2
yuzu-09e17fbb0ff70a62b4cff1cafae0ab579956c648.tar.lz
yuzu-09e17fbb0ff70a62b4cff1cafae0ab579956c648.tar.xz
yuzu-09e17fbb0ff70a62b4cff1cafae0ab579956c648.tar.zst
yuzu-09e17fbb0ff70a62b4cff1cafae0ab579956c648.zip
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
new file mode 100644
index 000000000..4bc330c9f
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -0,0 +1,244 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <tuple>
+#include <unordered_map>
+
+#include <boost/functional/hash.hpp>
+#include <boost/icl/interval_map.hpp>
+
+#include "common/assert.h"
+#include "common/common_types.h"
+#include "common/hash.h"
+#include "common/logging/log.h"
+#include "common/math_util.h"
+#include "video_core/gpu.h"
+#include "video_core/rasterizer_cache.h"
+#include "video_core/renderer_vulkan/declarations.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"
+#include "video_core/surface.h"
+#include "video_core/texture_cache/surface_base.h"
+#include "video_core/texture_cache/texture_cache.h"
+#include "video_core/textures/decoders.h"
+#include "video_core/textures/texture.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;
+
+ void FullTransition(vk::PipelineStageFlags new_stage_mask, vk::AccessFlags new_access,
+ vk::ImageLayout 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,
+ vk::PipelineStageFlags new_stage_mask, vk::AccessFlags new_access,
+ vk::ImageLayout 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;
+ }
+
+ vk::Image GetImageHandle() const {
+ return image->GetHandle();
+ }
+
+ vk::ImageAspectFlags GetAspectMask() const {
+ return image->GetAspectMask();
+ }
+
+ vk::BufferView GetBufferViewHandle() const {
+ return *buffer_view;
+ }
+
+protected:
+ void DecorateSurfaceName();
+
+ View CreateView(const ViewParams& params) override;
+ View CreateViewInner(const ViewParams& params, bool is_proxy);
+
+private:
+ void UploadBuffer(const std::vector<u8>& staging_buffer);
+
+ void UploadImage(const std::vector<u8>& staging_buffer);
+
+ vk::BufferImageCopy GetBufferImageCopy(u32 level) const;
+
+ vk::ImageSubresourceRange GetImageSubresourceRange() const;
+
+ Core::System& system;
+ const VKDevice& device;
+ VKResourceManager& resource_manager;
+ VKMemoryManager& memory_manager;
+ VKScheduler& scheduler;
+ VKStagingBufferPool& staging_pool;
+
+ std::optional<VKImage> image;
+ UniqueBuffer buffer;
+ UniqueBufferView buffer_view;
+ VKMemoryCommit commit;
+
+ vk::Format format;
+};
+
+class CachedSurfaceView final : public VideoCommon::ViewBase {
+public:
+ explicit CachedSurfaceView(const VKDevice& device, CachedSurface& surface,
+ const ViewParams& params, bool is_proxy);
+ ~CachedSurfaceView();
+
+ vk::ImageView GetHandle(Tegra::Texture::SwizzleSource x_source,
+ Tegra::Texture::SwizzleSource y_source,
+ Tegra::Texture::SwizzleSource z_source,
+ Tegra::Texture::SwizzleSource w_source);
+
+ bool IsOverlapping(const View& rhs) const;
+
+ vk::ImageView GetHandle() {
+ return GetHandle(Tegra::Texture::SwizzleSource::R, Tegra::Texture::SwizzleSource::G,
+ Tegra::Texture::SwizzleSource::B, Tegra::Texture::SwizzleSource::A);
+ }
+
+ u32 GetWidth() const {
+ return params.GetMipWidth(base_level);
+ }
+
+ u32 GetHeight() const {
+ return params.GetMipHeight(base_level);
+ }
+
+ bool IsBufferView() const {
+ return buffer_view;
+ }
+
+ vk::Image GetImage() const {
+ return image;
+ }
+
+ vk::BufferView GetBufferView() const {
+ return buffer_view;
+ }
+
+ vk::ImageSubresourceRange GetImageSubresourceRange() const {
+ return {aspect_mask, base_level, num_levels, base_layer, num_layers};
+ }
+
+ vk::ImageSubresourceLayers GetImageSubresourceLayers() const {
+ return {surface.GetAspectMask(), base_level, base_layer, num_layers};
+ }
+
+ void Transition(vk::ImageLayout new_layout, vk::PipelineStageFlags new_stage_mask,
+ vk::AccessFlags 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:
+ static u32 EncodeSwizzle(Tegra::Texture::SwizzleSource x_source,
+ Tegra::Texture::SwizzleSource y_source,
+ Tegra::Texture::SwizzleSource z_source,
+ Tegra::Texture::SwizzleSource w_source) {
+ return (static_cast<u32>(x_source) << 24) | (static_cast<u32>(y_source) << 16) |
+ (static_cast<u32>(z_source) << 8) | static_cast<u32>(w_source);
+ }
+
+ // Store a copy of these values to avoid double dereference when reading them
+ const SurfaceParams params;
+ const vk::Image image;
+ const vk::BufferView buffer_view;
+ const vk::ImageAspectFlags aspect_mask;
+
+ const VKDevice& device;
+ CachedSurface& surface;
+ const u32 base_layer;
+ const u32 num_layers;
+ const u32 base_level;
+ const u32 num_levels;
+ vk::ImageViewType image_view_type{};
+
+ vk::ImageView last_image_view;
+ u32 last_swizzle{};
+
+ std::unordered_map<u32, UniqueImageView> 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