mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-22 03:46:53 +02:00
graphics: avoid full-cache scans when deleting stencil associations
Co-authored-by: overlordxrz-source <overlordxrz-source@users.noreply.github.com> Co-authored-by: TheCruZ <thecruzwtf@gmail.com>
This commit is contained in:
+12
-8
@@ -25,6 +25,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
#include <vulkan/vulkan_format_traits.hpp>
|
#include <vulkan/vulkan_format_traits.hpp>
|
||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
@@ -251,14 +252,11 @@ void TextureCache::DeleteImage(ImageId id) {
|
|||||||
if (image == nullptr || !image->registered) {
|
if (image == nullptr || !image->registered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!image->depth_id) {
|
if (image->depth_id) {
|
||||||
std::vector<ImageId> associations;
|
std::erase(m_slot_images[image->depth_id].stencil_ids, id);
|
||||||
m_slot_images.ForEach([&](ImageId candidate, const Image& associated) {
|
} else {
|
||||||
if (associated.depth_id == id) {
|
// Detach first: deleting each association also unlinks it from its depth owner.
|
||||||
associations.push_back(candidate);
|
for (const auto association: std::exchange(image->stencil_ids, {})) {
|
||||||
}
|
|
||||||
});
|
|
||||||
for (const auto association: associations) {
|
|
||||||
FreeImage(association);
|
FreeImage(association);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1205,6 +1203,12 @@ ImageId TextureCache::AssociateStencil(ImageId depth_id, GuestRange stencil) {
|
|||||||
plane.IsTiled() ? TileGetDepthPitch(plane.extent.width, 1, 0) : depth.info.pitch;
|
plane.IsTiled() ? TileGetDepthPitch(plane.extent.width, 1, 0) : depth.info.pitch;
|
||||||
plane.bytes_per_block = 1;
|
plane.bytes_per_block = 1;
|
||||||
plane.UpdateSize();
|
plane.UpdateSize();
|
||||||
|
if (record.depth_id != depth_id) {
|
||||||
|
if (record.depth_id) {
|
||||||
|
std::erase(m_slot_images[record.depth_id].stencil_ids, association);
|
||||||
|
}
|
||||||
|
depth.stencil_ids.push_back(association);
|
||||||
|
}
|
||||||
record.info = plane;
|
record.info = plane;
|
||||||
record.depth_id = depth_id;
|
record.depth_id = depth_id;
|
||||||
record.stencil_subresources = depth.stencil_subresources;
|
record.stencil_subresources = depth.stencil_subresources;
|
||||||
|
|||||||
@@ -149,6 +149,8 @@ public:
|
|||||||
uint64_t track_addr = 0;
|
uint64_t track_addr = 0;
|
||||||
uint64_t track_addr_end = 0;
|
uint64_t track_addr_end = 0;
|
||||||
ImageId depth_id {};
|
ImageId depth_id {};
|
||||||
|
// Stencil associations that refer to this depth image.
|
||||||
|
std::vector<ImageId> stencil_ids;
|
||||||
// The current stencil plane's mapping into the depth image, also retained by its association.
|
// The current stencil plane's mapping into the depth image, also retained by its association.
|
||||||
ImageSubresourceRange stencil_subresources;
|
ImageSubresourceRange stencil_subresources;
|
||||||
uint64_t tick_accessed_last = 0;
|
uint64_t tick_accessed_last = 0;
|
||||||
|
|||||||
@@ -8240,9 +8240,11 @@ public:
|
|||||||
texture_cache.UnmapMemory(ms_depth_desc.info.data.address,
|
texture_cache.UnmapMemory(ms_depth_desc.info.data.address,
|
||||||
ms_depth_desc.info.data.size);
|
ms_depth_desc.info.data.size);
|
||||||
Require(name, "depth unmap proxy retirement",
|
Require(name, "depth unmap proxy retirement",
|
||||||
!texture_cache.FindImageFromRange(base + second_stencil_offset,
|
!texture_cache.FindImageFromRange(base + ms_stencil_offset,
|
||||||
ms_stencil_size, false),
|
ms_stencil_size, false) &&
|
||||||
"unmapping depth retained its re-associated stencil proxy");
|
!texture_cache.FindImageFromRange(base + second_stencil_offset,
|
||||||
|
ms_stencil_size, false),
|
||||||
|
"unmapping depth retained one of its stencil proxies");
|
||||||
|
|
||||||
auto reused_stencil_color = MakeLinearDesc(
|
auto reused_stencil_color = MakeLinearDesc(
|
||||||
base + 0x2200000, 0x40000, vk::Format::eR8Unorm,
|
base + 0x2200000, 0x40000, vk::Format::eR8Unorm,
|
||||||
@@ -8297,8 +8299,31 @@ public:
|
|||||||
ReadCachedTexel(name, context, reused_stencil_color_id, {},
|
ReadCachedTexel(name, context, reused_stencil_color_id, {},
|
||||||
{4, 1, 1}) == std::vector<u32>{0xffffffffu},
|
{4, 1, 1}) == std::vector<u32>{0xffffffffu},
|
||||||
"stencil address reuse changed the native R8 clear contents");
|
"stencil address reuse changed the native R8 clear contents");
|
||||||
|
auto successor_depth = reused_stencil_depth;
|
||||||
|
successor_depth.info.data.address += successor_depth.info.data.size;
|
||||||
|
const auto successor_depth_id = texture_cache.FindImage(successor_depth);
|
||||||
|
TextureCacheTestAccess::AssociateStencil(
|
||||||
|
texture_cache, successor_depth_id, successor_depth.info.stencil);
|
||||||
texture_cache.UnmapMemory(reused_stencil_depth.info.data.address,
|
texture_cache.UnmapMemory(reused_stencil_depth.info.data.address,
|
||||||
reused_stencil_depth.info.data.size);
|
reused_stencil_depth.info.data.size);
|
||||||
|
Require(name, "reparented stencil survives old depth retirement",
|
||||||
|
!TextureCacheTestAccess::Contains(texture_cache,
|
||||||
|
reused_stencil_depth_id) &&
|
||||||
|
TextureCacheTestAccess::Contains(texture_cache,
|
||||||
|
successor_depth_id) &&
|
||||||
|
texture_cache.FindImageFromRange(
|
||||||
|
successor_depth.info.stencil.address,
|
||||||
|
successor_depth.info.stencil.size, false) ==
|
||||||
|
reused_stencil_proxy &&
|
||||||
|
texture_cache.GetImage(reused_stencil_proxy).depth_id ==
|
||||||
|
successor_depth_id,
|
||||||
|
"retiring the previous depth owner removed its reparented proxy");
|
||||||
|
texture_cache.UnmapMemory(successor_depth.info.data.address,
|
||||||
|
successor_depth.info.data.size);
|
||||||
|
Require(name, "reparented stencil retires with new depth",
|
||||||
|
!TextureCacheTestAccess::Contains(texture_cache,
|
||||||
|
reused_stencil_proxy),
|
||||||
|
"retiring the new depth owner retained its reparented proxy");
|
||||||
texture_cache.UnmapMemory(reused_stencil_color.info.data.address,
|
texture_cache.UnmapMemory(reused_stencil_color.info.data.address,
|
||||||
reused_stencil_color.info.data.size);
|
reused_stencil_color.info.data.size);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user