mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 10:10:14 +00:00
Res cache fixes (#6838)
* rasterizer_cache: Dont consider res_scale during recycle * rasterizer_cache: Switch to plain erase loop * rasterizer_cache: Fix crash due to memory corruption
This commit is contained in:
parent
88ea66053e
commit
6f7612f73d
@ -1051,15 +1051,15 @@ bool RasterizerCache<T>::UploadCustomSurface(SurfaceId surface_id, SurfaceInterv
|
||||
surface.flags |= SurfaceFlagBits::Custom;
|
||||
|
||||
const auto upload = [this, level, surface_id, material]() -> bool {
|
||||
Surface& surface = slot_surfaces[surface_id];
|
||||
ASSERT_MSG(True(surface.flags & SurfaceFlagBits::Custom),
|
||||
ASSERT_MSG(True(slot_surfaces[surface_id].flags & SurfaceFlagBits::Custom),
|
||||
"Surface is not suitable for custom upload, aborting!");
|
||||
if (!surface.IsCustom()) {
|
||||
const SurfaceBase old_surface{surface};
|
||||
if (!slot_surfaces[surface_id].IsCustom()) {
|
||||
const SurfaceBase old_surface{slot_surfaces[surface_id]};
|
||||
const SurfaceId old_id =
|
||||
slot_surfaces.swap_and_insert(surface_id, runtime, old_surface, material);
|
||||
sentenced.emplace_back(old_id, frame_tick);
|
||||
}
|
||||
Surface& surface = slot_surfaces[surface_id];
|
||||
surface.UploadCustom(material, level);
|
||||
if (custom_tex_manager.SkipMipmaps()) {
|
||||
runtime.GenerateMipmaps(surface);
|
||||
@ -1316,14 +1316,17 @@ SurfaceId RasterizerCache<T>::CreateSurface(const SurfaceParams& params) {
|
||||
const auto it = std::find_if(sentenced.begin(), sentenced.end(), [&](const auto& pair) {
|
||||
return slot_surfaces[pair.first] == params;
|
||||
});
|
||||
if (it != sentenced.end()) {
|
||||
const SurfaceId surface_id = it->first;
|
||||
sentenced.erase(it);
|
||||
return surface_id;
|
||||
if (it == sentenced.end()) {
|
||||
return slot_surfaces.insert(runtime, params);
|
||||
}
|
||||
return slot_surfaces.insert(runtime, params);
|
||||
const SurfaceId surface_id = it->first;
|
||||
sentenced.erase(it);
|
||||
return surface_id;
|
||||
}();
|
||||
Surface& surface = slot_surfaces[surface_id];
|
||||
if (params.res_scale > surface.res_scale) {
|
||||
surface.ScaleUp(params.res_scale);
|
||||
}
|
||||
surface.MarkInvalid(surface.GetInterval());
|
||||
return surface_id;
|
||||
}
|
||||
@ -1368,8 +1371,8 @@ void RasterizerCache<T>::UnregisterSurface(SurfaceId surface_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::erase_if(texture_cube_cache, [&](auto& pair) {
|
||||
TextureCube& cube = pair.second;
|
||||
for (auto it = texture_cube_cache.begin(); it != texture_cube_cache.end();) {
|
||||
TextureCube& cube = it->second;
|
||||
for (SurfaceId& face_id : cube.face_ids) {
|
||||
if (face_id == surface_id) {
|
||||
face_id = SurfaceId{};
|
||||
@ -1378,10 +1381,11 @@ void RasterizerCache<T>::UnregisterSurface(SurfaceId surface_id) {
|
||||
if (std::none_of(cube.face_ids.begin(), cube.face_ids.end(),
|
||||
[](SurfaceId id) { return id; })) {
|
||||
sentenced.emplace_back(cube.surface_id, frame_tick);
|
||||
return true;
|
||||
it = texture_cube_cache.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
@ -227,4 +227,11 @@ std::string SurfaceParams::DebugName(bool scaled, bool custom) const noexcept {
|
||||
custom ? "custom," : "", scaled ? "scaled" : "unscaled");
|
||||
}
|
||||
|
||||
bool SurfaceParams::operator==(const SurfaceParams& other) const noexcept {
|
||||
return std::tie(addr, end, width, height, stride, levels, is_tiled, texture_type, pixel_format,
|
||||
custom_format) ==
|
||||
std::tie(other.addr, other.end, other.width, other.height, other.stride, other.levels,
|
||||
other.is_tiled, other.texture_type, other.pixel_format, other.custom_format);
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
@ -53,9 +53,7 @@ public:
|
||||
/// Returns a string identifier of the params object
|
||||
std::string DebugName(bool scaled, bool custom = false) const noexcept;
|
||||
|
||||
bool operator==(const SurfaceParams& other) const noexcept {
|
||||
return std::memcmp(this, &other, sizeof(SurfaceParams)) == 0;
|
||||
}
|
||||
bool operator==(const SurfaceParams& other) const noexcept;
|
||||
|
||||
[[nodiscard]] SurfaceInterval GetInterval() const noexcept {
|
||||
return SurfaceInterval{addr, end};
|
||||
|
Loading…
Reference in New Issue
Block a user