mirror of
https://github.com/PabloMK7/citra.git
synced 2024-11-24 16:34:24 +00:00
rasterizer_cache: Make reinterpretation stricter (#6515)
This commit is contained in:
parent
2035433159
commit
f9ab0b3042
2 changed files with 16 additions and 23 deletions
|
@ -1131,38 +1131,30 @@ void RasterizerCache<T>::DownloadFillSurface(Surface& surface, SurfaceInterval i
|
|||
template <class T>
|
||||
bool RasterizerCache<T>::ValidateByReinterpretation(Surface& surface, SurfaceParams params,
|
||||
const SurfaceInterval& interval) {
|
||||
const bool is_gpu_modified = boost::icl::contains(dirty_regions, interval);
|
||||
SurfaceId reinterpret_id =
|
||||
FindMatch<MatchFlags::Reinterpret>(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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue