From 816288962b8622f54fd9d97375a2a9057b6f8da4 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 2 Sep 2024 09:28:35 -0500 Subject: [PATCH 1/9] Assign is_stack and is_pooled Properly set these values to avoid potential errors, and future proof for when these types of memory are emulated. --- src/core/memory.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 7896ae500..de0abb8a6 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -311,6 +311,8 @@ int MemoryManager::VirtualQuery(VAddr addr, int flags, info->protection = static_cast(vma.prot); info->is_flexible.Assign(vma.type == VMAType::Flexible); info->is_direct.Assign(vma.type == VMAType::Direct); + info->is_stack.Assign(vma.type == VMAType::Stack); + info->is_pooled.Assign(vma.type == VMAType::Pooled); info->is_commited.Assign(vma.type != VMAType::Free && vma.type != VMAType::Reserved); vma.name.copy(info->name.data(), std::min(info->name.size(), vma.name.size())); if (vma.type == VMAType::Direct) { From f8d71b59d9009b79f153516889959a1ff9b1595e Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 2 Sep 2024 09:30:32 -0500 Subject: [PATCH 2/9] Fix MemoryManager::VirtualQuery header The headers for these functions were technically not the same as the actual function definition. This didn't cause any emulation issues, but caused some weird issues with my IDE. --- src/core/memory.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/memory.h b/src/core/memory.h index b7edee33a..ea122c512 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -163,9 +163,9 @@ public: int QueryProtection(VAddr addr, void** start, void** end, u32* prot); - int VirtualQuery(VAddr addr, int flags, Libraries::Kernel::OrbisVirtualQueryInfo* info); + int VirtualQuery(VAddr addr, int flags, ::Libraries::Kernel::OrbisVirtualQueryInfo* info); - int DirectMemoryQuery(PAddr addr, bool find_next, Libraries::Kernel::OrbisQueryInfo* out_info); + int DirectMemoryQuery(PAddr addr, bool find_next, ::Libraries::Kernel::OrbisQueryInfo* out_info); int DirectQueryAvailable(PAddr search_start, PAddr search_end, size_t alignment, PAddr* phys_addr_out, size_t* size_out); From 0503054b409774a55ec10731eb8efce3c023bc99 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 2 Sep 2024 09:39:46 -0500 Subject: [PATCH 3/9] Grammar --- src/core/libraries/kernel/memory_management.h | 2 +- src/core/memory.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/libraries/kernel/memory_management.h b/src/core/libraries/kernel/memory_management.h index 9a447fe8b..761cb0844 100644 --- a/src/core/libraries/kernel/memory_management.h +++ b/src/core/libraries/kernel/memory_management.h @@ -56,7 +56,7 @@ struct OrbisVirtualQueryInfo { BitField<1, 1, u32> is_direct; BitField<2, 1, u32> is_stack; BitField<3, 1, u32> is_pooled; - BitField<4, 1, u32> is_commited; + BitField<4, 1, u32> is_committed; }; std::array name; }; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index de0abb8a6..7a53c8341 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -313,7 +313,7 @@ int MemoryManager::VirtualQuery(VAddr addr, int flags, info->is_direct.Assign(vma.type == VMAType::Direct); info->is_stack.Assign(vma.type == VMAType::Stack); info->is_pooled.Assign(vma.type == VMAType::Pooled); - info->is_commited.Assign(vma.type != VMAType::Free && vma.type != VMAType::Reserved); + info->is_committed.Assign(vma.type != VMAType::Free && vma.type != VMAType::Reserved); vma.name.copy(info->name.data(), std::min(info->name.size(), vma.name.size())); if (vma.type == VMAType::Direct) { const auto dmem_it = FindDmemArea(vma.phys_base); From dc1313ea3cde87a069ba95ad89acbb20b5c4617c Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 2 Sep 2024 09:43:27 -0500 Subject: [PATCH 4/9] Always assign memory_type and offset The memory_type default is based on fpPS4 behavior. I'm not entirely sure how the offset should be handled, but since the value we use defaults to 0 anyway, that should be better than leaving random data in that area. --- src/core/memory.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 7a53c8341..640751477 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -308,6 +308,7 @@ int MemoryManager::VirtualQuery(VAddr addr, int flags, const auto& vma = it->second; info->start = vma.base; info->end = vma.base + vma.size; + info->offset = vma.phys_base; info->protection = static_cast(vma.prot); info->is_flexible.Assign(vma.type == VMAType::Flexible); info->is_direct.Assign(vma.type == VMAType::Direct); @@ -318,8 +319,9 @@ int MemoryManager::VirtualQuery(VAddr addr, int flags, if (vma.type == VMAType::Direct) { const auto dmem_it = FindDmemArea(vma.phys_base); ASSERT(dmem_it != dmem_map.end()); - info->offset = vma.phys_base; info->memory_type = dmem_it->second.memory_type; + } else { + info->memory_type = ::Libraries::Kernel::SCE_KERNEL_WB_ONION; } return ORBIS_OK; From 9a772aa2f50e98b9650b805829b001644ea62496 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 2 Sep 2024 10:03:39 -0500 Subject: [PATCH 5/9] Clang fix --- src/core/memory.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/memory.h b/src/core/memory.h index ea122c512..47fbb14ca 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -165,7 +165,8 @@ public: int VirtualQuery(VAddr addr, int flags, ::Libraries::Kernel::OrbisVirtualQueryInfo* info); - int DirectMemoryQuery(PAddr addr, bool find_next, ::Libraries::Kernel::OrbisQueryInfo* out_info); + int DirectMemoryQuery(PAddr addr, bool find_next, + ::Libraries::Kernel::OrbisQueryInfo* out_info); int DirectQueryAvailable(PAddr search_start, PAddr search_end, size_t alignment, PAddr* phys_addr_out, size_t* size_out); From 04fbd7b9e775d67b9b59ed4bd0bc54ec03847cbf Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 2 Sep 2024 10:04:56 -0500 Subject: [PATCH 6/9] Clang --- src/core/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/memory.h b/src/core/memory.h index 47fbb14ca..919995b0c 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -165,7 +165,7 @@ public: int VirtualQuery(VAddr addr, int flags, ::Libraries::Kernel::OrbisVirtualQueryInfo* info); - int DirectMemoryQuery(PAddr addr, bool find_next, + int DirectMemoryQuery(PAddr addr, bool find_next, ::Libraries::Kernel::OrbisQueryInfo* out_info); int DirectQueryAvailable(PAddr search_start, PAddr search_end, size_t alignment, From 42ab101908d30b54855a2dd1847b65d5dc952fc3 Mon Sep 17 00:00:00 2001 From: Paris Oplopoios Date: Tue, 3 Sep 2024 21:40:46 +0300 Subject: [PATCH 7/9] Set CF correctly on BLSR/BLSMSK patch (#724) * Set CF correctly on BLSR patch * Set CF correctly on BLSMSK patch --- src/core/cpu_patches.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/core/cpu_patches.cpp b/src/core/cpu_patches.cpp index 0160d63a3..f31ff18cb 100644 --- a/src/core/cpu_patches.cpp +++ b/src/core/cpu_patches.cpp @@ -345,9 +345,26 @@ static void GenerateBLSMSK(const ZydisDecodedOperand* operands, Xbyak::CodeGener SaveRegisters(c, {scratch}); + Xbyak::Label set_carry, clear_carry, end; + + // BLSMSK sets CF to zero if source is NOT zero, otherwise it sets CF to one. c.mov(scratch, *src); + c.test(scratch, scratch); + c.jz(set_carry); + c.jmp(clear_carry); + + c.L(set_carry); c.dec(scratch); c.xor_(scratch, *src); + c.stc(); + c.jmp(end); + + c.L(clear_carry); + c.dec(scratch); + c.xor_(scratch, *src); + // We don't need to clear carry here since XOR does that for us + + c.L(end); c.mov(dst, scratch); RestoreRegisters(c, {scratch}); @@ -361,9 +378,26 @@ static void GenerateBLSR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerat SaveRegisters(c, {scratch}); + Xbyak::Label set_carry, clear_carry, end; + + // BLSR sets CF to zero if source is NOT zero, otherwise it sets CF to one. c.mov(scratch, *src); + c.test(scratch, scratch); + c.jz(set_carry); + c.jmp(clear_carry); + + c.L(set_carry); c.dec(scratch); c.and_(scratch, *src); + c.stc(); + c.jmp(end); + + c.L(clear_carry); + c.dec(scratch); + c.and_(scratch, *src); + // We don't need to clear carry here since AND does that for us + + c.L(end); c.mov(dst, scratch); RestoreRegisters(c, {scratch}); From e9ef7261859c2838463ea7fe8a08f202f4a75c44 Mon Sep 17 00:00:00 2001 From: oltolm Date: Tue, 3 Sep 2024 20:41:59 +0200 Subject: [PATCH 8/9] Fix warnings (#749) * suppress warning in vk_mem_alloc.h * fix warnings in cheats_patches.cpp --- src/qt_gui/cheats_patches.cpp | 29 ++++++++++--------- src/video_core/buffer_cache/buffer.cpp | 3 ++ .../renderer_vulkan/renderer_vulkan.cpp | 3 ++ src/video_core/renderer_vulkan/vk_common.cpp | 3 ++ .../renderer_vulkan/vk_instance.cpp | 3 ++ src/video_core/texture_cache/image.cpp | 3 ++ src/video_core/texture_cache/tile_manager.cpp | 3 ++ 7 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/qt_gui/cheats_patches.cpp b/src/qt_gui/cheats_patches.cpp index beaadb286..1c30f7e92 100644 --- a/src/qt_gui/cheats_patches.cpp +++ b/src/qt_gui/cheats_patches.cpp @@ -147,13 +147,13 @@ void CheatsPatches::setupUI() { controlLayout->addWidget(downloadComboBox); QPushButton* downloadButton = new QPushButton(tr("Download Cheats")); - connect(downloadButton, &QPushButton::clicked, [=]() { + connect(downloadButton, &QPushButton::clicked, [this, downloadComboBox]() { QString source = downloadComboBox->currentData().toString(); downloadCheats(source, m_gameSerial, m_gameVersion, true); }); QPushButton* deleteCheatButton = new QPushButton(tr("Delete File")); - connect(deleteCheatButton, &QPushButton::clicked, [=]() { + connect(deleteCheatButton, &QPushButton::clicked, [this, CHEATS_DIR_QString]() { QStringListModel* model = qobject_cast(listView_selectFile->model()); if (!model) { return; @@ -232,7 +232,7 @@ void CheatsPatches::setupUI() { patchesControlLayout->addWidget(patchesComboBox); QPushButton* patchesButton = new QPushButton(tr("Download Patches")); - connect(patchesButton, &QPushButton::clicked, [=]() { + connect(patchesButton, &QPushButton::clicked, [this]() { QString selectedOption = patchesComboBox->currentData().toString(); downloadPatches(selectedOption, true); }); @@ -444,8 +444,8 @@ QCheckBox* CheatsPatches::findCheckBoxByName(const QString& name) { return nullptr; } -void CheatsPatches::downloadCheats(const QString& source, const QString& m_gameSerial, - const QString& m_gameVersion, const bool showMessageBox) { +void CheatsPatches::downloadCheats(const QString& source, const QString& gameSerial, + const QString& gameVersion, const bool showMessageBox) { QDir dir(Common::FS::GetUserPath(Common::FS::PathType::CheatsDir)); if (!dir.exists()) { dir.mkpath("."); @@ -455,7 +455,7 @@ void CheatsPatches::downloadCheats(const QString& source, const QString& m_gameS if (source == "GoldHEN") { url = "https://raw.githubusercontent.com/GoldHEN/GoldHEN_Cheat_Repository/main/json.txt"; } else if (source == "wolf2022") { - url = "https://wolf2022.ir/trainer/" + m_gameSerial + "_" + m_gameVersion + ".json"; + url = "https://wolf2022.ir/trainer/" + gameSerial + "_" + gameVersion + ".json"; } else if (source == "shadPS4") { url = "https://raw.githubusercontent.com/shadps4-emu/ps4_cheats/main/" "CHEATS_JSON.txt"; @@ -468,7 +468,7 @@ void CheatsPatches::downloadCheats(const QString& source, const QString& m_gameS QNetworkRequest request(url); QNetworkReply* reply = manager->get(request); - connect(reply, &QNetworkReply::finished, [=]() { + connect(reply, &QNetworkReply::finished, [=, this]() { if (reply->error() == QNetworkReply::NoError) { QByteArray jsonData = reply->readAll(); bool foundFiles = false; @@ -476,7 +476,7 @@ void CheatsPatches::downloadCheats(const QString& source, const QString& m_gameS if (source == "GoldHEN" || source == "shadPS4") { QString textContent(jsonData); QRegularExpression regex( - QString("%1_%2[^=]*\.json").arg(m_gameSerial).arg(m_gameVersion)); + QString("%1_%2[^=]*\\.json").arg(gameSerial).arg(gameVersion)); QRegularExpressionMatchIterator matches = regex.globalMatch(textContent); QString baseUrl; @@ -519,7 +519,7 @@ void CheatsPatches::downloadCheats(const QString& source, const QString& m_gameS QNetworkRequest fileRequest(fileUrl); QNetworkReply* fileReply = manager->get(fileRequest); - connect(fileReply, &QNetworkReply::finished, [=]() { + connect(fileReply, &QNetworkReply::finished, [=, this]() { if (fileReply->error() == QNetworkReply::NoError) { QByteArray fileData = fileReply->readAll(); QFile localFile(localFilePath); @@ -680,7 +680,7 @@ void CheatsPatches::downloadPatches(const QString repository, const bool showMes QNetworkRequest request(url); QNetworkReply* reply = manager->get(request); - connect(reply, &QNetworkReply::finished, [=]() { + connect(reply, &QNetworkReply::finished, [=, this]() { if (reply->error() == QNetworkReply::NoError) { QByteArray htmlData = reply->readAll(); reply->deleteLater(); @@ -725,7 +725,7 @@ void CheatsPatches::downloadPatches(const QString repository, const bool showMes QNetworkRequest fileRequest(fileUrl); QNetworkReply* fileReply = manager->get(fileRequest); - connect(fileReply, &QNetworkReply::finished, [=]() { + connect(fileReply, &QNetworkReply::finished, [=, this]() { if (fileReply->error() == QNetworkReply::NoError) { QByteArray fileData = fileReply->readAll(); QFile localFile(dir.filePath(fileName)); @@ -864,7 +864,7 @@ void CheatsPatches::addCheatsToLayout(const QJsonArray& modsArray, const QJsonAr rightLayout->addWidget(cheatCheckBox); m_cheatCheckBoxes.append(cheatCheckBox); connect(cheatCheckBox, &QCheckBox::toggled, - [=](bool checked) { applyCheat(modName, checked); }); + [this, modName](bool checked) { applyCheat(modName, checked); }); } else if (modType == "button") { QPushButton* cheatButton = new QPushButton(modName); cheatButton->adjustSize(); @@ -880,7 +880,8 @@ void CheatsPatches::addCheatsToLayout(const QJsonArray& modsArray, const QJsonAr buttonLayout->addStretch(); rightLayout->addLayout(buttonLayout); - connect(cheatButton, &QPushButton::clicked, [=]() { applyCheat(modName, true); }); + connect(cheatButton, &QPushButton::clicked, + [this, modName]() { applyCheat(modName, true); }); } } @@ -1093,7 +1094,7 @@ void CheatsPatches::addPatchesToLayout(const QString& filePath) { patchCheckBox->installEventFilter(this); connect(patchCheckBox, &QCheckBox::toggled, - [=](bool checked) { applyPatch(patchName, checked); }); + [this, patchName](bool checked) { applyPatch(patchName, checked); }); patchName.clear(); patchAuthor.clear(); diff --git a/src/video_core/buffer_cache/buffer.cpp b/src/video_core/buffer_cache/buffer.cpp index 372b6f745..adcea000b 100644 --- a/src/video_core/buffer_cache/buffer.cpp +++ b/src/video_core/buffer_cache/buffer.cpp @@ -9,7 +9,10 @@ #include "video_core/renderer_vulkan/vk_platform.h" #include "video_core/renderer_vulkan/vk_scheduler.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnullability-completeness" #include +#pragma GCC diagnostic pop namespace VideoCore { diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index b12708088..82b5d1043 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -11,7 +11,10 @@ #include "video_core/renderer_vulkan/vk_rasterizer.h" #include "video_core/texture_cache/image.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnullability-completeness" #include +#pragma GCC diagnostic pop namespace Vulkan { diff --git a/src/video_core/renderer_vulkan/vk_common.cpp b/src/video_core/renderer_vulkan/vk_common.cpp index e9265ea9c..0823fd23d 100644 --- a/src/video_core/renderer_vulkan/vk_common.cpp +++ b/src/video_core/renderer_vulkan/vk_common.cpp @@ -5,7 +5,10 @@ // Implement vma functions #define VMA_IMPLEMENTATION +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnullability-completeness" #include +#pragma GCC diagnostic pop // Store the dispatch loader here VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 76e8b1d92..e91c7be67 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -14,7 +14,10 @@ #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_platform.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnullability-completeness" #include +#pragma GCC diagnostic pop namespace Vulkan { diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp index 0b725655b..b733e34ca 100644 --- a/src/video_core/texture_cache/image.cpp +++ b/src/video_core/texture_cache/image.cpp @@ -9,7 +9,10 @@ #include "video_core/texture_cache/image.h" #include "video_core/texture_cache/tile_manager.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnullability-completeness" #include +#pragma GCC diagnostic pop namespace VideoCore { diff --git a/src/video_core/texture_cache/tile_manager.cpp b/src/video_core/texture_cache/tile_manager.cpp index 8b0227624..5f3ed0f89 100644 --- a/src/video_core/texture_cache/tile_manager.cpp +++ b/src/video_core/texture_cache/tile_manager.cpp @@ -15,7 +15,10 @@ #include #include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnullability-completeness" #include +#pragma GCC diagnostic pop namespace VideoCore { From 34ffd953060f6bd3628907bd9933a008d4c3baa3 Mon Sep 17 00:00:00 2001 From: psucien <168137814+psucien@users.noreply.github.com> Date: Tue, 3 Sep 2024 21:56:23 +0200 Subject: [PATCH 9/9] video_core: added `VK_LAYER_LUNARG_crash_diagnostic` (#751) --- src/common/config.cpp | 24 ++++++++++--- src/common/config.h | 3 +- src/core/libraries/gnmdriver/gnmdriver.cpp | 8 ++--- src/core/libraries/system/userservice.cpp | 2 +- src/core/libraries/videoout/video_out.cpp | 4 +-- src/emulator.cpp | 3 +- src/video_core/amdgpu/liverpool.cpp | 8 ----- .../renderer_vulkan/renderer_vulkan.cpp | 8 +++-- .../renderer_vulkan/vk_instance.cpp | 16 +++------ src/video_core/renderer_vulkan/vk_instance.h | 9 ++--- .../renderer_vulkan/vk_platform.cpp | 35 +++++++++++++++---- src/video_core/renderer_vulkan/vk_platform.h | 2 +- .../renderer_vulkan/vk_rasterizer.cpp | 13 ++----- .../renderer_vulkan/vk_rasterizer.h | 1 - .../renderer_vulkan/vk_scheduler.cpp | 7 ---- src/video_core/texture_cache/image.cpp | 3 -- 16 files changed, 76 insertions(+), 70 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index 8d87ed3c3..fb6ee120a 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -30,7 +30,9 @@ static bool vkValidation = false; static bool vkValidationSync = false; static bool vkValidationGpu = false; static bool rdocEnable = false; -static bool rdocMarkersEnable = false; +static bool vkMarkers = false; +static bool vkCrashDiagnostic = false; + // Gui std::string settings_install_dir = ""; u32 main_window_geometry_x = 400; @@ -121,7 +123,7 @@ bool isRdocEnabled() { } bool isMarkersEnabled() { - return rdocMarkersEnable; + return vkMarkers; } u32 vblankDiv() { @@ -140,6 +142,14 @@ bool vkValidationGpuEnabled() { return vkValidationGpu; } +bool vkMarkersEnabled() { + return vkMarkers || vkCrashDiagnostic; // Crash diagnostic forces markers on +} + +bool vkCrashDiagnosticEnabled() { + return vkCrashDiagnostic; +} + void setGpuId(s32 selectedGpuId) { gpuId = selectedGpuId; } @@ -384,7 +394,8 @@ void load(const std::filesystem::path& path) { vkValidationSync = toml::find_or(vk, "validation_sync", false); vkValidationGpu = toml::find_or(vk, "validation_gpu", true); rdocEnable = toml::find_or(vk, "rdocEnable", false); - rdocMarkersEnable = toml::find_or(vk, "rdocMarkersEnable", false); + vkMarkers = toml::find_or(vk, "rdocMarkersEnable", false); + vkCrashDiagnostic = toml::find_or(vk, "crashDiagnostic", false); } if (data.contains("Debug")) { @@ -460,7 +471,8 @@ void save(const std::filesystem::path& path) { data["Vulkan"]["validation_sync"] = vkValidationSync; data["Vulkan"]["validation_gpu"] = vkValidationGpu; data["Vulkan"]["rdocEnable"] = rdocEnable; - data["Vulkan"]["rdocMarkersEnable"] = rdocMarkersEnable; + data["Vulkan"]["rdocMarkersEnable"] = vkMarkers; + data["Vulkan"]["crashDiagnostic"] = vkCrashDiagnostic; data["Debug"]["DebugDump"] = isDebugDump; data["GUI"]["theme"] = mw_themes; data["GUI"]["iconSize"] = m_icon_size; @@ -504,7 +516,11 @@ void setDefaultValues() { shouldDumpPM4 = false; vblankDivider = 1; vkValidation = false; + vkValidationSync = false; + vkValidationGpu = false; rdocEnable = false; + vkMarkers = false; + vkCrashDiagnostic = false; emulator_language = "en"; m_language = 1; gpuId = -1; diff --git a/src/common/config.h b/src/common/config.h index 11e7d8827..7e717fe71 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -31,7 +31,6 @@ bool copyGPUCmdBuffers(); bool dumpShaders(); bool dumpPM4(); bool isRdocEnabled(); -bool isMarkersEnabled(); u32 vblankDiv(); void setDebugDump(bool enable); @@ -62,6 +61,8 @@ void setRdocEnabled(bool enable); bool vkValidationEnabled(); bool vkValidationSyncEnabled(); bool vkValidationGpuEnabled(); +bool vkMarkersEnabled(); +bool vkCrashDiagnosticEnabled(); // Gui void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h); diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index a2ef94037..ffec70300 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -499,7 +499,7 @@ int PS4_SYSV_ABI sceGnmDestroyWorkloadStream() { } void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw) { - LOG_INFO(Lib_GnmDriver, "vqid {}, offset_dw {}", gnm_vqid, next_offs_dw); + LOG_DEBUG(Lib_GnmDriver, "vqid {}, offset_dw {}", gnm_vqid, next_offs_dw); if (gnm_vqid == 0) { return; @@ -2054,7 +2054,7 @@ s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffers(u32 count, u32* dcb_gpu_addrs u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[], u32* ccb_sizes_in_bytes, u32 vo_handle, u32 buf_idx, u32 flip_mode, u32 flip_arg) { - LOG_INFO(Lib_GnmDriver, "called [buf = {}]", buf_idx); + LOG_DEBUG(Lib_GnmDriver, "called [buf = {}]", buf_idx); auto* cmdbuf = dcb_gpu_addrs[count - 1]; const auto size_dw = dcb_sizes_in_bytes[count - 1] / 4; @@ -2078,7 +2078,7 @@ int PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffersForWorkload() { s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[], u32* dcb_sizes_in_bytes, const u32* ccb_gpu_addrs[], u32* ccb_sizes_in_bytes) { - LOG_INFO(Lib_GnmDriver, "called"); + LOG_DEBUG(Lib_GnmDriver, "called"); if (!dcb_gpu_addrs || !dcb_sizes_in_bytes) { LOG_ERROR(Lib_GnmDriver, "dcbGpuAddrs and dcbSizesInBytes must not be NULL"); @@ -2154,7 +2154,7 @@ int PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload() { } int PS4_SYSV_ABI sceGnmSubmitDone() { - LOG_INFO(Lib_GnmDriver, "called"); + LOG_DEBUG(Lib_GnmDriver, "called"); if (!liverpool->IsGpuIdle()) { submission_lock = true; } diff --git a/src/core/libraries/system/userservice.cpp b/src/core/libraries/system/userservice.cpp index 8c48b3111..cd7a721c0 100644 --- a/src/core/libraries/system/userservice.cpp +++ b/src/core/libraries/system/userservice.cpp @@ -565,7 +565,7 @@ int PS4_SYSV_ABI sceUserServiceGetLoginFlag() { } s32 PS4_SYSV_ABI sceUserServiceGetLoginUserIdList(OrbisUserServiceLoginUserIdList* userIdList) { - LOG_INFO(Lib_UserService, "called"); + LOG_DEBUG(Lib_UserService, "called"); if (userIdList == nullptr) { LOG_ERROR(Lib_UserService, "user_id is null"); return ORBIS_USER_SERVICE_ERROR_INVALID_ARGUMENT; diff --git a/src/core/libraries/videoout/video_out.cpp b/src/core/libraries/videoout/video_out.cpp index a6c1a7623..631f77732 100644 --- a/src/core/libraries/videoout/video_out.cpp +++ b/src/core/libraries/videoout/video_out.cpp @@ -140,8 +140,8 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode return ORBIS_VIDEO_OUT_ERROR_INVALID_INDEX; } - LOG_INFO(Lib_VideoOut, "bufferIndex = {}, flipMode = {}, flipArg = {}", bufferIndex, flipMode, - flipArg); + LOG_DEBUG(Lib_VideoOut, "bufferIndex = {}, flipMode = {}, flipArg = {}", bufferIndex, flipMode, + flipArg); if (!driver->SubmitFlip(port, bufferIndex, flipArg)) { LOG_ERROR(Lib_VideoOut, "Flip queue is full"); diff --git a/src/emulator.cpp b/src/emulator.cpp index 85a4d745a..9d1bb00d9 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -64,7 +64,8 @@ Emulator::Emulator() { LOG_INFO(Config, "Vulkan vkValidationSync: {}", Config::vkValidationSyncEnabled()); LOG_INFO(Config, "Vulkan vkValidationGpu: {}", Config::vkValidationGpuEnabled()); LOG_INFO(Config, "Vulkan rdocEnable: {}", Config::isRdocEnabled()); - LOG_INFO(Config, "Vulkan rdocMarkersEnable: {}", Config::isMarkersEnabled()); + LOG_INFO(Config, "Vulkan rdocMarkersEnable: {}", Config::vkMarkersEnabled()); + LOG_INFO(Config, "Vulkan crashDiagnostics: {}", Config::vkCrashDiagnosticEnabled()); // Defer until after logging is initialized. memory = Core::Memory::Instance(); diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 35003e1a1..cee30f755 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -347,7 +347,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); rasterizer->ScopeMarkerBegin(fmt::format("dcb:{}:DrawIndex2", cmd_address)); - rasterizer->Breadcrumb(u64(cmd_address)); rasterizer->Draw(true); rasterizer->ScopeMarkerEnd(); } @@ -363,7 +362,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); rasterizer->ScopeMarkerBegin( fmt::format("dcb:{}:DrawIndexOffset2", cmd_address)); - rasterizer->Breadcrumb(u64(cmd_address)); rasterizer->Draw(true, draw_index_off->index_offset); rasterizer->ScopeMarkerEnd(); } @@ -376,7 +374,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); rasterizer->ScopeMarkerBegin(fmt::format("dcb:{}:DrawIndexAuto", cmd_address)); - rasterizer->Breadcrumb(u64(cmd_address)); rasterizer->Draw(false); rasterizer->ScopeMarkerEnd(); } @@ -390,7 +387,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); rasterizer->ScopeMarkerBegin(fmt::format("dcb:{}:DrawIndirect", cmd_address)); - rasterizer->Breadcrumb(u64(cmd_address)); rasterizer->DrawIndirect(false, ib_address, offset, size); rasterizer->ScopeMarkerEnd(); } @@ -406,7 +402,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); rasterizer->ScopeMarkerBegin( fmt::format("dcb:{}:DrawIndexIndirect", cmd_address)); - rasterizer->Breadcrumb(u64(cmd_address)); rasterizer->DrawIndirect(true, ib_address, offset, size); rasterizer->ScopeMarkerEnd(); } @@ -421,7 +416,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); rasterizer->ScopeMarkerBegin(fmt::format("dcb:{}:Dispatch", cmd_address)); - rasterizer->Breadcrumb(u64(cmd_address)); rasterizer->DispatchDirect(); rasterizer->ScopeMarkerEnd(); } @@ -437,7 +431,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); rasterizer->ScopeMarkerBegin( fmt::format("dcb:{}:DispatchIndirect", cmd_address)); - rasterizer->Breadcrumb(u64(cmd_address)); rasterizer->DispatchIndirect(ib_address, offset, size); rasterizer->ScopeMarkerEnd(); } @@ -602,7 +595,6 @@ Liverpool::Task Liverpool::ProcessCompute(std::span acb, int vqid) { if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) { const auto cmd_address = reinterpret_cast(header); rasterizer->ScopeMarkerBegin(fmt::format("acb[{}]:{}:Dispatch", vqid, cmd_address)); - rasterizer->Breadcrumb(u64(cmd_address)); rasterizer->DispatchDirect(); rasterizer->ScopeMarkerEnd(); } diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 82b5d1043..f1c81b6e2 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -68,8 +68,10 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice physical_device, vk::Format for RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_) : window{window_}, liverpool{liverpool_}, - instance{window, Config::getGpuId(), Config::vkValidationEnabled()}, draw_scheduler{instance}, - present_scheduler{instance}, flip_scheduler{instance}, swapchain{instance, window}, + instance{window, Config::getGpuId(), Config::vkValidationEnabled(), + Config::vkCrashDiagnosticEnabled()}, + draw_scheduler{instance}, present_scheduler{instance}, flip_scheduler{instance}, + swapchain{instance, window}, rasterizer{std::make_unique(instance, draw_scheduler, liverpool)}, texture_cache{rasterizer->GetTextureCache()} { const u32 num_images = swapchain.GetImageCount(); @@ -357,7 +359,7 @@ Frame* RendererVulkan::GetRenderFrame() { { std::unique_lock lock{free_mutex}; free_cv.wait(lock, [this] { return !free_queue.empty(); }); - LOG_INFO(Render_Vulkan, "Got render frame, remaining {}", free_queue.size() - 1); + LOG_DEBUG(Render_Vulkan, "Got render frame, remaining {}", free_queue.size() - 1); // Take the frame from the queue frame = free_queue.front(); diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index e91c7be67..56ab229ce 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -49,14 +49,15 @@ std::string GetReadableVersion(u32 version) { } // Anonymous namespace -Instance::Instance(bool enable_validation, bool dump_command_buffers) +Instance::Instance(bool enable_validation, bool enable_crash_diagnostic) : instance{CreateInstance(Frontend::WindowSystemType::Headless, enable_validation, - dump_command_buffers)}, + enable_crash_diagnostic)}, physical_devices{instance->enumeratePhysicalDevices()} {} Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index, - bool enable_validation /*= false*/) - : instance{CreateInstance(window.getWindowInfo().type, enable_validation, false)}, + bool enable_validation /*= false*/, bool enable_crash_diagnostic /*= false*/) + : instance{CreateInstance(window.getWindowInfo().type, enable_validation, + enable_crash_diagnostic)}, physical_devices{instance->enumeratePhysicalDevices()} { if (enable_validation) { debug_callback = CreateDebugCallback(*instance); @@ -228,13 +229,6 @@ bool Instance::CreateDevice() { add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); - if (Config::isMarkersEnabled()) { - const bool has_sync2 = add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); - if (has_sync2) { - has_nv_checkpoints = add_extension(VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME); - } - } - #ifdef __APPLE__ // Required by Vulkan spec if supported. add_extension(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index fb89a5546..ee36d23e6 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -21,9 +21,9 @@ namespace Vulkan { class Instance { public: - explicit Instance(bool validation = false, bool dump_command_buffers = false); + explicit Instance(bool validation = false, bool crash_diagnostic = false); explicit Instance(Frontend::WindowSDL& window, s32 physical_device_index, - bool enable_validation = false); + bool enable_validation = false, bool enable_crash_diagnostic = false); ~Instance(); /// Returns a formatted string for the driver version @@ -82,10 +82,6 @@ public: return profiler_context; } - bool HasNvCheckpoints() const { - return has_nv_checkpoints; - } - /// Returns true when a known debugging tool is attached. bool HasDebuggingToolAttached() const { return has_renderdoc || has_nsight_graphics; @@ -270,7 +266,6 @@ private: bool debug_utils_supported{}; bool has_nsight_graphics{}; bool has_renderdoc{}; - bool has_nv_checkpoints{}; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_platform.cpp b/src/video_core/renderer_vulkan/vk_platform.cpp index 7774cd2d0..2318bb247 100644 --- a/src/video_core/renderer_vulkan/vk_platform.cpp +++ b/src/video_core/renderer_vulkan/vk_platform.cpp @@ -17,6 +17,7 @@ #include "common/assert.h" #include "common/config.h" #include "common/logging/log.h" +#include "common/path_util.h" #include "sdl_window.h" #include "video_core/renderer_vulkan/vk_platform.h" @@ -32,7 +33,7 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instan namespace Vulkan { static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation"; -static const char* const API_DUMP_LAYER_NAME = "VK_LAYER_LUNARG_api_dump"; +static const char* const CRASH_DIAGNOSTIC_LAYER_NAME = "VK_LAYER_LUNARG_crash_diagnostic"; static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback( VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type, @@ -196,7 +197,7 @@ std::vector GetInstanceExtensions(Frontend::WindowSystemType window } vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool enable_validation, - bool dump_command_buffers) { + bool enable_crash_diagnostic) { LOG_INFO(Render_Vulkan, "Creating vulkan instance"); #if VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL @@ -227,15 +228,23 @@ vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool e u32 num_layers = 0; std::array layers; + vk::Bool32 enable_force_barriers = vk::False; + const char* log_path{}; + #if VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL if (enable_validation) { layers[num_layers++] = VALIDATION_LAYER_NAME; } - if (dump_command_buffers) { - layers[num_layers++] = API_DUMP_LAYER_NAME; + + if (enable_crash_diagnostic) { + layers[num_layers++] = CRASH_DIAGNOSTIC_LAYER_NAME; + static const auto crash_diagnostic_path = + Common::FS::GetUserPathString(Common::FS::PathType::LogDir); + log_path = crash_diagnostic_path.c_str(); + enable_force_barriers = vk::True; } #else - if (enable_validation || dump_command_buffers) { + if (enable_validation || enable_crash_diagnostic) { LOG_WARNING(Render_Vulkan, "Skipping loading Vulkan layers as dynamic loading is not enabled."); } @@ -258,7 +267,7 @@ vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool e }, vk::LayerSettingEXT{ .pLayerName = VALIDATION_LAYER_NAME, - .pSettingName = "sync_queue_submit", + .pSettingName = "syncval_submit_time_validation", .type = vk::LayerSettingTypeEXT::eBool32, .valueCount = 1, .pValues = &enable_sync, @@ -298,6 +307,20 @@ vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool e .valueCount = 1, .pValues = &enable_gpuav, }, + vk::LayerSettingEXT{ + .pLayerName = "lunarg_crash_diagnostic", + .pSettingName = "output_path", + .type = vk::LayerSettingTypeEXT::eString, + .valueCount = 1, + .pValues = &log_path, + }, + vk::LayerSettingEXT{ + .pLayerName = "lunarg_crash_diagnostic", + .pSettingName = "sync_after_commands", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_force_barriers, + }, }; vk::StructureChain instance_ci_chain = { diff --git a/src/video_core/renderer_vulkan/vk_platform.h b/src/video_core/renderer_vulkan/vk_platform.h index 413fa347e..e38bd2fef 100644 --- a/src/video_core/renderer_vulkan/vk_platform.h +++ b/src/video_core/renderer_vulkan/vk_platform.h @@ -22,7 +22,7 @@ constexpr u32 TargetVulkanApiVersion = VK_API_VERSION_1_2; vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& emu_window); vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool enable_validation, - bool dump_command_buffers); + bool enable_crash_diagnostic); vk::UniqueDebugUtilsMessengerEXT CreateDebugCallback(vk::Instance instance); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index cadce01eb..5a20899db 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -321,7 +321,7 @@ void Rasterizer::UpdateDepthStencilState() { } void Rasterizer::ScopeMarkerBegin(const std::string_view& str) { - if (Config::nullGpu() || !Config::isMarkersEnabled()) { + if (Config::nullGpu() || !Config::vkMarkersEnabled()) { return; } @@ -332,7 +332,7 @@ void Rasterizer::ScopeMarkerBegin(const std::string_view& str) { } void Rasterizer::ScopeMarkerEnd() { - if (Config::nullGpu() || !Config::isMarkersEnabled()) { + if (Config::nullGpu() || !Config::vkMarkersEnabled()) { return; } @@ -341,7 +341,7 @@ void Rasterizer::ScopeMarkerEnd() { } void Rasterizer::ScopedMarkerInsert(const std::string_view& str) { - if (Config::nullGpu() || !Config::isMarkersEnabled()) { + if (Config::nullGpu() || !Config::vkMarkersEnabled()) { return; } @@ -351,11 +351,4 @@ void Rasterizer::ScopedMarkerInsert(const std::string_view& str) { }); } -void Rasterizer::Breadcrumb(u64 id) { - if (Config::nullGpu() || !instance.HasNvCheckpoints()) { - return; - } - scheduler.CommandBuffer().setCheckpointNV(id); -} - } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index c38fe6ee9..43ab4756d 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -40,7 +40,6 @@ public: void ScopeMarkerBegin(const std::string_view& str); void ScopeMarkerEnd(); void ScopedMarkerInsert(const std::string_view& str); - void Breadcrumb(u64 id); void InvalidateMemory(VAddr addr, u64 size); void MapMemory(VAddr addr, u64 size); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 2f1f13d72..9ff332aef 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -192,13 +192,6 @@ void Scheduler::SubmitExecution(SubmitInfo& info) { try { instance.GetGraphicsQueue().submit(submit_info, info.fence); } catch (vk::DeviceLostError& err) { - if (instance.HasNvCheckpoints()) { - const auto checkpoint_data = instance.GetGraphicsQueue().getCheckpointData2NV(); - for (const auto& cp : checkpoint_data) { - LOG_CRITICAL(Render_Vulkan, "{}: {:#x}", vk::to_string(cp.stage), - reinterpret_cast(cp.pCheckpointMarker)); - } - } UNREACHABLE_MSG("Device lost during submit: {}", err.what()); } diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp index b733e34ca..0d20eaeab 100644 --- a/src/video_core/texture_cache/image.cpp +++ b/src/video_core/texture_cache/image.cpp @@ -2,12 +2,10 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/assert.h" -#include "common/config.h" #include "video_core/renderer_vulkan/liverpool_to_vk.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/texture_cache/image.h" -#include "video_core/texture_cache/tile_manager.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnullability-completeness" @@ -17,7 +15,6 @@ namespace VideoCore { using namespace Vulkan; -using Libraries::VideoOut::TilingMode; bool ImageInfo::IsBlockCoded() const { switch (pixel_format) {