rasterizer_cache: Improve validation skip heuristic (#69)

This commit is contained in:
GPUCode 2024-04-10 23:00:53 +03:00 committed by GitHub
parent f5cf180cee
commit 9dfe3eb4bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 10 additions and 24 deletions

View file

@ -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>

View file

@ -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);