diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index a9ed7696004..8068aae2ff1 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -166,6 +166,7 @@ void ImageInfo::UpdateSize() { mip_w = std::max(mip_w, 1u); mip_h = std::max(mip_h, 1u); auto mip_d = std::max(size.depth >> mip, 1u); + auto thickness = 1; if (props.is_pow2) { mip_w = std::bit_ceil(mip_w); @@ -181,12 +182,13 @@ void ImageInfo::UpdateSize() { break; } case AmdGpu::TilingMode::Texture_Volume: - mip_d += (-mip_d) & 3u; + thickness = 4; + mip_d += (-mip_d) & (thickness - 1); [[fallthrough]]; case AmdGpu::TilingMode::Display_MicroTiled: case AmdGpu::TilingMode::Texture_MicroTiled: { std::tie(mip_info.pitch, mip_info.size) = - ImageSizeMicroTiled(mip_w, mip_h, bpp, num_samples); + ImageSizeMicroTiled(mip_w, mip_h, bpp, thickness, num_samples); mip_info.height = std::max(mip_h, 8u); if (props.is_block) { mip_info.pitch = std::max(mip_info.pitch * 4, 32u); @@ -198,8 +200,8 @@ void ImageInfo::UpdateSize() { case AmdGpu::TilingMode::Texture_MacroTiled: case AmdGpu::TilingMode::Depth_MacroTiled: { ASSERT(!props.is_block); - std::tie(mip_info.pitch, mip_info.size) = - ImageSizeMacroTiled(mip_w, mip_h, bpp, num_samples, tiling_idx, mip, alt_tile); + std::tie(mip_info.pitch, mip_info.size) = ImageSizeMacroTiled( + mip_w, mip_h, thickness, bpp, num_samples, tiling_idx, mip, alt_tile); break; } default: { diff --git a/src/video_core/texture_cache/tile.h b/src/video_core/texture_cache/tile.h index 532bf3d8868..c111e6aca31 100644 --- a/src/video_core/texture_cache/tile.h +++ b/src/video_core/texture_cache/tile.h @@ -308,20 +308,20 @@ constexpr std::pair ImageSizeLinearAligned(u32 pitch, u32 height, u return {pitch_aligned, (log_sz * bpp + 7) / 8}; } -constexpr std::pair ImageSizeMicroTiled(u32 pitch, u32 height, u32 bpp, +constexpr std::pair ImageSizeMicroTiled(u32 pitch, u32 height, u32 thickness, u32 bpp, u32 num_samples) { const auto& [pitch_align, height_align] = micro_tile_extent; auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1); const auto height_aligned = (height + height_align - 1) & ~(height_align - 1); - size_t log_sz = (pitch_aligned * height_aligned * bpp * num_samples + 7) / 8; + size_t log_sz = (pitch_aligned * height_aligned * bpp * num_samples * thickness + 7) / 8; while (log_sz % 256) { - pitch_aligned += 8; + pitch_aligned += pitch_align; log_sz = (pitch_aligned * height_aligned * bpp * num_samples + 7) / 8; } return {pitch_aligned, log_sz}; } -constexpr std::pair ImageSizeMacroTiled(u32 pitch, u32 height, u32 bpp, +constexpr std::pair ImageSizeMacroTiled(u32 pitch, u32 height, u32 thickness, u32 bpp, u32 num_samples, u32 tiling_idx, u32 mip_n, bool alt) { const auto& [pitch_align, height_align] = @@ -335,7 +335,7 @@ constexpr std::pair ImageSizeMacroTiled(u32 pitch, u32 height, u32 } if (downgrade_to_micro) { - return ImageSizeMicroTiled(pitch, height, bpp, num_samples); + return ImageSizeMicroTiled(pitch, height, thickness, bpp, num_samples); } const auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1);