revert HTile lifetime changes and opt-in ZMask support

This commit is contained in:
nmzik
2026-10-19 04:53:56 +02:00
parent e87fb8c859
commit 2c730e58ea
11 changed files with 10 additions and 159 deletions
+5 -119
View File
@@ -6522,11 +6522,6 @@ public:
htile_depth.view_info.aspect = vk::ImageAspectFlagBits::eDepth;
htile_depth.view_info.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment;
const auto htile_depth_image = texture_cache.FindImage(htile_depth);
(void)texture_cache.FindDepthTarget(htile_depth_image, htile_depth);
Require(name, "HTile depth metadata registration",
texture_cache.ClearMeta(htile_depth.info.metadata.range.address) &&
texture_cache.TouchMeta(htile_depth.info.metadata.range.address, 0, false),
"depth target did not register independent slice clear state");
vk::ClearValue htile_clear{};
htile_clear.depthStencil.depth = 0.25f;
TextureCacheTestAccess::ClearImage(
@@ -6560,11 +6555,6 @@ public:
Require(name, "HTile depth storage prefix view",
texture_cache.FindTexture(id, htile_storage) != nullptr,
"converted depth prefix has no storage view");
Require(name, "HTile metadata survives native depth replacement",
texture_cache.IsMeta(htile_depth.info.metadata.range.address) &&
!texture_cache.IsMetaCleared(htile_depth.info.metadata.range.address, 0) &&
texture_cache.IsMetaCleared(htile_depth.info.metadata.range.address, 1),
"storage conversion discarded guest metadata or its slice clear state");
htile_storage_image = id;
}
auto htile_readback = CreateHostBuffer(
@@ -6585,11 +6575,6 @@ public:
std::vector<u32>(htile_layers, std::bit_cast<u32>(0.25f)),
"partial storage conversion lost native depth data outside its view");
DestroyBuffer(&htile_readback);
texture_cache.UnmapMemory(htile_depth.info.metadata.range.address,
htile_depth.info.metadata.range.size);
Require(name, "HTile metadata allocation unmap",
!texture_cache.IsMeta(htile_depth.info.metadata.range.address),
"unmapped guest metadata retained its registration");
auto layered_stencil_desc = MakeLinearDesc(
base + 0x27d4000, 6 * 4 * sizeof(float),
@@ -7908,16 +7893,9 @@ public:
"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, "HTile allocation outlives native depth retirement",
texture_cache.IsMeta(base + 0x28000) &&
!texture_cache.IsMetaCleared(base + 0x28000, 0) &&
texture_cache.IsMetaCleared(base + 0x28000, 1),
"retiring depth data erased an independent metadata allocation");
texture_cache.UnmapMemory(reused_depth.info.metadata.range.address,
reused_depth.info.metadata.range.size);
Require(name, "reused metadata final retirement",
!texture_cache.IsMeta(base + 0x28000),
"unmapping the HTile allocation left its metadata registered");
"retiring the HTile image left its metadata registered");
constexpr uint64_t partial_unmap_image_offset = 0x2700000;
auto partial_unmap_image =
@@ -15132,49 +15110,13 @@ public:
texture_cache.ClearMeta(high_slice_target.htile_data_base_addr),
"single high slice was rejected or changed the backing layer layout");
auto high_slice_readback = CreateHostBuffer(
name, 7 * sizeof(uint32_t), vk::BufferUsageFlagBits::eTransferDst, {});
auto high_slice_metadata = CreateHostBuffer(
name, 6 * sizeof(uint32_t), vk::BufferUsageFlagBits::eTransferDst, {});
const auto htile_slice_size = high_slice.desc.info.metadata.range.size / 87;
const auto htile_slice_address =
high_slice_target.htile_data_base_addr + 86 * htile_slice_size;
Require(name, "ZMask support default", !Config::SupportZmaskEnabled(),
"ZMask support should be disabled by default");
const auto copy_htile = [&](uint32_t pass) {
const auto program = make_buffer_program(
ShaderType::Compute, {.read = true, .written = pass != 0});
ShaderBufferResource descriptor{};
descriptor.UpdateAddress48(high_slice_target.htile_data_base_addr);
descriptor.fields[2] = high_slice.desc.info.metadata.range.size;
ShaderRecompiler::IR::ResourceSnapshot snapshot;
auto &value = snapshot.buffers.emplace_back();
std::copy_n(descriptor.fields, 4, value.dwords.begin());
value.dword_count = 4;
ShaderStageRuntime runtime{&program, &snapshot};
for (const bool support_zmask : {false, true}) {
Config::Load({.support_zmask = support_zmask});
PreparedBindings bindings;
executor.PrepareBindings(runtime, bindings);
std::array<PreparedBindings *, 1> stages{&bindings};
executor.FindBuffers(stages);
executor.RebindBuffers(bindings);
const auto &source = bindings.buffers[0];
const vk::BufferCopy copy{source.offset + 86 * htile_slice_size,
(pass * 2 + support_zmask) * sizeof(uint32_t), sizeof(uint32_t)};
scheduler.Current().Handle().copyBuffer(source.buffer,
high_slice_metadata.buffer, 1, &copy);
}
};
name, 4 * sizeof(uint32_t), vk::BufferUsageFlagBits::eTransferDst, {});
for (uint32_t pass = 0; pass < 2; ++pass) {
vk::ClearValue prior_depth{};
prior_depth.depthStencil.depth = 0.625f;
TextureCacheTestAccess::ClearImage(texture_cache, scheduler.Current(),
high_slice.image_id, {vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 87},
prior_depth);
if (pass == 1) {
resources.GetBufferCache().FillBuffer(
htile_slice_address, htile_slice_size, 0, false);
}
RenderDepthInfo acquired_high_slice{};
RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, scheduler.Current(), acquired_high_slice);
@@ -15194,67 +15136,15 @@ public:
{vk::ImageAspectFlagBits::eDepth, 0, 85, 2}, {}, {1, 1, 1}};
texture_cache.GetImage(high_slice.image_id).Download(
std::span{&copy, 1}, high_slice_readback.buffer, 0, high_slice_readback.size);
copy_htile(pass);
}
auto high_slice_storage = high_slice.desc;
high_slice_storage.type = BindingType::Storage;
high_slice_storage.info.pixel_format = vk::Format::eR32Sfloat;
high_slice_storage.info.metadata = {};
high_slice_storage.view_info.format = vk::Format::eR32Sfloat;
high_slice_storage.view_info.aspect = vk::ImageAspectFlagBits::eColor;
high_slice_storage.view_info.usage = vk::ImageUsageFlagBits::eStorage;
const auto high_slice_storage_id = texture_cache.FindImage(high_slice_storage);
Require(name, "HTile depth replacement before raw buffer read",
high_slice_storage_id != high_slice.image_id,
"R32 storage binding retained the native depth backing");
resources.GetBufferCache().FillBuffer(
htile_slice_address, htile_slice_size, 0, false);
copy_htile(2);
Config::Load({});
for (uint32_t pass = 0; pass < 3; ++pass) {
if (pass < 2) {
Require(name, "HTile clear across copied depth recreation",
texture_cache.ClearMeta(high_slice_target.htile_data_base_addr),
"copied depth lost HTile registration");
}
RenderDepthInfo copied_depth{};
RenderExecutorTestAccess::ResolveRenderDepthTarget(
executor, scheduler.Current(), copied_depth);
if (pass == 2) {
vk::ClearValue prior_depth{};
prior_depth.depthStencil.depth = 0.625f;
TextureCacheTestAccess::ClearImage(texture_cache, scheduler.Current(),
copied_depth.image_id, {vk::ImageAspectFlagBits::eDepth, 0, 1, 86, 1},
prior_depth);
}
const auto rendering = RenderExecutorTestAccess::AcquireRenderTargets(
executor, scheduler.Current(), &no_color, 0, copied_depth);
Require(name, "copied depth consumes only subsequent HTile clears",
copied_depth.image_id != high_slice_storage_id &&
rendering.depth_stencil_attachment.depth_clear == (pass == 1),
"copied depth was cleared again or ignored a subsequent metadata clear");
scheduler.BeginRendering(rendering);
scheduler.EndRendering();
RenderExecutorTestAccess::ResetBindings(executor);
const vk::BufferImageCopy copy{(4 + pass) * sizeof(uint32_t), 0, 0,
{vk::ImageAspectFlagBits::eDepth, 0, 86, 1}, {}, {1, 1, 1}};
texture_cache.GetImage(copied_depth.image_id).Download(
std::span{&copy, 1}, high_slice_readback.buffer, 0, high_slice_readback.size);
}
scheduler.Current().Handle().pipelineBarrier2(bounds_dependency);
scheduler.Finish();
Require(name, "high HTile slice contents and neighbor",
ReadBuffer(name, high_slice_readback, 7) == std::vector<uint32_t>{
ReadBuffer(name, high_slice_readback, 4) == std::vector<uint32_t>{
std::bit_cast<uint32_t>(0.625f), std::bit_cast<uint32_t>(0.375f),
std::bit_cast<uint32_t>(0.625f), std::bit_cast<uint32_t>(0.625f),
std::bit_cast<uint32_t>(0.625f), std::bit_cast<uint32_t>(0.375f),
std::bit_cast<uint32_t>(0.625f)},
"layer86 clear missed, repeated, or discarded copied depth");
Require(name, "GPU-visible opt-in ZMask support",
ReadBuffer(name, high_slice_metadata, 6) == std::vector<uint32_t>{0, 15, 0, 15, 0, 15},
"raw HTile binding ignored the ZMask setting or lost it after depth replacement");
std::bit_cast<uint32_t>(0.625f), std::bit_cast<uint32_t>(0.625f)},
"layer86 clear missed, repeated, or changed adjacent layer85");
DestroyBuffer(&high_slice_readback);
DestroyBuffer(&high_slice_metadata);
registers.SetDepthClearValue(0.0f);
// DB override copies run with depth and stencil tests disabled.
@@ -49457,12 +49347,8 @@ int main(int argc, char **argv) {
return 0;
}
if (argc == 2 && std::strcmp(argv[1], "--htile-clear-only") == 0) {
CheckNativeMsaaState();
CheckPs5DepthRegisterDecoding();
CheckDepthHtileStencilCompatibility();
VulkanHarness vulkan;
vulkan.CheckUnifiedTextureCacheFlow();
vulkan.CheckRenderExecutorStencilBindingDiscovery();
return 0;
}
if (argc == 2 && std::strcmp(argv[1], "--dcc-clear-only") == 0) {