mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 00:12:40 +00:00
revert HTile lifetime changes and opt-in ZMask support
This commit is contained in:
1 parent
e87fb8c859
commit
2c730e58ea
11 files changed
+9
-158
No files matched your search
@@ -189,10 +189,6 @@ bool SyncRawImageBuffersEnabled() {
|
|||||||
return g_config->sync_raw_image_buffers;
|
return g_config->sync_raw_image_buffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SupportZmaskEnabled() {
|
|
||||||
return g_config->support_zmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TessellationEnabled() {
|
bool TessellationEnabled() {
|
||||||
return g_config->tessellation_enabled;
|
return g_config->tessellation_enabled;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ struct ConfigOptions {
|
|||||||
bool renderdoc_enabled = false;
|
bool renderdoc_enabled = false;
|
||||||
bool readback_linear_images = false;
|
bool readback_linear_images = false;
|
||||||
bool sync_raw_image_buffers = false;
|
bool sync_raw_image_buffers = false;
|
||||||
bool support_zmask = false;
|
|
||||||
bool tessellation_enabled = false;
|
bool tessellation_enabled = false;
|
||||||
bool trophy_enabled = true;
|
bool trophy_enabled = true;
|
||||||
uint32_t trophy_duration_seconds = 6;
|
uint32_t trophy_duration_seconds = 6;
|
||||||
@@ -152,7 +151,6 @@ bool GpuAssistedValidationEnabled();
|
|||||||
bool RenderDocEnabled();
|
bool RenderDocEnabled();
|
||||||
bool ReadbackLinearImagesEnabled();
|
bool ReadbackLinearImagesEnabled();
|
||||||
bool SyncRawImageBuffersEnabled();
|
bool SyncRawImageBuffersEnabled();
|
||||||
bool SupportZmaskEnabled();
|
|
||||||
bool TessellationEnabled();
|
bool TessellationEnabled();
|
||||||
bool TrophyEnabled();
|
bool TrophyEnabled();
|
||||||
uint32_t GetTrophyDurationSeconds();
|
uint32_t GetTrophyDurationSeconds();
|
||||||
|
|||||||
+3
-8
@@ -263,6 +263,9 @@ void TextureCache::DeleteImage(ImageId id) {
|
|||||||
EXIT("TextureCache: deleting a GPU-modified image without resolving its contents\n");
|
EXIT("TextureCache: deleting a GPU-modified image without resolving its contents\n");
|
||||||
}
|
}
|
||||||
m_download_images.erase(id);
|
m_download_images.erase(id);
|
||||||
|
if (image->info.metadata.kind == ImageMetadataKind::Htile) {
|
||||||
|
m_surface_metas.erase(image->info.metadata.range.address);
|
||||||
|
}
|
||||||
UnregisterImage(id);
|
UnregisterImage(id);
|
||||||
if (m_scheduler.Active()) {
|
if (m_scheduler.Active()) {
|
||||||
m_scheduler.DeferOperation([this, id] { m_slot_images.erase(id); });
|
m_scheduler.DeferOperation([this, id] { m_slot_images.erase(id); });
|
||||||
@@ -716,13 +719,6 @@ ImageId TextureCache::ResolveDepthOverlap(const ImageInfo& requested, BindingTyp
|
|||||||
"TextureCache: unsupported unequal-sample depth overlap copy (%u -> %u)\n",
|
"TextureCache: unsupported unequal-sample depth overlap copy (%u -> %u)\n",
|
||||||
cached.backing.samples, replacement.backing.samples);
|
cached.backing.samples, replacement.backing.samples);
|
||||||
}
|
}
|
||||||
if (info.IsDepth() && info.metadata.kind == ImageMetadataKind::Htile) {
|
|
||||||
// Copied depth supersedes pending clears from the previous native image.
|
|
||||||
const auto metadata = m_surface_metas.find(info.metadata.range.address);
|
|
||||||
if (metadata != m_surface_metas.end()) {
|
|
||||||
metadata->second.clear_mask.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FreeImage(cached_id);
|
FreeImage(cached_id);
|
||||||
return replacement_id;
|
return replacement_id;
|
||||||
}
|
}
|
||||||
@@ -1880,7 +1876,6 @@ void TextureCache::UnmapMemory(uint64_t address, uint64_t size) {
|
|||||||
EXIT("TextureCache: invalid unmap range\n");
|
EXIT("TextureCache: invalid unmap range\n");
|
||||||
}
|
}
|
||||||
std::scoped_lock lock {m_lock};
|
std::scoped_lock lock {m_lock};
|
||||||
// HTILE belongs to guest memory, independently of native image replacements.
|
|
||||||
for (auto metadata = m_surface_metas.begin(); metadata != m_surface_metas.end();) {
|
for (auto metadata = m_surface_metas.begin(); metadata != m_surface_metas.end();) {
|
||||||
const auto base = metadata->first;
|
const auto base = metadata->first;
|
||||||
if (base >= address && base < address + size) {
|
if (base >= address && base < address + size) {
|
||||||
|
|||||||
@@ -126,13 +126,9 @@ NativeStorageBuffer(RenderContext& context, const PreparedBindings::BufferSource
|
|||||||
if (size > graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange) {
|
if (size > graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange) {
|
||||||
EXIT("storage buffer range is unsupported\n");
|
EXIT("storage buffer range is unsupported\n");
|
||||||
}
|
}
|
||||||
const bool metadata_read = resource.read && Config::SupportZmaskEnabled() &&
|
|
||||||
(address & 0x7fffu) == 0 &&
|
|
||||||
context.GetTextureCache().IsMeta(address);
|
|
||||||
auto [buffer, offset] = context.GetBufferCache().ObtainBuffer(
|
auto [buffer, offset] = context.GetBufferCache().ObtainBuffer(
|
||||||
address, size, resource.written || metadata_read,
|
address, size, resource.written,
|
||||||
resource.formatted || (resource.read && Config::SyncRawImageBuffersEnabled()), id);
|
resource.formatted || (resource.read && Config::SyncRawImageBuffersEnabled()), id);
|
||||||
if (metadata_read) buffer->Fill(offset, size, 0xf); // HTILE ZMask::kUncompressed.
|
|
||||||
const auto aligned_offset = Common::AlignDown(offset, alignment);
|
const auto aligned_offset = Common::AlignDown(offset, alignment);
|
||||||
const auto adjustment = offset - aligned_offset;
|
const auto adjustment = offset - aligned_offset;
|
||||||
const auto max_range = graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange;
|
const auto max_range = graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange;
|
||||||
|
|||||||
@@ -493,12 +493,6 @@
|
|||||||
<property name="text"><string>Accurate texture synchronization</string></property>
|
<property name="text"><string>Accurate texture synchronization</string></property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="checkBox_support_zmask">
|
|
||||||
<property name="toolTip"><string>Can restore missing geometry (High on Life 2).</string></property>
|
|
||||||
<property name="text"><string>Support ZMask</string></property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ public:
|
|||||||
bool hide_cursor_enabled = false;
|
bool hide_cursor_enabled = false;
|
||||||
bool readback_linear_images = false;
|
bool readback_linear_images = false;
|
||||||
bool sync_raw_image_buffers = false;
|
bool sync_raw_image_buffers = false;
|
||||||
bool support_zmask = false;
|
|
||||||
bool tessellation_enabled = false;
|
bool tessellation_enabled = false;
|
||||||
bool trophy_enabled = true;
|
bool trophy_enabled = true;
|
||||||
int trophy_duration_seconds = 6;
|
int trophy_duration_seconds = 6;
|
||||||
@@ -167,7 +166,6 @@ public:
|
|||||||
hide_cursor_enabled = other.hide_cursor_enabled;
|
hide_cursor_enabled = other.hide_cursor_enabled;
|
||||||
readback_linear_images = other.readback_linear_images;
|
readback_linear_images = other.readback_linear_images;
|
||||||
sync_raw_image_buffers = other.sync_raw_image_buffers;
|
sync_raw_image_buffers = other.sync_raw_image_buffers;
|
||||||
support_zmask = other.support_zmask;
|
|
||||||
tessellation_enabled = other.tessellation_enabled;
|
tessellation_enabled = other.tessellation_enabled;
|
||||||
trophy_enabled = other.trophy_enabled;
|
trophy_enabled = other.trophy_enabled;
|
||||||
trophy_duration_seconds = other.trophy_duration_seconds;
|
trophy_duration_seconds = other.trophy_duration_seconds;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ QVariantMap Configuration::GameSettings() const {
|
|||||||
KYTY_CFG_SET(hide_cursor_enabled);
|
KYTY_CFG_SET(hide_cursor_enabled);
|
||||||
KYTY_CFG_SET(readback_linear_images);
|
KYTY_CFG_SET(readback_linear_images);
|
||||||
KYTY_CFG_SET(sync_raw_image_buffers);
|
KYTY_CFG_SET(sync_raw_image_buffers);
|
||||||
KYTY_CFG_SET(support_zmask);
|
|
||||||
KYTY_CFG_SET(tessellation_enabled);
|
KYTY_CFG_SET(tessellation_enabled);
|
||||||
KYTY_CFG_SET(trophy_enabled);
|
KYTY_CFG_SET(trophy_enabled);
|
||||||
KYTY_CFG_SET(trophy_duration_seconds);
|
KYTY_CFG_SET(trophy_duration_seconds);
|
||||||
@@ -64,7 +63,6 @@ void Configuration::ReadGameSettingsValues(const Settings& s) {
|
|||||||
KYTY_CFG_GET(hide_cursor_enabled);
|
KYTY_CFG_GET(hide_cursor_enabled);
|
||||||
KYTY_CFG_GET(readback_linear_images);
|
KYTY_CFG_GET(readback_linear_images);
|
||||||
KYTY_CFG_GET(sync_raw_image_buffers);
|
KYTY_CFG_GET(sync_raw_image_buffers);
|
||||||
KYTY_CFG_GET(support_zmask);
|
|
||||||
KYTY_CFG_GET(tessellation_enabled);
|
KYTY_CFG_GET(tessellation_enabled);
|
||||||
trophy_enabled = s.value("trophy_enabled", trophy_enabled).toBool();
|
trophy_enabled = s.value("trophy_enabled", trophy_enabled).toBool();
|
||||||
KYTY_CFG_GET(trophy_duration_seconds);
|
KYTY_CFG_GET(trophy_duration_seconds);
|
||||||
|
|||||||
@@ -287,7 +287,6 @@ void ConfigurationEditDialog::Init(const Configuration& info) {
|
|||||||
m_ui->checkBox_hide_cursor->setChecked(info.hide_cursor_enabled);
|
m_ui->checkBox_hide_cursor->setChecked(info.hide_cursor_enabled);
|
||||||
m_ui->checkBox_readback->setChecked(info.readback_linear_images);
|
m_ui->checkBox_readback->setChecked(info.readback_linear_images);
|
||||||
m_ui->checkBox_sync_raw_image_buffers->setChecked(info.sync_raw_image_buffers);
|
m_ui->checkBox_sync_raw_image_buffers->setChecked(info.sync_raw_image_buffers);
|
||||||
m_ui->checkBox_support_zmask->setChecked(info.support_zmask);
|
|
||||||
m_ui->checkBox_tessellation->setChecked(info.tessellation_enabled);
|
m_ui->checkBox_tessellation->setChecked(info.tessellation_enabled);
|
||||||
m_ui->checkBox_skip_notice_screen->setChecked(info.skip_notice_screen);
|
m_ui->checkBox_skip_notice_screen->setChecked(info.skip_notice_screen);
|
||||||
m_ui->checkBox_network_connected->setChecked(info.network_connected);
|
m_ui->checkBox_network_connected->setChecked(info.network_connected);
|
||||||
@@ -481,7 +480,6 @@ static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui, boo
|
|||||||
info.hide_cursor_enabled = ui.checkBox_hide_cursor->isChecked();
|
info.hide_cursor_enabled = ui.checkBox_hide_cursor->isChecked();
|
||||||
info.readback_linear_images = ui.checkBox_readback->isChecked();
|
info.readback_linear_images = ui.checkBox_readback->isChecked();
|
||||||
info.sync_raw_image_buffers = ui.checkBox_sync_raw_image_buffers->isChecked();
|
info.sync_raw_image_buffers = ui.checkBox_sync_raw_image_buffers->isChecked();
|
||||||
info.support_zmask = ui.checkBox_support_zmask->isChecked();
|
|
||||||
info.tessellation_enabled = ui.checkBox_tessellation->isChecked();
|
info.tessellation_enabled = ui.checkBox_tessellation->isChecked();
|
||||||
info.skip_notice_screen = ui.checkBox_skip_notice_screen->isChecked();
|
info.skip_notice_screen = ui.checkBox_skip_notice_screen->isChecked();
|
||||||
info.network_connected = ui.checkBox_network_connected->isChecked();
|
info.network_connected = ui.checkBox_network_connected->isChecked();
|
||||||
|
|||||||
@@ -262,7 +262,6 @@ static QStringList CreateEmulatorArgs(const Configuration& info) {
|
|||||||
}
|
}
|
||||||
args << "--readback-linear-images" << BoolArg(info.readback_linear_images);
|
args << "--readback-linear-images" << BoolArg(info.readback_linear_images);
|
||||||
args << "--sync-raw-image-buffers" << BoolArg(info.sync_raw_image_buffers);
|
args << "--sync-raw-image-buffers" << BoolArg(info.sync_raw_image_buffers);
|
||||||
args << "--support-zmask" << BoolArg(info.support_zmask);
|
|
||||||
args << "--trophy-notifications" << BoolArg(info.trophy_enabled);
|
args << "--trophy-notifications" << BoolArg(info.trophy_enabled);
|
||||||
args << "--trophy-duration" << QString::number(info.trophy_duration_seconds);
|
args << "--trophy-duration" << QString::number(info.trophy_duration_seconds);
|
||||||
args << "--perf-overlay" << BoolArg(info.perf_overlay_enabled);
|
args << "--perf-overlay" << BoolArg(info.perf_overlay_enabled);
|
||||||
|
|||||||
@@ -91,8 +91,6 @@ static void PrintUsage() {
|
|||||||
" --readback-linear-images <true|false> Read back writable linear images on submit.\n");
|
" --readback-linear-images <true|false> Read back writable linear images on submit.\n");
|
||||||
::printf(
|
::printf(
|
||||||
" --sync-raw-image-buffers <true|false> Synchronize raw reads of GPU images. Default: false.\n");
|
" --sync-raw-image-buffers <true|false> Synchronize raw reads of GPU images. Default: false.\n");
|
||||||
::printf(
|
|
||||||
" --support-zmask <true|false> Fill HTILE buffers with uncompressed ZMask. Default: false.\n");
|
|
||||||
::printf(
|
::printf(
|
||||||
" --trophy-notifications <true|false> Show trophy unlock toasts and play their sound.\n");
|
" --trophy-notifications <true|false> Show trophy unlock toasts and play their sound.\n");
|
||||||
::printf(
|
::printf(
|
||||||
@@ -479,11 +477,6 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
|
|||||||
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
|
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (arg == "--support-zmask") {
|
|
||||||
if (!ParseBool(value, options.config.support_zmask)) {
|
|
||||||
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (arg == "--trophy-notifications") {
|
} else if (arg == "--trophy-notifications") {
|
||||||
if (!ParseBool(value, options.config.trophy_enabled)) {
|
if (!ParseBool(value, options.config.trophy_enabled)) {
|
||||||
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
|
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
|
||||||
|
|||||||
@@ -6522,11 +6522,6 @@ public:
|
|||||||
htile_depth.view_info.aspect = vk::ImageAspectFlagBits::eDepth;
|
htile_depth.view_info.aspect = vk::ImageAspectFlagBits::eDepth;
|
||||||
htile_depth.view_info.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
htile_depth.view_info.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||||
const auto htile_depth_image = texture_cache.FindImage(htile_depth);
|
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{};
|
vk::ClearValue htile_clear{};
|
||||||
htile_clear.depthStencil.depth = 0.25f;
|
htile_clear.depthStencil.depth = 0.25f;
|
||||||
TextureCacheTestAccess::ClearImage(
|
TextureCacheTestAccess::ClearImage(
|
||||||
@@ -6560,11 +6555,6 @@ public:
|
|||||||
Require(name, "HTile depth storage prefix view",
|
Require(name, "HTile depth storage prefix view",
|
||||||
texture_cache.FindTexture(id, htile_storage) != nullptr,
|
texture_cache.FindTexture(id, htile_storage) != nullptr,
|
||||||
"converted depth prefix has no storage view");
|
"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;
|
htile_storage_image = id;
|
||||||
}
|
}
|
||||||
auto htile_readback = CreateHostBuffer(
|
auto htile_readback = CreateHostBuffer(
|
||||||
@@ -6585,11 +6575,6 @@ public:
|
|||||||
std::vector<u32>(htile_layers, std::bit_cast<u32>(0.25f)),
|
std::vector<u32>(htile_layers, std::bit_cast<u32>(0.25f)),
|
||||||
"partial storage conversion lost native depth data outside its view");
|
"partial storage conversion lost native depth data outside its view");
|
||||||
DestroyBuffer(&htile_readback);
|
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(
|
auto layered_stencil_desc = MakeLinearDesc(
|
||||||
base + 0x27d4000, 6 * 4 * sizeof(float),
|
base + 0x27d4000, 6 * 4 * sizeof(float),
|
||||||
@@ -7908,16 +7893,9 @@ public:
|
|||||||
"retiring the old DCC image erased the live HTile slice state");
|
"retiring the old DCC image erased the live HTile slice state");
|
||||||
texture_cache.UnmapMemory(reused_depth.info.data.address,
|
texture_cache.UnmapMemory(reused_depth.info.data.address,
|
||||||
reused_depth.info.data.size);
|
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",
|
Require(name, "reused metadata final retirement",
|
||||||
!texture_cache.IsMeta(base + 0x28000),
|
!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;
|
constexpr uint64_t partial_unmap_image_offset = 0x2700000;
|
||||||
auto partial_unmap_image =
|
auto partial_unmap_image =
|
||||||
@@ -15132,49 +15110,13 @@ public:
|
|||||||
texture_cache.ClearMeta(high_slice_target.htile_data_base_addr),
|
texture_cache.ClearMeta(high_slice_target.htile_data_base_addr),
|
||||||
"single high slice was rejected or changed the backing layer layout");
|
"single high slice was rejected or changed the backing layer layout");
|
||||||
auto high_slice_readback = CreateHostBuffer(
|
auto high_slice_readback = CreateHostBuffer(
|
||||||
name, 7 * sizeof(uint32_t), vk::BufferUsageFlagBits::eTransferDst, {});
|
name, 4 * 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, ©);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for (uint32_t pass = 0; pass < 2; ++pass) {
|
for (uint32_t pass = 0; pass < 2; ++pass) {
|
||||||
vk::ClearValue prior_depth{};
|
vk::ClearValue prior_depth{};
|
||||||
prior_depth.depthStencil.depth = 0.625f;
|
prior_depth.depthStencil.depth = 0.625f;
|
||||||
TextureCacheTestAccess::ClearImage(texture_cache, scheduler.Current(),
|
TextureCacheTestAccess::ClearImage(texture_cache, scheduler.Current(),
|
||||||
high_slice.image_id, {vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 87},
|
high_slice.image_id, {vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 87},
|
||||||
prior_depth);
|
prior_depth);
|
||||||
if (pass == 1) {
|
|
||||||
resources.GetBufferCache().FillBuffer(
|
|
||||||
htile_slice_address, htile_slice_size, 0, false);
|
|
||||||
}
|
|
||||||
RenderDepthInfo acquired_high_slice{};
|
RenderDepthInfo acquired_high_slice{};
|
||||||
RenderExecutorTestAccess::ResolveRenderDepthTarget(
|
RenderExecutorTestAccess::ResolveRenderDepthTarget(
|
||||||
executor, scheduler.Current(), acquired_high_slice);
|
executor, scheduler.Current(), acquired_high_slice);
|
||||||
@@ -15194,67 +15136,15 @@ public:
|
|||||||
{vk::ImageAspectFlagBits::eDepth, 0, 85, 2}, {}, {1, 1, 1}};
|
{vk::ImageAspectFlagBits::eDepth, 0, 85, 2}, {}, {1, 1, 1}};
|
||||||
texture_cache.GetImage(high_slice.image_id).Download(
|
texture_cache.GetImage(high_slice.image_id).Download(
|
||||||
std::span{©, 1}, high_slice_readback.buffer, 0, high_slice_readback.size);
|
std::span{©, 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{©, 1}, high_slice_readback.buffer, 0, high_slice_readback.size);
|
|
||||||
}
|
}
|
||||||
scheduler.Current().Handle().pipelineBarrier2(bounds_dependency);
|
scheduler.Current().Handle().pipelineBarrier2(bounds_dependency);
|
||||||
scheduler.Finish();
|
scheduler.Finish();
|
||||||
Require(name, "high HTile slice contents and neighbor",
|
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.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.625f)},
|
||||||
std::bit_cast<uint32_t>(0.625f), std::bit_cast<uint32_t>(0.375f),
|
"layer86 clear missed, repeated, or changed adjacent layer85");
|
||||||
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");
|
|
||||||
DestroyBuffer(&high_slice_readback);
|
DestroyBuffer(&high_slice_readback);
|
||||||
DestroyBuffer(&high_slice_metadata);
|
|
||||||
registers.SetDepthClearValue(0.0f);
|
registers.SetDepthClearValue(0.0f);
|
||||||
|
|
||||||
// DB override copies run with depth and stencil tests disabled.
|
// DB override copies run with depth and stencil tests disabled.
|
||||||
@@ -49457,12 +49347,8 @@ int main(int argc, char **argv) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--htile-clear-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--htile-clear-only") == 0) {
|
||||||
CheckNativeMsaaState();
|
|
||||||
CheckPs5DepthRegisterDecoding();
|
|
||||||
CheckDepthHtileStencilCompatibility();
|
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
vulkan.CheckUnifiedTextureCacheFlow();
|
vulkan.CheckUnifiedTextureCacheFlow();
|
||||||
vulkan.CheckRenderExecutorStencilBindingDiscovery();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--dcc-clear-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--dcc-clear-only") == 0) {
|
||||||
|
|||||||
Reference in new issue
Block a user