mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-26 03:40:06 +00:00
rasterizer_cache: Make reinterpretation stricter (#6515)
This commit is contained in:
parent
2035433159
commit
f9ab0b3042
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user