diff --git a/src/common/emulatorConfig.cpp b/src/common/emulatorConfig.cpp index c230cf249..7705f5c61 100644 --- a/src/common/emulatorConfig.cpp +++ b/src/common/emulatorConfig.cpp @@ -189,10 +189,6 @@ bool SyncRawImageBuffersEnabled() { return g_config->sync_raw_image_buffers; } -bool SupportZmaskEnabled() { - return g_config->support_zmask; -} - bool TessellationEnabled() { return g_config->tessellation_enabled; } diff --git a/src/common/emulatorConfig.h b/src/common/emulatorConfig.h index 6bde334af..4387dafc9 100644 --- a/src/common/emulatorConfig.h +++ b/src/common/emulatorConfig.h @@ -86,7 +86,6 @@ struct ConfigOptions { bool renderdoc_enabled = false; bool readback_linear_images = false; bool sync_raw_image_buffers = false; - bool support_zmask = false; bool tessellation_enabled = false; bool trophy_enabled = true; uint32_t trophy_duration_seconds = 6; @@ -152,7 +151,6 @@ bool GpuAssistedValidationEnabled(); bool RenderDocEnabled(); bool ReadbackLinearImagesEnabled(); bool SyncRawImageBuffersEnabled(); -bool SupportZmaskEnabled(); bool TessellationEnabled(); bool TrophyEnabled(); uint32_t GetTrophyDurationSeconds(); diff --git a/src/graphics/host_gpu/renderer/cache/textureCache.cpp b/src/graphics/host_gpu/renderer/cache/textureCache.cpp index e3abcc6db..dd62b80d6 100644 --- a/src/graphics/host_gpu/renderer/cache/textureCache.cpp +++ b/src/graphics/host_gpu/renderer/cache/textureCache.cpp @@ -263,6 +263,9 @@ void TextureCache::DeleteImage(ImageId id) { EXIT("TextureCache: deleting a GPU-modified image without resolving its contents\n"); } m_download_images.erase(id); + if (image->info.metadata.kind == ImageMetadataKind::Htile) { + m_surface_metas.erase(image->info.metadata.range.address); + } UnregisterImage(id); if (m_scheduler.Active()) { 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", 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); return replacement_id; } @@ -1880,7 +1876,6 @@ void TextureCache::UnmapMemory(uint64_t address, uint64_t size) { EXIT("TextureCache: invalid unmap range\n"); } 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();) { const auto base = metadata->first; if (base >= address && base < address + size) { diff --git a/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp b/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp index edea24b48..17ba542ea 100644 --- a/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/descriptors.cpp @@ -126,13 +126,9 @@ NativeStorageBuffer(RenderContext& context, const PreparedBindings::BufferSource if (size > graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange) { 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( - address, size, resource.written || metadata_read, + auto [buffer, offset] = context.GetBufferCache().ObtainBuffer( + address, size, resource.written, 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 adjustment = offset - aligned_offset; const auto max_range = graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange; diff --git a/src/launcher/forms/configuration_edit_dialog.ui b/src/launcher/forms/configuration_edit_dialog.ui index e3f48e017..7d869632c 100644 --- a/src/launcher/forms/configuration_edit_dialog.ui +++ b/src/launcher/forms/configuration_edit_dialog.ui @@ -493,12 +493,6 @@ Accurate texture synchronization - - - Can restore missing geometry (High on Life 2). - Support ZMask - - diff --git a/src/launcher/include/configuration.h b/src/launcher/include/configuration.h index f45b7b936..8a3a820d1 100644 --- a/src/launcher/include/configuration.h +++ b/src/launcher/include/configuration.h @@ -127,7 +127,6 @@ public: bool hide_cursor_enabled = false; bool readback_linear_images = false; bool sync_raw_image_buffers = false; - bool support_zmask = false; bool tessellation_enabled = false; bool trophy_enabled = true; int trophy_duration_seconds = 6; @@ -167,7 +166,6 @@ public: hide_cursor_enabled = other.hide_cursor_enabled; readback_linear_images = other.readback_linear_images; sync_raw_image_buffers = other.sync_raw_image_buffers; - support_zmask = other.support_zmask; tessellation_enabled = other.tessellation_enabled; trophy_enabled = other.trophy_enabled; trophy_duration_seconds = other.trophy_duration_seconds; diff --git a/src/launcher/src/configuration.cpp b/src/launcher/src/configuration.cpp index 5e53416c4..a6e63dfba 100644 --- a/src/launcher/src/configuration.cpp +++ b/src/launcher/src/configuration.cpp @@ -14,7 +14,6 @@ QVariantMap Configuration::GameSettings() const { KYTY_CFG_SET(hide_cursor_enabled); KYTY_CFG_SET(readback_linear_images); KYTY_CFG_SET(sync_raw_image_buffers); - KYTY_CFG_SET(support_zmask); KYTY_CFG_SET(tessellation_enabled); KYTY_CFG_SET(trophy_enabled); 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(readback_linear_images); KYTY_CFG_GET(sync_raw_image_buffers); - KYTY_CFG_GET(support_zmask); KYTY_CFG_GET(tessellation_enabled); trophy_enabled = s.value("trophy_enabled", trophy_enabled).toBool(); KYTY_CFG_GET(trophy_duration_seconds); diff --git a/src/launcher/src/configurationEditDialog.cpp b/src/launcher/src/configurationEditDialog.cpp index 525f101ec..dcfcdfeb5 100644 --- a/src/launcher/src/configurationEditDialog.cpp +++ b/src/launcher/src/configurationEditDialog.cpp @@ -287,7 +287,6 @@ void ConfigurationEditDialog::Init(const Configuration& info) { m_ui->checkBox_hide_cursor->setChecked(info.hide_cursor_enabled); 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_support_zmask->setChecked(info.support_zmask); m_ui->checkBox_tessellation->setChecked(info.tessellation_enabled); m_ui->checkBox_skip_notice_screen->setChecked(info.skip_notice_screen); 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.readback_linear_images = ui.checkBox_readback->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.skip_notice_screen = ui.checkBox_skip_notice_screen->isChecked(); info.network_connected = ui.checkBox_network_connected->isChecked(); diff --git a/src/launcher/src/mainDialog.cpp b/src/launcher/src/mainDialog.cpp index d3ca29313..e33373166 100644 --- a/src/launcher/src/mainDialog.cpp +++ b/src/launcher/src/mainDialog.cpp @@ -262,7 +262,6 @@ static QStringList CreateEmulatorArgs(const Configuration& info) { } args << "--readback-linear-images" << BoolArg(info.readback_linear_images); 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-duration" << QString::number(info.trophy_duration_seconds); args << "--perf-overlay" << BoolArg(info.perf_overlay_enabled); diff --git a/src/main.cpp b/src/main.cpp index 1c3bdbb91..fec8b2cfb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -91,8 +91,6 @@ static void PrintUsage() { " --readback-linear-images Read back writable linear images on submit.\n"); ::printf( " --sync-raw-image-buffers Synchronize raw reads of GPU images. Default: false.\n"); - ::printf( - " --support-zmask Fill HTILE buffers with uncompressed ZMask. Default: false.\n"); ::printf( " --trophy-notifications Show trophy unlock toasts and play their sound.\n"); ::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()); 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") { if (!ParseBool(value, options.config.trophy_enabled)) { ::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str()); diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 2ecdfccca..22699004a 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -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(htile_layers, std::bit_cast(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 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, ©); - } - }; + 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{©, 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.Finish(); Require(name, "high HTile slice contents and neighbor", - ReadBuffer(name, high_slice_readback, 7) == std::vector{ + ReadBuffer(name, high_slice_readback, 4) == std::vector{ std::bit_cast(0.625f), std::bit_cast(0.375f), - std::bit_cast(0.625f), std::bit_cast(0.625f), - std::bit_cast(0.625f), std::bit_cast(0.375f), - std::bit_cast(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{0, 15, 0, 15, 0, 15}, - "raw HTile binding ignored the ZMask setting or lost it after depth replacement"); + std::bit_cast(0.625f), std::bit_cast(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) {