From f9e5c704147417025d7622f572dfa48ebfcb9d39 Mon Sep 17 00:00:00 2001
From: psucien <bad_cast@protonmail.com>
Date: Wed, 5 Jun 2024 18:37:06 +0200
Subject: [PATCH] texture_cache: detiler image view moved into image class

---
 src/video_core/host_shaders/detile_m8x1.comp   |  2 +-
 src/video_core/host_shaders/detile_m8x4.comp   |  3 +--
 src/video_core/texture_cache/image.cpp         |  9 +++++++++
 src/video_core/texture_cache/image.h           |  3 +++
 src/video_core/texture_cache/texture_cache.cpp | 10 +---------
 src/video_core/texture_cache/texture_cache.h   |  3 ---
 src/video_core/texture_cache/tile_manager.cpp  | 10 ++++------
 src/video_core/texture_cache/tile_manager.h    |  4 +---
 8 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/src/video_core/host_shaders/detile_m8x1.comp b/src/video_core/host_shaders/detile_m8x1.comp
index 1b84b402..b4d920e6 100644
--- a/src/video_core/host_shaders/detile_m8x1.comp
+++ b/src/video_core/host_shaders/detile_m8x1.comp
@@ -32,7 +32,7 @@ void main() {
     uint row = (gl_LocalInvocationID.x % TEXELS_PER_ELEMENT)
                 + TEXELS_PER_ELEMENT * (gl_LocalInvocationID.x >> 3);
 
-    uint tiles_per_pitch = info.pitch / MICRO_TILE_DIM;
+    uint tiles_per_pitch = info.pitch >> 3; // log2(MICRO_TILE_DIM)
     uint target_tile_x = gl_WorkGroupID.x % tiles_per_pitch;
     uint target_tile_y = gl_WorkGroupID.x / tiles_per_pitch;
     uint dw_ofs_x = target_tile_x * MICRO_TILE_DIM + TEXELS_PER_ELEMENT * col;
diff --git a/src/video_core/host_shaders/detile_m8x4.comp b/src/video_core/host_shaders/detile_m8x4.comp
index 97438fe9..25f7fef6 100644
--- a/src/video_core/host_shaders/detile_m8x4.comp
+++ b/src/video_core/host_shaders/detile_m8x4.comp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #version 450
-#extension GL_KHR_shader_subgroup_shuffle : require
 
 layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
 
@@ -39,7 +38,7 @@ void main() {
     uint col = bitfieldExtract(packed_pos, 4, 4);
     uint row = bitfieldExtract(packed_pos, 0, 4);
 
-    uint tiles_per_pitch = info.pitch / MICRO_TILE_DIM;
+    uint tiles_per_pitch = info.pitch >> 3; // log2(MICRO_TILE_DIM)
     uint target_tile_x = gl_WorkGroupID.x % tiles_per_pitch;
     uint target_tile_y = gl_WorkGroupID.x / tiles_per_pitch;
 
diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp
index dd556a7b..7aa3062b 100644
--- a/src/video_core/texture_cache/image.cpp
+++ b/src/video_core/texture_cache/image.cpp
@@ -7,6 +7,7 @@
 #include "video_core/renderer_vulkan/vk_instance.h"
 #include "video_core/renderer_vulkan/vk_scheduler.h"
 #include "video_core/texture_cache/image.h"
+#include "video_core/texture_cache/tile_manager.h"
 
 #include <vk_mem_alloc.h>
 
@@ -181,6 +182,14 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
 
     image.Create(image_ci);
 
+    // Create a special view for detiler
+    if (info.is_tiled) {
+        ImageViewInfo view_info;
+        view_info.format = DemoteImageFormatForDetiling(info.pixel_format);
+        view_info.used_for_detiling = true;
+        view_for_detiler.emplace(*instance, view_info, image);
+    }
+
     Transit(vk::ImageLayout::eGeneral, vk::AccessFlagBits::eNone);
 }
 
diff --git a/src/video_core/texture_cache/image.h b/src/video_core/texture_cache/image.h
index f2de6abb..c357f8a2 100644
--- a/src/video_core/texture_cache/image.h
+++ b/src/video_core/texture_cache/image.h
@@ -12,6 +12,8 @@
 #include "video_core/texture_cache/image_view.h"
 #include "video_core/texture_cache/types.h"
 
+#include <optional>
+
 namespace Vulkan {
 class Instance;
 class Scheduler;
@@ -117,6 +119,7 @@ struct Image {
     VAddr cpu_addr_end = 0;
     std::vector<ImageViewInfo> image_view_infos;
     std::vector<ImageViewId> image_view_ids;
+    std::optional<ImageView> view_for_detiler;
 
     // Resource state tracking
     vk::Flags<vk::PipelineStageFlagBits> pl_stage = vk::PipelineStageFlagBits::eAllCommands;
diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp
index 786f9cf5..d3c6b678 100644
--- a/src/video_core/texture_cache/texture_cache.cpp
+++ b/src/video_core/texture_cache/texture_cache.cpp
@@ -66,7 +66,7 @@ TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler&
     : instance{instance_}, scheduler{scheduler_},
       staging{instance, scheduler, vk::BufferUsageFlagBits::eTransferSrc, StreamBufferSize,
               Vulkan::BufferType::Upload},
-      tile_manager{instance, scheduler, *this} {
+      tile_manager{instance, scheduler} {
 
 #ifndef _WIN64
     sigset_t signal_mask;
@@ -167,14 +167,6 @@ ImageView& TextureCache::FindImageView(const AmdGpu::Image& desc) {
     return RegisterImageView(image, view_info);
 }
 
-ImageView& TextureCache::GetImageViewForDetiler(Image& image) {
-    ImageViewInfo view_info;
-    view_info.format = DemoteImageFormatForDetiling(image.info.pixel_format);
-    view_info.used_for_detiling = true;
-
-    return RegisterImageView(image, view_info);
-}
-
 ImageView& TextureCache::RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
                                       const AmdGpu::Liverpool::CbDbExtent& hint) {
     const ImageInfo info{buffer, hint};
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index f9384211..a4dbff73 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -42,9 +42,6 @@ public:
     /// Retrieves an image view with the properties of the specified image descriptor.
     [[nodiscard]] ImageView& FindImageView(const AmdGpu::Image& image);
 
-    /// Retrieves an image view with "demoted" pixel format used in detiling
-    [[nodiscard]] ImageView& GetImageViewForDetiler(Image& image);
-
     /// Retrieves the render target with specified properties
     [[nodiscard]] ImageView& RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
                                           const AmdGpu::Liverpool::CbDbExtent& hint);
diff --git a/src/video_core/texture_cache/tile_manager.cpp b/src/video_core/texture_cache/tile_manager.cpp
index decae2d1..54cbc5da 100644
--- a/src/video_core/texture_cache/tile_manager.cpp
+++ b/src/video_core/texture_cache/tile_manager.cpp
@@ -206,10 +206,8 @@ static constexpr vk::BufferUsageFlags StagingFlags = vk::BufferUsageFlagBits::eT
                                                      vk::BufferUsageFlagBits::eUniformBuffer |
                                                      vk::BufferUsageFlagBits::eStorageBuffer;
 
-TileManager::TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler,
-                         TextureCache& texture_cache)
-    : instance{instance}, scheduler{scheduler}, texture_cache{texture_cache},
-      staging{instance, scheduler, StagingFlags, 64_MB} {
+TileManager::TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler)
+    : instance{instance}, scheduler{scheduler}, staging{instance, scheduler, StagingFlags, 64_MB} {
 
     static const std::array detiler_shaders{
         HostShaders::DETILE_M8X1_COMP,
@@ -322,9 +320,9 @@ bool TileManager::TryDetile(Image& image) {
         .range = image.info.guest_size_bytes,
     };
 
-    const auto& demoted_view = texture_cache.GetImageViewForDetiler(image);
+    ASSERT(image.view_for_detiler.has_value());
     const vk::DescriptorImageInfo output_image_info{
-        .imageView = *demoted_view.image_view,
+        .imageView = *image.view_for_detiler->image_view,
         .imageLayout = image.layout,
     };
 
diff --git a/src/video_core/texture_cache/tile_manager.h b/src/video_core/texture_cache/tile_manager.h
index d8c3cfaf..c630004c 100644
--- a/src/video_core/texture_cache/tile_manager.h
+++ b/src/video_core/texture_cache/tile_manager.h
@@ -31,8 +31,7 @@ struct DetilerContext {
 
 class TileManager {
 public:
-    TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler,
-                TextureCache& texture_cache);
+    TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler);
     ~TileManager();
 
     bool TryDetile(Image& image);
@@ -43,7 +42,6 @@ private:
 private:
     const Vulkan::Instance& instance;
     Vulkan::Scheduler& scheduler;
-    TextureCache& texture_cache;
     Vulkan::StreamBuffer staging;
     std::array<DetilerContext, DetilerType::Max> detilers;
 };