mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-28 18:46:06 +00:00
amdgpu: tiling mode introduced
This commit is contained in:
parent
d7d324ac76
commit
d491bbf366
|
@ -6,6 +6,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
#include "resource.h"
|
||||||
#include "video_core/amdgpu/pixel_format.h"
|
#include "video_core/amdgpu/pixel_format.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -622,7 +623,7 @@ struct Liverpool {
|
||||||
BitField<19, 1, u32> cmask_is_linear;
|
BitField<19, 1, u32> cmask_is_linear;
|
||||||
} info;
|
} info;
|
||||||
union {
|
union {
|
||||||
BitField<0, 5, u32> tile_mode_index;
|
BitField<0, 5, TilingMode> tile_mode_index;
|
||||||
BitField<5, 5, u32> fmask_tile_mode_index;
|
BitField<5, 5, u32> fmask_tile_mode_index;
|
||||||
BitField<12, 3, u32> num_samples_log2;
|
BitField<12, 3, u32> num_samples_log2;
|
||||||
BitField<15, 3, u32> num_fragments_log2;
|
BitField<15, 3, u32> num_fragments_log2;
|
||||||
|
@ -661,6 +662,22 @@ struct Liverpool {
|
||||||
return u64(cmask_base_address) << 8;
|
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 {
|
NumberFormat NumFormat() const {
|
||||||
// There is a small difference between T# and CB number types, account for it.
|
// There is a small difference between T# and CB number types, account for it.
|
||||||
return info.number_type == AmdGpu::NumberFormat::Uscaled ? AmdGpu::NumberFormat::Srgb
|
return info.number_type == AmdGpu::NumberFormat::Uscaled ? AmdGpu::NumberFormat::Srgb
|
||||||
|
|
|
@ -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 {
|
struct Image {
|
||||||
union {
|
union {
|
||||||
BitField<0, 38, u64> base_address;
|
BitField<0, 38, u64> base_address;
|
||||||
|
@ -122,7 +128,7 @@ struct Image {
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Pitch() const {
|
u32 Pitch() const {
|
||||||
return pitch;
|
return pitch + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 NumLayers() const {
|
u32 NumLayers() const {
|
||||||
|
@ -140,6 +146,19 @@ struct Image {
|
||||||
NumberFormat GetNumberFmt() const noexcept {
|
NumberFormat GetNumberFmt() const noexcept {
|
||||||
return static_cast<NumberFormat>(num_format.Value());
|
return static_cast<NumberFormat>(num_format.Value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TilingMode GetTilingMode() const {
|
||||||
|
return static_cast<TilingMode>(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]
|
// 8.2.7. Image Sampler [RDNA 2 Instruction Set Architecture]
|
||||||
|
|
|
@ -86,18 +86,19 @@ ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group) noe
|
||||||
|
|
||||||
ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||||
const AmdGpu::Liverpool::CbDbExtent& hint /*= {}*/) noexcept {
|
const AmdGpu::Liverpool::CbDbExtent& hint /*= {}*/) noexcept {
|
||||||
is_tiled = true;
|
is_tiled = buffer.IsTiled();
|
||||||
pixel_format = LiverpoolToVK::SurfaceFormat(buffer.info.format, buffer.NumFormat());
|
pixel_format = LiverpoolToVK::SurfaceFormat(buffer.info.format, buffer.NumFormat());
|
||||||
type = vk::ImageType::e2D;
|
type = vk::ImageType::e2D;
|
||||||
size.width = hint.Valid() ? hint.width : buffer.Pitch();
|
size.width = hint.Valid() ? hint.width : buffer.Pitch();
|
||||||
size.height = hint.Valid() ? hint.height : buffer.Height();
|
size.height = hint.Valid() ? hint.height : buffer.Height();
|
||||||
size.depth = 1;
|
size.depth = 1;
|
||||||
pitch = size.width;
|
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 {
|
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());
|
pixel_format = LiverpoolToVK::SurfaceFormat(image.GetDataFmt(), image.GetNumberFmt());
|
||||||
type = ConvertImageType(image.type);
|
type = ConvertImageType(image.type);
|
||||||
size.width = image.width + 1;
|
size.width = image.width + 1;
|
||||||
|
@ -106,8 +107,7 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept {
|
||||||
pitch = image.Pitch();
|
pitch = image.Pitch();
|
||||||
resources.levels = image.NumLevels();
|
resources.levels = image.NumLevels();
|
||||||
resources.layers = image.NumLayers();
|
resources.layers = image.NumLayers();
|
||||||
// TODO: Derive this properly from tiling params
|
guest_size_bytes = image.GetSizeAligned();
|
||||||
guest_size_bytes = size.width * size.height * 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UniqueImage::UniqueImage(vk::Device device_, VmaAllocator allocator_)
|
UniqueImage::UniqueImage(vk::Device device_, VmaAllocator allocator_)
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct ImageInfo {
|
||||||
Extent3D size{1, 1, 1};
|
Extent3D size{1, 1, 1};
|
||||||
u32 pitch = 0;
|
u32 pitch = 0;
|
||||||
u32 guest_size_bytes = 0;
|
u32 guest_size_bytes = 0;
|
||||||
|
AmdGpu::TilingMode tiling_mode{AmdGpu::TilingMode::Display_Linear};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UniqueImage {
|
struct UniqueImage {
|
||||||
|
|
Loading…
Reference in a new issue