From edefa59c854c369213e67af174710cc80b63e1b6 Mon Sep 17 00:00:00 2001 From: shaquib01 Date: Sun, 1 Nov 2026 16:47:34 +0530 Subject: [PATCH 1/9] perf(agc): adopt mapped guest memory on window attachment --- .../prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp index d607e1ae53..7d715280de 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp @@ -4,6 +4,7 @@ #include "prx/libSceAgcDriver/Execution/include/Driver/Queues/WorkerAffinity.hpp" #include "prx/libSceAgcDriver/Execution/include/GuestMemory.hpp" #include "prx/libSceAgcDriver/Execution/include/PerformanceTimer.hpp" +#include "prx/libc/include/GuestAllocations.hpp" #include #include "prx/libSceAgcDriver/Execution/include/TracyZone.hpp" #include @@ -68,6 +69,8 @@ void Driver::AttachWindow(const PresentationWindow& window) { replacedDevices.push_back(device); } device = std::make_shared(&window); + const auto mapped = GuestAllocations::GuestAllocationsAcquire_nid_postfix(); + device->ImportGuestMemory(GuestAllocations::Mapped(mapped.begin(), mapped.end()), GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true); } void Driver::Present(const PresentationWindow& window, const DisplayBuffer* buffer, const DisplayBuffer* plane, bool opaque, void (*gpuReady)(void*), void* context) { From 0e9311cd5487466a03f24e5f7db1e0a19c76e6d6 Mon Sep 17 00:00:00 2001 From: Shaquib Nawaid <63773478+shaquib01@users.noreply.github.com> Date: Mon, 2 Nov 2026 17:01:57 +0530 Subject: [PATCH 2/9] perf(agc): trace window attachment and eager import phases --- .../libSceAgcDriver/Execution/src/Driver/Presentation.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp index 7d715280de..a5c0beeffc 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp @@ -62,15 +62,20 @@ void Driver::AttachWindow(const PresentationWindow& window) { CheckFailure(); std::unique_lock replacing(deviceReplacement); GuestMemory::TagGpuLockSite(GuestMemory::GpuLockSite::Present); + PerformanceTimer timing("Driver.AttachWindow"); std::lock_guard lock(GuestMemory::GpuMutex()); if (device) { require(device->Window() == nullptr, "a window is already attached to the device"); device->PrepareForReplacement(); replacedDevices.push_back(device); } + timing.Mark("device_replacement"); device = std::make_shared(&window); + timing.Mark("vulkan_device_create"); const auto mapped = GuestAllocations::GuestAllocationsAcquire_nid_postfix(); - device->ImportGuestMemory(GuestAllocations::Mapped(mapped.begin(), mapped.end()), GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true); + timing.Mark("guest_mapping_snapshot", mapped.size()); + const bool imported = device->ImportGuestMemory(GuestAllocations::Mapped(mapped.begin(), mapped.end()), GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true); + timing.Mark(imported ? "existing_mappings_imported" : "existing_mappings_deferred", mapped.size()); } void Driver::Present(const PresentationWindow& window, const DisplayBuffer* buffer, const DisplayBuffer* plane, bool opaque, void (*gpuReady)(void*), void* context) { From 78eae40cf536d74f7e5b7bdcffc2debafcbcb2e4 Mon Sep 17 00:00:00 2001 From: Shaquib Nawaid <63773478+shaquib01@users.noreply.github.com> Date: Mon, 2 Nov 2026 17:04:37 +0530 Subject: [PATCH 3/9] test(agc): cover oversized host import budget refusal --- .../tests/execution/HostImportWindows.cpp | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/core/libs/prx/libSceAgcDriver/tests/execution/HostImportWindows.cpp b/core/libs/prx/libSceAgcDriver/tests/execution/HostImportWindows.cpp index 35e4f777cd..9465f554d2 100644 --- a/core/libs/prx/libSceAgcDriver/tests/execution/HostImportWindows.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/execution/HostImportWindows.cpp @@ -40,6 +40,7 @@ constexpr std::uint64_t BlockBytes = 2 * WindowBytes; constexpr std::uint64_t OtherBytes = 64 * 1024; constexpr std::uint64_t GuestAlignment = 64 * 1024; constexpr std::uint64_t ProbeBytes = 4096; +constexpr std::uint64_t TestImportBudgetMiB = 1; std::string Hex(std::uint64_t value) { char text[32]; @@ -206,10 +207,38 @@ Outcome SmallMappingsImportOnFirstUse() { return Outcome::Passed; } + +Outcome OversizedMappingRespectsImportBudget() { + GuestBlock oversized(2 * MiB); + auto device = OpenVulkanTestDevice(); + if (!device) return Outcome::NoDevice; + const auto context = AgcDriver::VulkanDeviceTestAccess::ContextOf(*device); + if (context.hostImportAlignment == 0) return Outcome::NoImport; + + GuestAllocations::Mapped ranges; + for (const auto& range : GuestAllocations::GuestAllocationsAcquire_nid_postfix()) { + if (range->address == oversized.Address()) ranges.push_back(range); + } + Require(ranges.size() == 1, "host import budget: the oversized mapping is not registered"); + + Graphics::ClearHostImports(device->Device()); + { + std::lock_guard lock(AgcDriver::GuestMemory::GpuMutex()); + Require(Graphics::ImportMappedRanges(context, ranges, GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true), "host import budget: device adoption failed"); + } + Require(!Graphics::HostImportCovers(context, oversized.Address(), ProbeBytes), "host import budget: a mapping larger than the configured budget was imported in full"); + return Outcome::Passed; +} + } int main() { try { +#ifdef _WIN32 + _putenv_s("APS5_HOST_IMPORT_MIB", "1"); +#else + setenv("APS5_HOST_IMPORT_MIB", "1", 1); +#endif const auto counting = ClearingDropsImports(); if (counting == Outcome::NoDevice) return VulkanTestSkipped; if (counting == Outcome::NoImport) { @@ -220,6 +249,8 @@ int main() { Require(windows == Outcome::Passed, "host import windows: the device stopped importing guest memory between two scenarios"); Require(ResidentMappingsImportAfterCollection() == Outcome::Passed, "resident import test failed"); Require(SmallMappingsImportOnFirstUse() == Outcome::Passed, "mapped import test lost its Vulkan device or host import support"); + const auto budget = OversizedMappingRespectsImportBudget(); + Require(budget == Outcome::Passed, "host import budget test lost its Vulkan device or host import support"); std::puts("host import windows tests passed"); return 0; } catch (const std::exception& error) { From 72b6a610c1a38b9b0c98cb832ac573be8dae647a Mon Sep 17 00:00:00 2001 From: Shaquib Nawaid <63773478+shaquib01@users.noreply.github.com> Date: Mon, 2 Nov 2026 17:05:00 +0530 Subject: [PATCH 4/9] test(agc): revert invalid isolated budget test --- .../tests/execution/HostImportWindows.cpp | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/core/libs/prx/libSceAgcDriver/tests/execution/HostImportWindows.cpp b/core/libs/prx/libSceAgcDriver/tests/execution/HostImportWindows.cpp index 9465f554d2..35e4f777cd 100644 --- a/core/libs/prx/libSceAgcDriver/tests/execution/HostImportWindows.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/execution/HostImportWindows.cpp @@ -40,7 +40,6 @@ constexpr std::uint64_t BlockBytes = 2 * WindowBytes; constexpr std::uint64_t OtherBytes = 64 * 1024; constexpr std::uint64_t GuestAlignment = 64 * 1024; constexpr std::uint64_t ProbeBytes = 4096; -constexpr std::uint64_t TestImportBudgetMiB = 1; std::string Hex(std::uint64_t value) { char text[32]; @@ -207,38 +206,10 @@ Outcome SmallMappingsImportOnFirstUse() { return Outcome::Passed; } - -Outcome OversizedMappingRespectsImportBudget() { - GuestBlock oversized(2 * MiB); - auto device = OpenVulkanTestDevice(); - if (!device) return Outcome::NoDevice; - const auto context = AgcDriver::VulkanDeviceTestAccess::ContextOf(*device); - if (context.hostImportAlignment == 0) return Outcome::NoImport; - - GuestAllocations::Mapped ranges; - for (const auto& range : GuestAllocations::GuestAllocationsAcquire_nid_postfix()) { - if (range->address == oversized.Address()) ranges.push_back(range); - } - Require(ranges.size() == 1, "host import budget: the oversized mapping is not registered"); - - Graphics::ClearHostImports(device->Device()); - { - std::lock_guard lock(AgcDriver::GuestMemory::GpuMutex()); - Require(Graphics::ImportMappedRanges(context, ranges, GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true), "host import budget: device adoption failed"); - } - Require(!Graphics::HostImportCovers(context, oversized.Address(), ProbeBytes), "host import budget: a mapping larger than the configured budget was imported in full"); - return Outcome::Passed; -} - } int main() { try { -#ifdef _WIN32 - _putenv_s("APS5_HOST_IMPORT_MIB", "1"); -#else - setenv("APS5_HOST_IMPORT_MIB", "1", 1); -#endif const auto counting = ClearingDropsImports(); if (counting == Outcome::NoDevice) return VulkanTestSkipped; if (counting == Outcome::NoImport) { @@ -249,8 +220,6 @@ int main() { Require(windows == Outcome::Passed, "host import windows: the device stopped importing guest memory between two scenarios"); Require(ResidentMappingsImportAfterCollection() == Outcome::Passed, "resident import test failed"); Require(SmallMappingsImportOnFirstUse() == Outcome::Passed, "mapped import test lost its Vulkan device or host import support"); - const auto budget = OversizedMappingRespectsImportBudget(); - Require(budget == Outcome::Passed, "host import budget test lost its Vulkan device or host import support"); std::puts("host import windows tests passed"); return 0; } catch (const std::exception& error) { From 1a9f6bf44832baa2e68ed8a165268c4f0f87e6bc Mon Sep 17 00:00:00 2001 From: Shaquib Nawaid <63773478+shaquib01@users.noreply.github.com> Date: Mon, 2 Nov 2026 17:05:15 +0530 Subject: [PATCH 5/9] perf(agc): add opt-out for eager host import A/B testing --- .../Execution/src/Driver/Presentation.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp index a5c0beeffc..3c34e58167 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp @@ -74,8 +74,14 @@ void Driver::AttachWindow(const PresentationWindow& window) { timing.Mark("vulkan_device_create"); const auto mapped = GuestAllocations::GuestAllocationsAcquire_nid_postfix(); timing.Mark("guest_mapping_snapshot", mapped.size()); - const bool imported = device->ImportGuestMemory(GuestAllocations::Mapped(mapped.begin(), mapped.end()), GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true); - timing.Mark(imported ? "existing_mappings_imported" : "existing_mappings_deferred", mapped.size()); + // A/B switch: compare eager window-attach imports with the normal first-use import path. + static const bool eagerHostImport = std::getenv("APS5_NO_EAGER_HOST_IMPORT") == nullptr; + if (eagerHostImport) { + const bool imported = device->ImportGuestMemory(GuestAllocations::Mapped(mapped.begin(), mapped.end()), GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true); + timing.Mark(imported ? "existing_mappings_imported" : "existing_mappings_deferred", mapped.size()); + } else { + timing.Mark("existing_mappings_skipped", mapped.size()); + } } void Driver::Present(const PresentationWindow& window, const DisplayBuffer* buffer, const DisplayBuffer* plane, bool opaque, void (*gpuReady)(void*), void* context) { From 7d90640470bbd01399e3579e7d481eb1922029ff Mon Sep 17 00:00:00 2001 From: Shaquib Nawaid <63773478+shaquib01@users.noreply.github.com> Date: Mon, 2 Nov 2026 17:06:26 +0530 Subject: [PATCH 6/9] style(agc): keep host import experiment comment-free --- .../prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp index 3c34e58167..f53ce0c37f 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp @@ -74,7 +74,6 @@ void Driver::AttachWindow(const PresentationWindow& window) { timing.Mark("vulkan_device_create"); const auto mapped = GuestAllocations::GuestAllocationsAcquire_nid_postfix(); timing.Mark("guest_mapping_snapshot", mapped.size()); - // A/B switch: compare eager window-attach imports with the normal first-use import path. static const bool eagerHostImport = std::getenv("APS5_NO_EAGER_HOST_IMPORT") == nullptr; if (eagerHostImport) { const bool imported = device->ImportGuestMemory(GuestAllocations::Mapped(mapped.begin(), mapped.end()), GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true); From d5eca4259db89c869639a1d28777f7059b54aba5 Mon Sep 17 00:00:00 2001 From: Shaquib Nawaid <63773478+shaquib01@users.noreply.github.com> Date: Mon, 2 Nov 2026 17:08:36 +0530 Subject: [PATCH 7/9] fix(agc): avoid bulk host imports while attaching window --- .../Execution/src/Driver/Presentation.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp index f53ce0c37f..2bed73d1b2 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp @@ -4,10 +4,8 @@ #include "prx/libSceAgcDriver/Execution/include/Driver/Queues/WorkerAffinity.hpp" #include "prx/libSceAgcDriver/Execution/include/GuestMemory.hpp" #include "prx/libSceAgcDriver/Execution/include/PerformanceTimer.hpp" -#include "prx/libc/include/GuestAllocations.hpp" #include #include "prx/libSceAgcDriver/Execution/include/TracyZone.hpp" -#include namespace AgcDriver::DriverDetail { @@ -72,15 +70,6 @@ void Driver::AttachWindow(const PresentationWindow& window) { timing.Mark("device_replacement"); device = std::make_shared(&window); timing.Mark("vulkan_device_create"); - const auto mapped = GuestAllocations::GuestAllocationsAcquire_nid_postfix(); - timing.Mark("guest_mapping_snapshot", mapped.size()); - static const bool eagerHostImport = std::getenv("APS5_NO_EAGER_HOST_IMPORT") == nullptr; - if (eagerHostImport) { - const bool imported = device->ImportGuestMemory(GuestAllocations::Mapped(mapped.begin(), mapped.end()), GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true); - timing.Mark(imported ? "existing_mappings_imported" : "existing_mappings_deferred", mapped.size()); - } else { - timing.Mark("existing_mappings_skipped", mapped.size()); - } } void Driver::Present(const PresentationWindow& window, const DisplayBuffer* buffer, const DisplayBuffer* plane, bool opaque, void (*gpuReady)(void*), void* context) { From 416ed7921bdcfd1230ba9f38d1456b0a7a0a36e9 Mon Sep 17 00:00:00 2001 From: Shaquib Nawaid <63773478+shaquib01@users.noreply.github.com> Date: Mon, 2 Nov 2026 17:14:51 +0530 Subject: [PATCH 8/9] fix(agc): retain direct cstdlib dependency --- .../prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp index 2bed73d1b2..f4a343c8d6 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp @@ -6,6 +6,7 @@ #include "prx/libSceAgcDriver/Execution/include/PerformanceTimer.hpp" #include #include "prx/libSceAgcDriver/Execution/include/TracyZone.hpp" +#include namespace AgcDriver::DriverDetail { From f9c826f7db6ac4c62d6fac720fe687010c473d8f Mon Sep 17 00:00:00 2001 From: Shaquib Nawaid <63773478+shaquib01@users.noreply.github.com> Date: Mon, 2 Nov 2026 21:56:43 +0530 Subject: [PATCH 9/9] fix(agc): separate window lock wait timing --- .../prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp index f4a343c8d6..034d0629e7 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp @@ -63,12 +63,13 @@ void Driver::AttachWindow(const PresentationWindow& window) { GuestMemory::TagGpuLockSite(GuestMemory::GpuLockSite::Present); PerformanceTimer timing("Driver.AttachWindow"); std::lock_guard lock(GuestMemory::GpuMutex()); + timing.Mark("gpu_mutex_wait"); if (device) { require(device->Window() == nullptr, "a window is already attached to the device"); device->PrepareForReplacement(); replacedDevices.push_back(device); + timing.Mark("device_replacement"); } - timing.Mark("device_replacement"); device = std::make_shared(&window); timing.Mark("vulkan_device_create"); }