mirror of
https://github.com/PabloMK7/citra
synced 2024-11-15 05:08:23 +00:00
rasterizer_cache: Improve validation skip heuristic (#69)
This commit is contained in:
parent
f5cf180cee
commit
9dfe3eb4bc
2 changed files with 10 additions and 24 deletions
|
@ -1180,27 +1180,16 @@ bool RasterizerCache<T>::ValidateByReinterpretation(Surface& surface, SurfacePar
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
// Before entering the slow path, check if part of the interval is owned
|
||||||
// so we don't want to skip validation in that case.
|
// by a gpu modified surface with a different stride than ours. This is indicative
|
||||||
const bool has_invalid = IntervalHasInvalidPixelFormat(params, interval);
|
// of texture aliasing by the guest, which for the vast majority of cases we don't
|
||||||
const bool is_gpu_modified = boost::icl::contains(dirty_regions, interval);
|
// need to validate.
|
||||||
return !has_invalid && is_gpu_modified;
|
// TODO: While this works for the vast majority of cases, in Fire Emblem: Shadows of Valentia
|
||||||
}
|
// the warping effect when running in dugeons relies on this stride reinterpretation.
|
||||||
|
// In the future this transformation should be properly implemented with a GPU shader.
|
||||||
template <class T>
|
const auto it = dirty_regions.find(interval);
|
||||||
bool RasterizerCache<T>::IntervalHasInvalidPixelFormat(const SurfaceParams& params,
|
return it != dirty_regions.end() && it->second &&
|
||||||
SurfaceInterval interval) {
|
slot_surfaces[it->second].stride != surface.stride;
|
||||||
bool invalid_format_found = false;
|
|
||||||
const PAddr addr = boost::icl::lower(interval);
|
|
||||||
const u32 size = boost::icl::length(interval);
|
|
||||||
ForEachSurfaceInRegion(addr, size, [&](SurfaceId surface_id, Surface& surface) {
|
|
||||||
if (surface.pixel_format == PixelFormat::Invalid) {
|
|
||||||
invalid_format_found = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
return invalid_format_found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
@ -193,9 +193,6 @@ private:
|
||||||
bool ValidateByReinterpretation(Surface& surface, SurfaceParams params,
|
bool ValidateByReinterpretation(Surface& surface, SurfaceParams params,
|
||||||
const SurfaceInterval& interval);
|
const SurfaceInterval& interval);
|
||||||
|
|
||||||
/// Return true if a surface with an invalid pixel format exists at the interval
|
|
||||||
bool IntervalHasInvalidPixelFormat(const SurfaceParams& params, SurfaceInterval interval);
|
|
||||||
|
|
||||||
/// Create a new surface
|
/// Create a new surface
|
||||||
SurfaceId CreateSurface(const SurfaceParams& params);
|
SurfaceId CreateSurface(const SurfaceParams& params);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue