Merge pull request #6669 from ReinUsesLisp/fix-samples-sizes

texture_cache/util: Fix size calculations of multisampled images
This commit is contained in:
Fernando S 2021-07-19 03:21:03 +02:00 committed by GitHub
commit 41f4edd256
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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>
} }
[[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>
} }
[[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 {
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
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);
} }