mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
textures: handle DCC memory reused as HTile
This commit is contained in:
1 parent
99a87bd65b
commit
6ca8201982
2 files changed
+64
-10
No files matched your search
+14
-10
@@ -328,7 +328,15 @@ void TextureCache::DeleteImage(ImageId id) {
|
||||
}
|
||||
m_download_images.erase(id);
|
||||
if (image->info.HasMetadata()) {
|
||||
m_surface_metas.erase(image->info.metadata.range.address);
|
||||
const auto metadata = m_surface_metas.find(image->info.metadata.range.address);
|
||||
if (metadata != m_surface_metas.end() &&
|
||||
((image->info.metadata.kind == ImageMetadataKind::Dcc &&
|
||||
metadata->second.type == MetaDataInfo::Type::Dcc) ||
|
||||
(image->info.metadata.kind == ImageMetadataKind::Htile &&
|
||||
metadata->second.type == MetaDataInfo::Type::HTile))) {
|
||||
// A later binding may have reused this address for another metadata type.
|
||||
m_surface_metas.erase(metadata);
|
||||
}
|
||||
}
|
||||
UnregisterImage(id);
|
||||
if (m_scheduler.Active()) {
|
||||
@@ -1436,15 +1444,11 @@ vk::ImageView TextureCache::FindDepthTarget(ImageId id, const ImageDesc& desc) {
|
||||
m_surface_metas.try_emplace(desc.info.metadata.range.address,
|
||||
MetaDataInfo {.type = MetaDataInfo::Type::HTile,
|
||||
.clear_mask = image.info.htile_clear_mask});
|
||||
if (!inserted && metadata->second.type == MetaDataInfo::Type::PendingDcc) {
|
||||
// PendingDcc fills use DCC-specific encoding. Do not reinterpret a speculative
|
||||
// DCC/buffer fill as HTile state if the address is later classified as depth metadata.
|
||||
metadata->second.type = MetaDataInfo::Type::HTile;
|
||||
metadata->second.clear_mask = image.info.htile_clear_mask;
|
||||
metadata->second.fill_value = 0xffffffffu;
|
||||
metadata->second.fill_size = 0;
|
||||
} else if (!inserted && metadata->second.type != MetaDataInfo::Type::HTile) {
|
||||
EXIT("TextureCache: depth target reuses non-HTile metadata\n");
|
||||
if (!inserted && metadata->second.type != MetaDataInfo::Type::HTile) {
|
||||
// PS5 allocations can reuse DCC storage as HTile while the old color image is cached.
|
||||
// The depth binding defines the new type; incompatible fill state cannot carry over.
|
||||
metadata->second = {.type = MetaDataInfo::Type::HTile,
|
||||
.clear_mask = image.info.htile_clear_mask};
|
||||
}
|
||||
}
|
||||
CommitGpuWrite(image);
|
||||
|
||||
@@ -6025,6 +6025,56 @@ public:
|
||||
texture_cache.IsMetaCleared(base + metadata_b, 0),
|
||||
"BufferCache fill did not publish an exact-address metadata clear");
|
||||
|
||||
// R-Type Final 3 reuses an old color allocation inside a new stencil plane,
|
||||
// with the same metadata address changing from DCC to HTile.
|
||||
auto reused_depth = MakeMetadataDepth(0x12300, 0x13200);
|
||||
reused_depth.info.pixel_format = vk::Format::eD32SfloatS8Uint;
|
||||
reused_depth.info.stencil = {base + 0x12200, 0x80};
|
||||
reused_depth.info.htile_clear_mask = 0;
|
||||
reused_depth.view_info.format = vk::Format::eD32SfloatS8Uint;
|
||||
reused_depth.view_info.aspect = vk::ImageAspectFlagBits::eDepth |
|
||||
vk::ImageAspectFlagBits::eStencil;
|
||||
auto reused_color = MakeLinearDesc(
|
||||
base + 0x12240, sizeof(uint32_t), vk::Format::eR8G8B8A8Unorm,
|
||||
Prospero::BufferFormat::k8_8_8_8UNorm, Prospero::ImageType::kColor2D,
|
||||
{1, 1, 1}, 1, 4, 1);
|
||||
reused_color.type = BindingType::RenderTarget;
|
||||
reused_color.info.metadata.kind = ImageMetadataKind::Dcc;
|
||||
reused_color.info.metadata.range = {base + 0x13200, 0x20};
|
||||
reused_color.view_info.usage = vk::ImageUsageFlagBits::eColorAttachment;
|
||||
const auto reused_color_id = texture_cache.FindImage(reused_color);
|
||||
(void)texture_cache.FindRenderTarget(reused_color_id, reused_color);
|
||||
texture_cache.TrackDccFill(base + 0x13200, 0x80, 0);
|
||||
texture_cache.InvalidateMemoryFromGPU(reused_depth.info.stencil.address,
|
||||
reused_depth.info.stencil.size);
|
||||
const auto reused_depth_id = texture_cache.FindImage(reused_depth);
|
||||
(void)texture_cache.FindDepthTarget(reused_depth_id, reused_depth);
|
||||
uint32_t reused_fill = 0;
|
||||
Require(
|
||||
name, "DCC allocation reused as HTile",
|
||||
TextureCacheTestAccess::Contains(texture_cache, reused_color_id) &&
|
||||
texture_cache.GetImage(reused_color_id).IsBufferModified() &&
|
||||
!texture_cache.GetImage(reused_color_id).IsGpuModified() &&
|
||||
!texture_cache.IsMetaCleared(base + 0x13200, 0, &reused_fill) &&
|
||||
reused_fill == UINT32_MAX &&
|
||||
texture_cache.ClearMeta(base + 0x13200) &&
|
||||
texture_cache.TouchMeta(base + 0x13200, 0, false),
|
||||
"depth binding retained incompatible DCC clear state");
|
||||
TextureCacheTestAccess::DeleteImage(texture_cache, reused_color_id);
|
||||
(void)texture_cache.FindDepthTarget(reused_depth_id, reused_depth);
|
||||
Require(
|
||||
name, "reused metadata owner retirement",
|
||||
!TextureCacheTestAccess::Contains(texture_cache, reused_color_id) &&
|
||||
texture_cache.IsMeta(base + 0x13200) &&
|
||||
!texture_cache.IsMetaCleared(base + 0x13200, 0) &&
|
||||
texture_cache.IsMetaCleared(base + 0x13200, 1),
|
||||
"retiring the old DCC image erased the live HTile slice state");
|
||||
texture_cache.UnmapMemory(reused_depth.info.data.address,
|
||||
reused_depth.info.data.size);
|
||||
Require(name, "reused metadata final retirement",
|
||||
!texture_cache.IsMeta(base + 0x13200),
|
||||
"retiring the HTile image left its metadata registered");
|
||||
|
||||
constexpr uint64_t partial_unmap_image_offset = 0x2700000;
|
||||
auto partial_unmap_image =
|
||||
MakeLinearDesc(base + partial_unmap_image_offset, 0x2000,
|
||||
|
||||
Reference in new issue
Block a user