From f9ab0b3042a47fb535470c7d8792306c02526128 Mon Sep 17 00:00:00 2001 From: GPUCode <47210458+GPUCode@users.noreply.github.com> Date: Sun, 7 May 2023 23:13:01 +0300 Subject: [PATCH] rasterizer_cache: Make reinterpretation stricter (#6515) --- .../rasterizer_cache/rasterizer_cache.h | 34 +++++++------------ .../rasterizer_cache/surface_params.cpp | 5 +-- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.h b/src/video_core/rasterizer_cache/rasterizer_cache.h index cf387aa43..b942e5d6e 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache.h @@ -1131,38 +1131,30 @@ void RasterizerCache::DownloadFillSurface(Surface& surface, SurfaceInterval i template bool RasterizerCache::ValidateByReinterpretation(Surface& surface, SurfaceParams params, const SurfaceInterval& interval) { - const bool is_gpu_modified = boost::icl::contains(dirty_regions, interval); SurfaceId reinterpret_id = FindMatch(params, ScaleMatch::Ignore, interval); if (reinterpret_id) { Surface& src_surface = slot_surfaces[reinterpret_id]; - if (src_surface.stride == surface.stride) { - const SurfaceInterval copy_interval = src_surface.GetCopyableInterval(params); - if (boost::icl::is_empty(copy_interval)) { - return false; - } - const PAddr addr = boost::icl::lower(interval); - const SurfaceParams copy_params = surface.FromInterval(copy_interval); - const TextureBlit reinterpret = { - .src_level = src_surface.LevelOf(addr), - .dst_level = surface.LevelOf(addr), - .src_rect = src_surface.GetScaledSubRect(copy_params), - .dst_rect = surface.GetScaledSubRect(copy_params), - }; - return runtime.Reinterpret(src_surface, surface, reinterpret); + const SurfaceInterval copy_interval = src_surface.GetCopyableInterval(params); + if (boost::icl::is_empty(copy_interval)) { + return false; } - LOG_INFO(HW_GPU, "Unimplemented dimentional reinterpretatation {}x{} -> {}x{}", - src_surface.width, src_surface.height, surface.width, surface.height); - // A surface with matching bit width was found but couldn't be reinterpreted - // due to mismatching stride. It's probably a developer mistake so skip flushing - // if it was created on the GPU. - return is_gpu_modified; + const PAddr addr = boost::icl::lower(interval); + const SurfaceParams copy_params = surface.FromInterval(copy_interval); + const TextureBlit reinterpret = { + .src_level = src_surface.LevelOf(addr), + .dst_level = surface.LevelOf(addr), + .src_rect = src_surface.GetScaledSubRect(copy_params), + .dst_rect = surface.GetScaledSubRect(copy_params), + }; + return runtime.Reinterpret(src_surface, surface, reinterpret); } // No surfaces were found in the cache that had a matching bit-width. // If there's a surface with invalid format it means the region was cleared // so we don't want to skip validation in that case. const bool has_invalid = IntervalHasInvalidPixelFormat(params, interval); + const bool is_gpu_modified = boost::icl::contains(dirty_regions, interval); return !has_invalid && is_gpu_modified; } diff --git a/src/video_core/rasterizer_cache/surface_params.cpp b/src/video_core/rasterizer_cache/surface_params.cpp index b34ddee21..de630e804 100644 --- a/src/video_core/rasterizer_cache/surface_params.cpp +++ b/src/video_core/rasterizer_cache/surface_params.cpp @@ -28,8 +28,9 @@ bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const { bool SurfaceParams::CanReinterpret(const SurfaceParams& other_surface) { return other_surface.addr >= addr && other_surface.end <= end && pixel_format != PixelFormat::Invalid && GetFormatBpp() == other_surface.GetFormatBpp() && - other_surface.is_tiled == is_tiled && - (other_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0; + other_surface.is_tiled == is_tiled && other_surface.stride == stride && + (other_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 && + GetSubRect(other_surface).right <= stride; } bool SurfaceParams::CanExpand(const SurfaceParams& expanded_surface) const {