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 @@ -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 + namespace Vulkan { class Instance; class Scheduler; @@ -117,6 +119,7 @@ struct Image { VAddr cpu_addr_end = 0; std::vector image_view_infos; std::vector image_view_ids; + std::optional view_for_detiler; // Resource state tracking vk::Flags 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 detilers; };