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;
|
surface.flags |= SurfaceFlagBits::Custom;
|
||||||
|
|
||||||
const auto upload = [this, level, surface_id, material]() -> bool {
|
const auto upload = [this, level, surface_id, material]() -> bool {
|
||||||
Surface& surface = slot_surfaces[surface_id];
|
ASSERT_MSG(True(slot_surfaces[surface_id].flags & SurfaceFlagBits::Custom),
|
||||||
ASSERT_MSG(True(surface.flags & SurfaceFlagBits::Custom),
|
|
||||||
"Surface is not suitable for custom upload, aborting!");
|
"Surface is not suitable for custom upload, aborting!");
|
||||||
if (!surface.IsCustom()) {
|
if (!slot_surfaces[surface_id].IsCustom()) {
|
||||||
const SurfaceBase old_surface{surface};
|
const SurfaceBase old_surface{slot_surfaces[surface_id]};
|
||||||
const SurfaceId old_id =
|
const SurfaceId old_id =
|
||||||
slot_surfaces.swap_and_insert(surface_id, runtime, old_surface, material);
|
slot_surfaces.swap_and_insert(surface_id, runtime, old_surface, material);
|
||||||
sentenced.emplace_back(old_id, frame_tick);
|
sentenced.emplace_back(old_id, frame_tick);
|
||||||
}
|
}
|
||||||
|
Surface& surface = slot_surfaces[surface_id];
|
||||||
surface.UploadCustom(material, level);
|
surface.UploadCustom(material, level);
|
||||||
if (custom_tex_manager.SkipMipmaps()) {
|
if (custom_tex_manager.SkipMipmaps()) {
|
||||||
runtime.GenerateMipmaps(surface);
|
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) {
|
const auto it = std::find_if(sentenced.begin(), sentenced.end(), [&](const auto& pair) {
|
||||||
return slot_surfaces[pair.first] == params;
|
return slot_surfaces[pair.first] == params;
|
||||||
});
|
});
|
||||||
if (it != sentenced.end()) {
|
if (it == sentenced.end()) {
|
||||||
const SurfaceId surface_id = it->first;
|
return slot_surfaces.insert(runtime, params);
|
||||||
sentenced.erase(it);
|
|
||||||
return surface_id;
|
|
||||||
}
|
}
|
||||||
return slot_surfaces.insert(runtime, params);
|
const SurfaceId surface_id = it->first;
|
||||||
|
sentenced.erase(it);
|
||||||
|
return surface_id;
|
||||||
}();
|
}();
|
||||||
Surface& surface = slot_surfaces[surface_id];
|
Surface& surface = slot_surfaces[surface_id];
|
||||||
|
if (params.res_scale > surface.res_scale) {
|
||||||
|
surface.ScaleUp(params.res_scale);
|
||||||
|
}
|
||||||
surface.MarkInvalid(surface.GetInterval());
|
surface.MarkInvalid(surface.GetInterval());
|
||||||
return surface_id;
|
return surface_id;
|
||||||
}
|
}
|
||||||
|
@ -1368,8 +1371,8 @@ void RasterizerCache<T>::UnregisterSurface(SurfaceId surface_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::erase_if(texture_cube_cache, [&](auto& pair) {
|
for (auto it = texture_cube_cache.begin(); it != texture_cube_cache.end();) {
|
||||||
TextureCube& cube = pair.second;
|
TextureCube& cube = it->second;
|
||||||
for (SurfaceId& face_id : cube.face_ids) {
|
for (SurfaceId& face_id : cube.face_ids) {
|
||||||
if (face_id == surface_id) {
|
if (face_id == surface_id) {
|
||||||
face_id = SurfaceId{};
|
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(),
|
if (std::none_of(cube.face_ids.begin(), cube.face_ids.end(),
|
||||||
[](SurfaceId id) { return id; })) {
|
[](SurfaceId id) { return id; })) {
|
||||||
sentenced.emplace_back(cube.surface_id, frame_tick);
|
sentenced.emplace_back(cube.surface_id, frame_tick);
|
||||||
return true;
|
it = texture_cube_cache.erase(it);
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
@ -227,4 +227,11 @@ std::string SurfaceParams::DebugName(bool scaled, bool custom) const noexcept {
|
||||||
custom ? "custom," : "", scaled ? "scaled" : "unscaled");
|
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
|
} // namespace VideoCore
|
||||||
|
|
|
@ -53,9 +53,7 @@ public:
|
||||||
/// Returns a string identifier of the params object
|
/// Returns a string identifier of the params object
|
||||||
std::string DebugName(bool scaled, bool custom = false) const noexcept;
|
std::string DebugName(bool scaled, bool custom = false) const noexcept;
|
||||||
|
|
||||||
bool operator==(const SurfaceParams& other) const noexcept {
|
bool operator==(const SurfaceParams& other) const noexcept;
|
||||||
return std::memcmp(this, &other, sizeof(SurfaceParams)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] SurfaceInterval GetInterval() const noexcept {
|
[[nodiscard]] SurfaceInterval GetInterval() const noexcept {
|
||||||
return SurfaceInterval{addr, end};
|
return SurfaceInterval{addr, end};
|
||||||
|
|
Reference in New Issue