From d491bbf366eda2fc0108e391a9674aecff46d8b9 Mon Sep 17 00:00:00 2001 From: psucien Date: Sun, 2 Jun 2024 22:58:23 +0200 Subject: [PATCH] amdgpu: tiling mode introduced --- src/video_core/amdgpu/liverpool.h | 19 ++++++++++++++++++- src/video_core/amdgpu/resource.h | 21 ++++++++++++++++++++- src/video_core/texture_cache/image.cpp | 10 +++++----- src/video_core/texture_cache/image.h | 1 + 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index b09182ae..b561b712 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -6,6 +6,7 @@ #include "common/assert.h" #include "common/bit_field.h" #include "common/types.h" +#include "resource.h" #include "video_core/amdgpu/pixel_format.h" #include @@ -622,7 +623,7 @@ struct Liverpool { BitField<19, 1, u32> cmask_is_linear; } info; union { - BitField<0, 5, u32> tile_mode_index; + BitField<0, 5, TilingMode> tile_mode_index; BitField<5, 5, u32> fmask_tile_mode_index; BitField<12, 3, u32> num_samples_log2; BitField<15, 3, u32> num_fragments_log2; @@ -661,6 +662,22 @@ struct Liverpool { return u64(cmask_base_address) << 8; } + [[nodiscard]] size_t GetSizeAligned() const { + const auto num_bytes_per_element = NumBits(info.format) / 8u; + const auto slice_size = (slice.tile_max + 1) * 64u; + const auto total_size = slice_size * (view.slice_max + 1) * num_bytes_per_element; + ASSERT(total_size > 0); + return total_size; + } + + [[nodiscard]] TilingMode GetTilingMode() const { + return attrib.tile_mode_index; + } + + [[nodiscard]] bool IsTiled() const { + return !info.linear_general; + } + NumberFormat NumFormat() const { // There is a small difference between T# and CB number types, account for it. return info.number_type == AmdGpu::NumberFormat::Uscaled ? AmdGpu::NumberFormat::Srgb diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index ef78c2f4..e9b7a553 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -85,6 +85,12 @@ constexpr std::string_view NameOf(ImageType type) { } } +enum class TilingMode : u32 { + Display_Linear = 0x8u, + Display_MacroTiled = 0xAu, + Texture_MicroTiled = 0xDu, +}; + struct Image { union { BitField<0, 38, u64> base_address; @@ -122,7 +128,7 @@ struct Image { } u32 Pitch() const { - return pitch; + return pitch + 1; } u32 NumLayers() const { @@ -140,6 +146,19 @@ struct Image { NumberFormat GetNumberFmt() const noexcept { return static_cast(num_format.Value()); } + + [[nodiscard]] TilingMode GetTilingMode() const { + return static_cast(tiling_index.Value()); + } + + [[nodiscard]] bool IsTiled() const { + return GetTilingMode() != TilingMode::Display_Linear; + } + + [[nodiscard]] size_t GetSizeAligned() const { + // TODO: Derive this properly from tiling params + return (width + 1) * (height + 1) * NumComponents(GetDataFmt()); + } }; // 8.2.7. Image Sampler [RDNA 2 Instruction Set Architecture] diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp index 3334c4a7..bc8cb198 100644 --- a/src/video_core/texture_cache/image.cpp +++ b/src/video_core/texture_cache/image.cpp @@ -86,18 +86,19 @@ ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group) noe ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer, const AmdGpu::Liverpool::CbDbExtent& hint /*= {}*/) noexcept { - is_tiled = true; + is_tiled = buffer.IsTiled(); pixel_format = LiverpoolToVK::SurfaceFormat(buffer.info.format, buffer.NumFormat()); type = vk::ImageType::e2D; size.width = hint.Valid() ? hint.width : buffer.Pitch(); size.height = hint.Valid() ? hint.height : buffer.Height(); size.depth = 1; pitch = size.width; - guest_size_bytes = buffer.slice.tile_max * (buffer.view.slice_max + 1); + guest_size_bytes = buffer.GetSizeAligned(); } ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept { - is_tiled = false; + is_tiled = image.IsTiled(); + tiling_mode = image.GetTilingMode(); pixel_format = LiverpoolToVK::SurfaceFormat(image.GetDataFmt(), image.GetNumberFmt()); type = ConvertImageType(image.type); size.width = image.width + 1; @@ -106,8 +107,7 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept { pitch = image.Pitch(); resources.levels = image.NumLevels(); resources.layers = image.NumLayers(); - // TODO: Derive this properly from tiling params - guest_size_bytes = size.width * size.height * 4; + guest_size_bytes = image.GetSizeAligned(); } UniqueImage::UniqueImage(vk::Device device_, VmaAllocator allocator_) diff --git a/src/video_core/texture_cache/image.h b/src/video_core/texture_cache/image.h index cc3adff4..5d9a1547 100644 --- a/src/video_core/texture_cache/image.h +++ b/src/video_core/texture_cache/image.h @@ -45,6 +45,7 @@ struct ImageInfo { Extent3D size{1, 1, 1}; u32 pitch = 0; u32 guest_size_bytes = 0; + AmdGpu::TilingMode tiling_mode{AmdGpu::TilingMode::Display_Linear}; }; struct UniqueImage {