From 418274038433e674b5e793322742b9b286c12802 Mon Sep 17 00:00:00 2001 From: psucien Date: Sat, 31 Aug 2024 00:10:47 +0200 Subject: [PATCH 1/7] Don't load `sync2` ext if `nv_checkpoints` isn't used --- src/video_core/renderer_vulkan/vk_instance.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index e1a5cb414..34727d27e 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -220,12 +220,12 @@ bool Instance::CreateDevice() { const bool maintenance5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); - const bool has_sync2 = add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); - if (has_sync2) { - has_nv_checkpoints = Config::isMarkersEnabled() - ? add_extension(VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME) - : false; + 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__ From 61db246c5ec86aa63215a13ad915f42da1f98426 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Fri, 30 Aug 2024 20:47:07 -0700 Subject: [PATCH 2/7] core: Fix CPU patch stack issues --- CMakeLists.txt | 2 +- src/core/cpu_patches.cpp | 30 +++++++------------ .../libraries/kernel/thread_management.cpp | 3 +- src/core/linker.cpp | 4 +-- 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c7e03e3c..a65e9c599 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -636,7 +636,7 @@ target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAlloca if (APPLE) # Reserve system-managed memory space. - target_link_options(shadps4 PRIVATE -Wl,-no_pie,-no_fixup_chains,-no_huge,-pagezero_size,0x400000,-segaddr,GUEST_SYSTEM,0x400000,-image_base,0x10000000000) + target_link_options(shadps4 PRIVATE -Wl,-no_pie,-no_fixup_chains,-no_huge,-pagezero_size,0x400000,-segaddr,GUEST_SYSTEM,0x400000,-image_base,0x20000000000) # Link MoltenVK for Vulkan support find_library(MOLTENVK MoltenVK REQUIRED) diff --git a/src/core/cpu_patches.cpp b/src/core/cpu_patches.cpp index 55bbf23b1..e713155ae 100644 --- a/src/core/cpu_patches.cpp +++ b/src/core/cpu_patches.cpp @@ -126,39 +126,35 @@ static Xbyak::Reg AllocateScratchRegister( static pthread_key_t stack_pointer_slot; static pthread_key_t patch_stack_slot; static std::once_flag patch_context_slots_init_flag; +static constexpr u32 patch_stack_size = 0x1000; static_assert(sizeof(void*) == sizeof(u64), "Cannot fit a register inside a thread local storage slot."); +static void FreePatchStack(void* patch_stack) { + // Subtract back to the bottom of the stack for free. + std::free(static_cast(patch_stack) - patch_stack_size); +} + static void InitializePatchContextSlots() { ASSERT_MSG(pthread_key_create(&stack_pointer_slot, nullptr) == 0, "Unable to allocate thread-local register for stack pointer."); - ASSERT_MSG(pthread_key_create(&patch_stack_slot, nullptr) == 0, + ASSERT_MSG(pthread_key_create(&patch_stack_slot, FreePatchStack) == 0, "Unable to allocate thread-local register for patch stack."); } void InitializeThreadPatchStack() { std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots); - const auto* patch_stack = std::malloc(0x1000); - pthread_setspecific(patch_stack_slot, patch_stack); -} - -void CleanupThreadPatchStack() { - std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots); - - auto* patch_stack = pthread_getspecific(patch_stack_slot); - if (patch_stack != nullptr) { - std::free(patch_stack); - pthread_setspecific(patch_stack_slot, nullptr); - } + pthread_setspecific(patch_stack_slot, + static_cast(std::malloc(patch_stack_size)) + patch_stack_size); } /// Saves the stack pointer to thread local storage and loads the patch stack. static void SaveStack(Xbyak::CodeGenerator& c) { std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots); - // Save stack pointer and load patch stack. + // Save original stack pointer and load patch stack. c.putSeg(gs); c.mov(qword[reinterpret_cast(stack_pointer_slot * sizeof(void*))], rsp); c.putSeg(gs); @@ -184,10 +180,6 @@ void InitializeThreadPatchStack() { // No-op } -void CleanupThreadPatchStack() { - // No-op -} - /// Saves the stack pointer to thread local storage and loads the patch stack. static void SaveStack(Xbyak::CodeGenerator& c) { UNIMPLEMENTED(); @@ -244,7 +236,7 @@ static void RestoreContext(Xbyak::CodeGenerator& c, const Xbyak::Operand& dst) { if (!dst.isREG() || dst.getIdx() != reg) { c.pop(Xbyak::Reg64(reg)); } else { - c.add(rsp, 4); + c.add(rsp, 8); } } RestoreStack(c); diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index a2befd4c7..5c84c35d7 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -986,15 +986,14 @@ static void cleanup_thread(void* arg) { destructor(value); } } - Core::CleanupThreadPatchStack(); thread->is_almost_done = true; } static void* run_thread(void* arg) { auto* thread = static_cast(arg); Common::SetCurrentThreadName(thread->name.c_str()); - auto* linker = Common::Singleton::Instance(); Core::InitializeThreadPatchStack(); + auto* linker = Common::Singleton::Instance(); linker->InitTlsForThread(false); void* ret = nullptr; g_pthread_self = thread; diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 4ef62c4a3..0c914cef1 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -85,8 +85,8 @@ void Linker::Execute() { // Init primary thread. Common::SetCurrentThreadName("GAME_MainThread"); - Libraries::Kernel::pthreadInitSelfMainThread(); InitializeThreadPatchStack(); + Libraries::Kernel::pthreadInitSelfMainThread(); InitTlsForThread(true); // Start shared library modules @@ -106,8 +106,6 @@ void Linker::Execute() { RunMainEntry(m->GetEntryAddress(), &p, ProgramExitFunc); } } - - CleanupThreadPatchStack(); } s32 Linker::LoadModule(const std::filesystem::path& elf_name, bool is_dynamic) { From 766c286d626e65e757313e59649d15f4c83c58de Mon Sep 17 00:00:00 2001 From: psucien Date: Sat, 31 Aug 2024 22:01:08 +0200 Subject: [PATCH 3/7] libraries: gnmdriver: `sceGnmValidateCommandBuffers` added --- src/core/libraries/gnmdriver/gnmdriver.cpp | 6 +++--- src/core/libraries/gnmdriver/gnmdriver.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 34d056156..a2ef94037 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -2346,9 +2346,9 @@ s32 PS4_SYSV_ABI sceGnmUpdateVsShader(u32* cmdbuf, u32 size, const u32* vs_regs, return ORBIS_OK; } -int PS4_SYSV_ABI sceGnmValidateCommandBuffers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); - return ORBIS_OK; +s32 PS4_SYSV_ABI sceGnmValidateCommandBuffers() { + LOG_TRACE(Lib_GnmDriver, "called"); + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; // not available in retail FW; } int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics() { diff --git a/src/core/libraries/gnmdriver/gnmdriver.h b/src/core/libraries/gnmdriver/gnmdriver.h index 40a6ca5b6..754d488f8 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.h +++ b/src/core/libraries/gnmdriver/gnmdriver.h @@ -223,7 +223,7 @@ s32 PS4_SYSV_ABI sceGnmUpdatePsShader(u32* cmdbuf, u32 size, const u32* ps_regs) s32 PS4_SYSV_ABI sceGnmUpdatePsShader350(u32* cmdbuf, u32 size, const u32* ps_regs); s32 PS4_SYSV_ABI sceGnmUpdateVsShader(u32* cmdbuf, u32 size, const u32* vs_regs, u32 shader_modifier); -int PS4_SYSV_ABI sceGnmValidateCommandBuffers(); +s32 PS4_SYSV_ABI sceGnmValidateCommandBuffers(); int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics(); int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics2(); int PS4_SYSV_ABI sceGnmValidateDispatchCommandBuffers(); From 5aaab7f8412591e8d4d8034e3dd4a18d294ac7bc Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 31 Aug 2024 13:12:59 -0700 Subject: [PATCH 4/7] ci: Remove translations folder from macOS upload. --- .github/workflows/macos-qt.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/macos-qt.yml b/.github/workflows/macos-qt.yml index def98ea34..8a882b30f 100644 --- a/.github/workflows/macos-qt.yml +++ b/.github/workflows/macos-qt.yml @@ -50,7 +50,6 @@ jobs: run: | mkdir upload mv ${{github.workspace}}/build/shadps4.app upload - mv ${{github.workspace}}/build/translations upload macdeployqt upload/shadps4.app tar cf shadps4-macos-qt.tar.gz -C upload . From 95943e42edd4373430ade3cd97ca675cbbd19c69 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 31 Aug 2024 13:28:22 -0700 Subject: [PATCH 5/7] ci: Remove translations folder from Windows upload. --- .github/workflows/windows-qt.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/windows-qt.yml b/.github/workflows/windows-qt.yml index 70c33ebe9..1c8657365 100644 --- a/.github/workflows/windows-qt.yml +++ b/.github/workflows/windows-qt.yml @@ -40,7 +40,6 @@ jobs: run: | mkdir upload move build/Release/shadPS4.exe upload - move build/translations upload windeployqt --dir upload upload/shadPS4.exe - name: Upload executable From ba89552373341be2edecb7e6cb8f8ebec1417e24 Mon Sep 17 00:00:00 2001 From: Marius Alexandersen Date: Sat, 31 Aug 2024 23:33:47 +0200 Subject: [PATCH 6/7] Fix segfault when unable to find PFSCOffset in pfs_image --- src/core/file_format/pkg.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/file_format/pkg.cpp b/src/core/file_format/pkg.cpp index d86f3b28d..13e5e88b1 100644 --- a/src/core/file_format/pkg.cpp +++ b/src/core/file_format/pkg.cpp @@ -258,6 +258,12 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem:: // Retrieve PFSC from decrypted pfs_image. pfsc_offset = GetPFSCOffset(pfs_decrypted); + if (pfsc_offset == (u32)-1) + { + failreason = "Could not retrieve PFSC from decrypted pfs_image"; + return false; + } + std::memcpy(pfsc.data(), pfs_decrypted.data() + pfsc_offset, length - pfsc_offset); PFSCHdr pfsChdr; From d920a9e5449a2624e6a03efad02c9bb87d29ad9c Mon Sep 17 00:00:00 2001 From: Mariuspersen <59454368+Mariuspersen@users.noreply.github.com> Date: Sun, 1 Sep 2024 00:03:33 +0200 Subject: [PATCH 7/7] Update pkg.cpp fix code style non-compliance --- src/core/file_format/pkg.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/file_format/pkg.cpp b/src/core/file_format/pkg.cpp index 13e5e88b1..4ce7a1af4 100644 --- a/src/core/file_format/pkg.cpp +++ b/src/core/file_format/pkg.cpp @@ -258,8 +258,7 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem:: // Retrieve PFSC from decrypted pfs_image. pfsc_offset = GetPFSCOffset(pfs_decrypted); - if (pfsc_offset == (u32)-1) - { + if (pfsc_offset == (u32)-1) { failreason = "Could not retrieve PFSC from decrypted pfs_image"; return false; }