Skip to content
Snippets Groups Projects
Commit 6d9f347e authored by ReinUsesLisp's avatar ReinUsesLisp
Browse files

texture_cache/util: Fix size calculations of multisampled images

On the texture cache we handle multisampled images by keeping their real
size in samples (e.g. 1920x1080 with 4 samples is 3840x2160).

This works nicely with size matches and other comparisons, but the
calculation for guest sizes was not having this in mind, and the size
was being multiplied (again) by the number of samples per dimension.
For example a 3840x2160 texture cache image had its width and height
multiplied by 2, resulting in a much larger texture.

Fix this issue.

- Fixes performance regression on cooking related titles when an
  unrelated bug was fixed.
parent 8b532093
No related branches found
No related tags found
No related merge requests found
...@@ -169,23 +169,6 @@ template <u32 GOB_EXTENT> ...@@ -169,23 +169,6 @@ template <u32 GOB_EXTENT>
return Common::DivCeil(AdjustMipSize(size, level), block_size); return Common::DivCeil(AdjustMipSize(size, level), block_size);
} }
[[nodiscard]] constexpr std::pair<int, int> Samples(int num_samples) {
switch (num_samples) {
case 1:
return {1, 1};
case 2:
return {2, 1};
case 4:
return {2, 2};
case 8:
return {4, 2};
case 16:
return {4, 4};
}
UNREACHABLE_MSG("Invalid number of samples={}", num_samples);
return {1, 1};
}
[[nodiscard]] constexpr Extent2D DefaultBlockSize(PixelFormat format) { [[nodiscard]] constexpr Extent2D DefaultBlockSize(PixelFormat format) {
return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
} }
...@@ -283,14 +266,13 @@ template <u32 GOB_EXTENT> ...@@ -283,14 +266,13 @@ template <u32 GOB_EXTENT>
} }
[[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block, [[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block,
u32 num_samples, u32 tile_width_spacing) { u32 tile_width_spacing) {
const auto [samples_x, samples_y] = Samples(num_samples);
const u32 bytes_per_block = BytesPerBlock(format); const u32 bytes_per_block = BytesPerBlock(format);
return { return {
.size = .size =
{ {
.width = size.width * samples_x, .width = size.width,
.height = size.height * samples_y, .height = size.height,
.depth = size.depth, .depth = size.depth,
}, },
.block = block, .block = block,
...@@ -301,14 +283,12 @@ template <u32 GOB_EXTENT> ...@@ -301,14 +283,12 @@ template <u32 GOB_EXTENT>
} }
[[nodiscard]] constexpr LevelInfo MakeLevelInfo(const ImageInfo& info) { [[nodiscard]] constexpr LevelInfo MakeLevelInfo(const ImageInfo& info) {
return MakeLevelInfo(info.format, info.size, info.block, info.num_samples, return MakeLevelInfo(info.format, info.size, info.block, info.tile_width_spacing);
info.tile_width_spacing);
} }
[[nodiscard]] constexpr u32 CalculateLevelOffset(PixelFormat format, Extent3D size, Extent3D block, [[nodiscard]] constexpr u32 CalculateLevelOffset(PixelFormat format, Extent3D size, Extent3D block,
u32 num_samples, u32 tile_width_spacing, u32 tile_width_spacing, u32 level) {
u32 level) { const LevelInfo info = MakeLevelInfo(format, size, block, tile_width_spacing);
const LevelInfo info = MakeLevelInfo(format, size, block, num_samples, tile_width_spacing);
u32 offset = 0; u32 offset = 0;
for (u32 current_level = 0; current_level < level; ++current_level) { for (u32 current_level = 0; current_level < level; ++current_level) {
offset += CalculateLevelSize(info, current_level); offset += CalculateLevelSize(info, current_level);
...@@ -645,8 +625,8 @@ u32 CalculateLayerStride(const ImageInfo& info) noexcept { ...@@ -645,8 +625,8 @@ u32 CalculateLayerStride(const ImageInfo& info) noexcept {
u32 CalculateLayerSize(const ImageInfo& info) noexcept { u32 CalculateLayerSize(const ImageInfo& info) noexcept {
ASSERT(info.type != ImageType::Linear); ASSERT(info.type != ImageType::Linear);
return CalculateLevelOffset(info.format, info.size, info.block, info.num_samples, return CalculateLevelOffset(info.format, info.size, info.block, info.tile_width_spacing,
info.tile_width_spacing, info.resources.levels); info.resources.levels);
} }
LevelArray CalculateMipLevelOffsets(const ImageInfo& info) noexcept { LevelArray CalculateMipLevelOffsets(const ImageInfo& info) noexcept {
...@@ -1195,37 +1175,37 @@ static_assert(CalculateLevelSize(LevelInfo{{1920, 1080, 1}, {0, 2, 0}, {1, 1}, 2 ...@@ -1195,37 +1175,37 @@ static_assert(CalculateLevelSize(LevelInfo{{1920, 1080, 1}, {0, 2, 0}, {1, 1}, 2
0x7f8000); 0x7f8000);
static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x4000); static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x4000);
static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 1, 0, 7) == static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 0, 7) ==
0x2afc00); 0x2afc00);
static_assert(CalculateLevelOffset(PixelFormat::ASTC_2D_12X12_UNORM, {8192, 4096, 1}, {0, 2, 0}, 1, static_assert(CalculateLevelOffset(PixelFormat::ASTC_2D_12X12_UNORM, {8192, 4096, 1}, {0, 2, 0}, 0,
0, 12) == 0x50d200); 12) == 0x50d200);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 0) ==
0) == 0); 0);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 1) ==
1) == 0x400000); 0x400000);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 2) ==
2) == 0x500000); 0x500000);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 3) ==
3) == 0x540000); 0x540000);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 4) ==
4) == 0x550000); 0x550000);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 5) ==
5) == 0x554000); 0x554000);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 6) ==
6) == 0x555000); 0x555000);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 7) ==
7) == 0x555400); 0x555400);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 8) ==
8) == 0x555600); 0x555600);
static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 9) ==
9) == 0x555800); 0x555800);
constexpr u32 ValidateLayerSize(PixelFormat format, u32 width, u32 height, u32 block_height, constexpr u32 ValidateLayerSize(PixelFormat format, u32 width, u32 height, u32 block_height,
u32 tile_width_spacing, u32 level) { u32 tile_width_spacing, u32 level) {
const Extent3D size{width, height, 1}; const Extent3D size{width, height, 1};
const Extent3D block{0, block_height, 0}; const Extent3D block{0, block_height, 0};
const u32 offset = CalculateLevelOffset(format, size, block, 1, tile_width_spacing, level); const u32 offset = CalculateLevelOffset(format, size, block, tile_width_spacing, level);
return AlignLayerSize(offset, size, block, DefaultBlockHeight(format), tile_width_spacing); return AlignLayerSize(offset, size, block, DefaultBlockHeight(format), tile_width_spacing);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment