From e0407212406c37eef441b3513dbe37afbf9f6492 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Thu, 17 Jul 2025 00:41:23 +0300 Subject: [PATCH] texture_cache: Clamp buffer image height to microtile height --- src/video_core/buffer_cache/buffer_cache.cpp | 6 +++--- .../texture_cache/texture_cache.cpp | 19 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index 42e3c61a5..c5e5d18f8 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -961,15 +961,15 @@ bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, const u32 height = std::max(image.info.size.height >> m, 1u); const u32 depth = image.info.props.is_volume ? std::max(image.info.size.depth >> m, 1u) : 1u; - const auto& [mip_size, mip_pitch, mip_height, mip_ofs] = image.info.mips_layout[m]; + const auto [mip_size, mip_pitch, mip_height, mip_ofs] = image.info.mips_layout[m]; offset += mip_ofs; if (offset + mip_size > max_offset) { break; } copies.push_back({ .bufferOffset = offset, - .bufferRowLength = static_cast(mip_pitch), - .bufferImageHeight = static_cast(mip_height), + .bufferRowLength = mip_pitch, + .bufferImageHeight = mip_height, .imageSubresource{ .aspectMask = image.aspect_mask & ~vk::ImageAspectFlagBits::eStencil, .mipLevel = m, diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index a6657d8d9..fa24728ad 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -605,28 +605,27 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule const u32 height = std::max(image.info.size.height >> m, 1u); const u32 depth = image.info.props.is_volume ? std::max(image.info.size.depth >> m, 1u) : 1u; - const auto& mip = image.info.mips_layout[m]; + const auto [mip_size, mip_pitch, mip_height, mip_offset] = image.info.mips_layout[m]; // Protect GPU modified resources from accidental CPU reuploads. if (is_gpu_modified && !is_gpu_dirty) { const u8* addr = std::bit_cast(image.info.guest_address); - const u64 hash = XXH3_64bits(addr + mip.offset, mip.size); + const u64 hash = XXH3_64bits(addr + mip_offset, mip_size); if (image.mip_hashes[m] == hash) { continue; } image.mip_hashes[m] = hash; } - auto mip_pitch = static_cast(mip.pitch); - auto mip_height = static_cast(mip.height); - - auto image_extent_width = mip_pitch ? std::min(mip_pitch, width) : width; - auto image_extent_height = mip_height ? std::min(mip_height, height) : height; + const u32 extent_width = mip_pitch ? std::min(mip_pitch, width) : width; + const u32 extent_height = mip_height ? std::min(mip_height, height) : height; + const u32 height_aligned = + mip_height && image.info.IsTiled() ? std::max(mip_height, 8U) : mip_height; image_copy.push_back({ - .bufferOffset = mip.offset, + .bufferOffset = mip_offset, .bufferRowLength = mip_pitch, - .bufferImageHeight = mip_height, + .bufferImageHeight = height_aligned, .imageSubresource{ .aspectMask = image.aspect_mask & ~vk::ImageAspectFlagBits::eStencil, .mipLevel = m, @@ -634,7 +633,7 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule .layerCount = num_layers, }, .imageOffset = {0, 0, 0}, - .imageExtent = {image_extent_width, image_extent_height, depth}, + .imageExtent = {extent_width, extent_height, depth}, }); }