citra-emu
/
citra-canary
Archived
1
0
Fork 0

rasterizer_cache: Make reinterpretation stricter (#6515)

This commit is contained in:
GPUCode 2023-05-07 23:13:01 +03:00 committed by GitHub
parent 2035433159
commit f9ab0b3042
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 23 deletions

View File

@ -1131,38 +1131,30 @@ void RasterizerCache<T>::DownloadFillSurface(Surface& surface, SurfaceInterval i
template <class T> template <class T>
bool RasterizerCache<T>::ValidateByReinterpretation(Surface& surface, SurfaceParams params, bool RasterizerCache<T>::ValidateByReinterpretation(Surface& surface, SurfaceParams params,
const SurfaceInterval& interval) { const SurfaceInterval& interval) {
const bool is_gpu_modified = boost::icl::contains(dirty_regions, interval);
SurfaceId reinterpret_id = SurfaceId reinterpret_id =
FindMatch<MatchFlags::Reinterpret>(params, ScaleMatch::Ignore, interval); FindMatch<MatchFlags::Reinterpret>(params, ScaleMatch::Ignore, interval);
if (reinterpret_id) { if (reinterpret_id) {
Surface& src_surface = slot_surfaces[reinterpret_id]; Surface& src_surface = slot_surfaces[reinterpret_id];
if (src_surface.stride == surface.stride) { const SurfaceInterval copy_interval = src_surface.GetCopyableInterval(params);
const SurfaceInterval copy_interval = src_surface.GetCopyableInterval(params); if (boost::icl::is_empty(copy_interval)) {
if (boost::icl::is_empty(copy_interval)) { return false;
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);
} }
LOG_INFO(HW_GPU, "Unimplemented dimentional reinterpretatation {}x{} -> {}x{}", const PAddr addr = boost::icl::lower(interval);
src_surface.width, src_surface.height, surface.width, surface.height); const SurfaceParams copy_params = surface.FromInterval(copy_interval);
// A surface with matching bit width was found but couldn't be reinterpreted const TextureBlit reinterpret = {
// due to mismatching stride. It's probably a developer mistake so skip flushing .src_level = src_surface.LevelOf(addr),
// if it was created on the GPU. .dst_level = surface.LevelOf(addr),
return is_gpu_modified; .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. // 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 // 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. // so we don't want to skip validation in that case.
const bool has_invalid = IntervalHasInvalidPixelFormat(params, interval); const bool has_invalid = IntervalHasInvalidPixelFormat(params, interval);
const bool is_gpu_modified = boost::icl::contains(dirty_regions, interval);
return !has_invalid && is_gpu_modified; return !has_invalid && is_gpu_modified;
} }

View File

@ -28,8 +28,9 @@ bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const {
bool SurfaceParams::CanReinterpret(const SurfaceParams& other_surface) { bool SurfaceParams::CanReinterpret(const SurfaceParams& other_surface) {
return other_surface.addr >= addr && other_surface.end <= end && return other_surface.addr >= addr && other_surface.end <= end &&
pixel_format != PixelFormat::Invalid && GetFormatBpp() == other_surface.GetFormatBpp() && pixel_format != PixelFormat::Invalid && GetFormatBpp() == other_surface.GetFormatBpp() &&
other_surface.is_tiled == is_tiled && other_surface.is_tiled == is_tiled && other_surface.stride == stride &&
(other_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0; (other_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 &&
GetSubRect(other_surface).right <= stride;
} }
bool SurfaceParams::CanExpand(const SurfaceParams& expanded_surface) const { bool SurfaceParams::CanExpand(const SurfaceParams& expanded_surface) const {