diff --git a/docs/AMD_FSR2_INTEGRATION.md b/docs/AMD_FSR2_INTEGRATION.md index a2e81ca6..8ce0ab18 100644 --- a/docs/AMD_FSR2_INTEGRATION.md +++ b/docs/AMD_FSR2_INTEGRATION.md @@ -67,7 +67,7 @@ Runtime note: - required device extensions: `VK_KHR_external_memory`, `VK_KHR_external_memory_win32`, `VK_KHR_external_semaphore`, `VK_KHR_external_semaphore_win32` - Path B wrapper ABI contract is declared in: - `include/rendering/amd_fsr3_wrapper_abi.h` -- Current wrapper ABI version: `2` (adds external memory/semaphore handle fields in dispatch payload for bridge interop). +- Current wrapper ABI version: `2` (adds external memory and semaphore handle fields in dispatch payload for bridge interop). - Required wrapper exports: - `wowee_fsr3_wrapper_get_abi_version` - `wowee_fsr3_wrapper_initialize` diff --git a/src/rendering/amd_fsr3_wrapper_impl.cpp b/src/rendering/amd_fsr3_wrapper_impl.cpp index 2cb82911..7f972af0 100644 --- a/src/rendering/amd_fsr3_wrapper_impl.cpp +++ b/src/rendering/amd_fsr3_wrapper_impl.cpp @@ -663,10 +663,13 @@ WOWEE_FSR3_WRAPPER_EXPORT int32_t wowee_fsr3_wrapper_dispatch_upscale(WoweeFsr3W WOWEE_FSR3_WRAPPER_EXTERNAL_COLOR_MEMORY | WOWEE_FSR3_WRAPPER_EXTERNAL_DEPTH_MEMORY | WOWEE_FSR3_WRAPPER_EXTERNAL_MOTION_MEMORY | - WOWEE_FSR3_WRAPPER_EXTERNAL_OUTPUT_MEMORY; + WOWEE_FSR3_WRAPPER_EXTERNAL_OUTPUT_MEMORY | + WOWEE_FSR3_WRAPPER_EXTERNAL_ACQUIRE_SEMAPHORE | + WOWEE_FSR3_WRAPPER_EXTERNAL_RELEASE_SEMAPHORE; if ((dispatchDesc->externalFlags & requiredMask) != requiredMask || dispatchDesc->colorMemoryHandle == 0 || dispatchDesc->depthMemoryHandle == 0 || - dispatchDesc->motionVectorMemoryHandle == 0 || dispatchDesc->outputMemoryHandle == 0) { + dispatchDesc->motionVectorMemoryHandle == 0 || dispatchDesc->outputMemoryHandle == 0 || + dispatchDesc->acquireSemaphoreHandle == 0 || dispatchDesc->releaseSemaphoreHandle == 0) { return -1; } } @@ -730,9 +733,12 @@ WOWEE_FSR3_WRAPPER_EXPORT int32_t wowee_fsr3_wrapper_dispatch_framegen(WoweeFsr3 if (ctx->backend == WrapperBackend::Dx12Bridge) { const uint32_t requiredMask = WOWEE_FSR3_WRAPPER_EXTERNAL_OUTPUT_MEMORY | - WOWEE_FSR3_WRAPPER_EXTERNAL_FRAMEGEN_OUTPUT_MEMORY; + WOWEE_FSR3_WRAPPER_EXTERNAL_FRAMEGEN_OUTPUT_MEMORY | + WOWEE_FSR3_WRAPPER_EXTERNAL_ACQUIRE_SEMAPHORE | + WOWEE_FSR3_WRAPPER_EXTERNAL_RELEASE_SEMAPHORE; if ((dispatchDesc->externalFlags & requiredMask) != requiredMask || - dispatchDesc->outputMemoryHandle == 0 || dispatchDesc->frameGenOutputMemoryHandle == 0) { + dispatchDesc->outputMemoryHandle == 0 || dispatchDesc->frameGenOutputMemoryHandle == 0 || + dispatchDesc->acquireSemaphoreHandle == 0 || dispatchDesc->releaseSemaphoreHandle == 0) { return -1; } } diff --git a/src/rendering/renderer.cpp b/src/rendering/renderer.cpp index c1ff9bfc..dcf1f722 100644 --- a/src/rendering/renderer.cpp +++ b/src/rendering/renderer.cpp @@ -58,6 +58,7 @@ #include "rendering/vk_pipeline.hpp" #include "rendering/vk_utils.hpp" #include "rendering/amd_fsr3_runtime.hpp" +#include "rendering/amd_fsr3_wrapper_abi.h" #include #include #include @@ -134,6 +135,23 @@ static uint64_t exportImageMemoryHandleWin32(VkDevice device, PFN_vkGetDevicePro if (getMemHandle(device, &handleInfo, &outHandle) != VK_SUCCESS || !outHandle) return 0; return reinterpret_cast(outHandle); } + +static uint64_t exportSemaphoreHandleWin32(VkDevice device, PFN_vkGetDeviceProcAddr getDeviceProcAddr, + VkSemaphore semaphore) { + if (!device || !getDeviceProcAddr || !semaphore) return 0; + auto getSemHandle = reinterpret_cast( + getDeviceProcAddr(device, "vkGetSemaphoreWin32HandleKHR")); + if (!getSemHandle) return 0; + + VkSemaphoreGetWin32HandleInfoKHR handleInfo{}; + handleInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR; + handleInfo.semaphore = semaphore; + handleInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT; + + HANDLE outHandle = nullptr; + if (getSemHandle(device, &handleInfo, &outHandle) != VK_SUCCESS || !outHandle) return 0; + return reinterpret_cast(outHandle); +} #endif static std::vector parseEmoteCommands(const std::string& raw) { @@ -4559,6 +4577,20 @@ void Renderer::dispatchAmdFsr3Framegen() { fgDispatch.externalFlags |= WOWEE_FSR3_WRAPPER_EXTERNAL_FRAMEGEN_OUTPUT_MEMORY; trackHandle(fgDispatch.frameGenOutputMemoryHandle); } + + const FrameData& frameData = vkCtx->getCurrentFrameData(); + fgDispatch.acquireSemaphoreHandle = exportSemaphoreHandleWin32( + device, vkGetDeviceProcAddr, frameData.imageAvailableSemaphore); + if (fgDispatch.acquireSemaphoreHandle) { + fgDispatch.externalFlags |= WOWEE_FSR3_WRAPPER_EXTERNAL_ACQUIRE_SEMAPHORE; + trackHandle(fgDispatch.acquireSemaphoreHandle); + } + fgDispatch.releaseSemaphoreHandle = exportSemaphoreHandleWin32( + device, vkGetDeviceProcAddr, frameData.renderFinishedSemaphore); + if (fgDispatch.releaseSemaphoreHandle) { + fgDispatch.externalFlags |= WOWEE_FSR3_WRAPPER_EXTERNAL_RELEASE_SEMAPHORE; + trackHandle(fgDispatch.releaseSemaphoreHandle); + } #endif if (!fsr2_.amdFsr3Runtime->dispatchUpscale(fgDispatch)) {