graphics: track HTile clears across PS5 depth array slices

Co-authored-by: fxpw <fxpw@outlook.com>
This commit is contained in:
nmzik
2026-10-15 00:45:03 +02:00
parent 12c522bba5
commit 279bc95941
5 changed files with 128 additions and 33 deletions
+13 -13
View File
@@ -692,7 +692,7 @@ ImageId TextureCache::ResolveDepthOverlap(const ImageInfo& requested, BindingTyp
info.linear_slice_stride = cached.info.linear_slice_stride;
info.first_tail_level = cached.info.first_tail_level;
}
info.htile_clear_mask = 0;
info.htile_initial_clear = false;
const auto replacement_id = InsertImage(info);
auto& replacement = m_slot_images[replacement_id];
replacement.usage = cached.usage;
@@ -1416,9 +1416,13 @@ vk::ImageView TextureCache::FindDepthTarget(ImageId id, const ImageDesc& desc) {
image.info.stencil = desc.info.stencil;
image.info.metadata = desc.info.metadata;
if (desc.info.HasMetadata()) {
m_surface_metas.emplace(desc.info.metadata.range.address,
MetaDataInfo {.type = MetaDataInfo::Type::HTile,
.clear_mask = image.info.htile_clear_mask});
const auto [metadata, inserted] = m_surface_metas.try_emplace(desc.info.metadata.range.address);
if (inserted) {
metadata->second.type = MetaDataInfo::Type::HTile;
if (image.info.htile_initial_clear) {
metadata->second.clear_mask.set();
}
}
}
RefreshImage(id);
CommitGpuWrite(image);
@@ -1841,10 +1845,10 @@ bool TextureCache::IsMeta(uint64_t address) {
bool TextureCache::IsMetaCleared(uint64_t address, uint32_t slice) {
std::scoped_lock lock {m_lock};
const auto found = m_surface_metas.find(address);
if (found == m_surface_metas.end() || slice >= 32) {
if (found == m_surface_metas.end() || slice >= found->second.clear_mask.size()) {
return false;
}
return (found->second.clear_mask & (1u << slice)) != 0;
return found->second.clear_mask.test(slice);
}
bool TextureCache::ClearMeta(uint64_t address) {
@@ -1853,21 +1857,17 @@ bool TextureCache::ClearMeta(uint64_t address) {
if (found == m_surface_metas.end()) {
return false;
}
found->second.clear_mask = UINT32_MAX;
found->second.clear_mask.set();
return true;
}
bool TextureCache::TouchMeta(uint64_t address, uint32_t slice, bool is_clear) {
std::scoped_lock lock {m_lock};
const auto found = m_surface_metas.find(address);
if (found == m_surface_metas.end() || slice >= 32) {
if (found == m_surface_metas.end() || slice >= found->second.clear_mask.size()) {
return false;
}
if (is_clear) {
found->second.clear_mask |= 1u << slice;
} else {
found->second.clear_mask &= ~(1u << slice);
}
found->second.clear_mask.set(slice, is_clear);
return true;
}
+4 -2
View File
@@ -12,6 +12,7 @@
#include "graphics/host_gpu/renderer/image/image.h"
#include "graphics/host_gpu/renderer/image/tiler.h"
#include <bitset>
#include <map>
#include <type_traits>
#include <unordered_set>
@@ -82,8 +83,9 @@ private:
struct MetaDataInfo {
enum class Type : uint8_t { CMask, FMask, HTile };
Type type;
uint32_t clear_mask = UINT32_MAX;
Type type;
// PS5 DB_DEPTH_VIEW encodes 13-bit base and last array-slice indices.
std::bitset<8192> clear_mask;
};
struct OverlapResult {
@@ -177,9 +177,6 @@ static TextureCache::ImageDesc MakeDepthTargetDesc(const CommandBuffer& buffer,
if (z.htile_data_base_addr == 0 || (z.htile_data_base_addr & 0x7fffu) != 0) {
DepthFatal("invalid HTile metadata address");
}
if (z.depth_view.slice_max >= 32) {
DepthFatal("HTile clear tracking supports at most 32 slices");
}
}
if (!z.size.valid) {
DepthFatal("missing depth extent");
@@ -69,7 +69,7 @@ struct ImageInfo {
GuestRange data;
GuestRange stencil;
ImageMetadataInfo metadata;
uint32_t htile_clear_mask = UINT32_MAX;
bool htile_initial_clear = true;
vk::Format pixel_format = vk::Format::eUndefined;
Prospero::BufferFormat guest_format = Prospero::BufferFormat::kInvalid;
Prospero::ImageType type = Prospero::ImageType::kColor2D;