diff --git a/README.md b/README.md index 7d920d2c..74fb26f8 100644 --- a/README.md +++ b/README.md @@ -218,7 +218,7 @@ make -j$(nproc) - Set to `0` to skip adapter/device preflight. - Bridge preflight also checks Vulkan Win32 interop funcs/extensions before enabling DX12 path. - Path B wrapper libraries must export the clean wrapper ABI (`include/rendering/amd_fsr3_wrapper_abi.h`): - - ABI version is currently `2` (dispatch includes external-memory/semaphore handle fields for bridge interop plumbing). + - ABI version is currently `3` (dispatch includes external-memory/semaphore handles plus acquire/release fence values for bridge sync). - `wowee_fsr3_wrapper_get_abi_version` - `wowee_fsr3_wrapper_initialize` - `wowee_fsr3_wrapper_dispatch_upscale` diff --git a/docs/AMD_FSR2_INTEGRATION.md b/docs/AMD_FSR2_INTEGRATION.md index cc906e8b..12ac856c 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 and semaphore handle fields in dispatch payload for bridge interop). +- Current wrapper ABI version: `3` (dispatch payload carries external memory/semaphore handles and acquire/release fence values for bridge synchronization). - Required wrapper exports: - `wowee_fsr3_wrapper_get_abi_version` - `wowee_fsr3_wrapper_initialize` diff --git a/include/rendering/amd_fsr3_runtime.hpp b/include/rendering/amd_fsr3_runtime.hpp index b2b1b678..4e9417d5 100644 --- a/include/rendering/amd_fsr3_runtime.hpp +++ b/include/rendering/amd_fsr3_runtime.hpp @@ -52,6 +52,8 @@ struct AmdFsr3RuntimeDispatchDesc { uint64_t frameGenOutputMemoryHandle = 0; uint64_t acquireSemaphoreHandle = 0; uint64_t releaseSemaphoreHandle = 0; + uint64_t acquireSemaphoreValue = 0; + uint64_t releaseSemaphoreValue = 0; }; class AmdFsr3Runtime { diff --git a/include/rendering/amd_fsr3_wrapper_abi.h b/include/rendering/amd_fsr3_wrapper_abi.h index 24518757..58ee8144 100644 --- a/include/rendering/amd_fsr3_wrapper_abi.h +++ b/include/rendering/amd_fsr3_wrapper_abi.h @@ -7,7 +7,7 @@ extern "C" { #endif -#define WOWEE_FSR3_WRAPPER_ABI_VERSION 2u +#define WOWEE_FSR3_WRAPPER_ABI_VERSION 3u typedef void* WoweeFsr3WrapperContext; @@ -58,6 +58,8 @@ typedef struct WoweeFsr3WrapperDispatchDesc { uint64_t frameGenOutputMemoryHandle; uint64_t acquireSemaphoreHandle; uint64_t releaseSemaphoreHandle; + uint64_t acquireSemaphoreValue; + uint64_t releaseSemaphoreValue; } WoweeFsr3WrapperDispatchDesc; enum { diff --git a/src/rendering/amd_fsr3_runtime.cpp b/src/rendering/amd_fsr3_runtime.cpp index f358581d..e83618dc 100644 --- a/src/rendering/amd_fsr3_runtime.cpp +++ b/src/rendering/amd_fsr3_runtime.cpp @@ -472,6 +472,8 @@ bool AmdFsr3Runtime::dispatchUpscale(const AmdFsr3RuntimeDispatchDesc& desc) { wrapperDesc.frameGenOutputMemoryHandle = desc.frameGenOutputMemoryHandle; wrapperDesc.acquireSemaphoreHandle = desc.acquireSemaphoreHandle; wrapperDesc.releaseSemaphoreHandle = desc.releaseSemaphoreHandle; + wrapperDesc.acquireSemaphoreValue = desc.acquireSemaphoreValue; + wrapperDesc.releaseSemaphoreValue = desc.releaseSemaphoreValue; const bool ok = fns_->wrapperDispatchUpscale(static_cast(wrapperContext_), &wrapperDesc) == 0; if (!ok) { if (fns_->wrapperGetLastError) { @@ -593,6 +595,8 @@ bool AmdFsr3Runtime::dispatchFrameGeneration(const AmdFsr3RuntimeDispatchDesc& d wrapperDesc.frameGenOutputMemoryHandle = desc.frameGenOutputMemoryHandle; wrapperDesc.acquireSemaphoreHandle = desc.acquireSemaphoreHandle; wrapperDesc.releaseSemaphoreHandle = desc.releaseSemaphoreHandle; + wrapperDesc.acquireSemaphoreValue = desc.acquireSemaphoreValue; + wrapperDesc.releaseSemaphoreValue = desc.releaseSemaphoreValue; const bool ok = fns_->wrapperDispatchFramegen(static_cast(wrapperContext_), &wrapperDesc) == 0; if (!ok) { if (fns_->wrapperGetLastError) { diff --git a/src/rendering/amd_fsr3_wrapper_impl.cpp b/src/rendering/amd_fsr3_wrapper_impl.cpp index 59d6e16e..79bb4257 100644 --- a/src/rendering/amd_fsr3_wrapper_impl.cpp +++ b/src/rendering/amd_fsr3_wrapper_impl.cpp @@ -846,7 +846,8 @@ WOWEE_FSR3_WRAPPER_EXPORT int32_t wowee_fsr3_wrapper_dispatch_upscale(WoweeFsr3W if ((dispatchDesc->externalFlags & requiredMask) != requiredMask || dispatchDesc->colorMemoryHandle == 0 || dispatchDesc->depthMemoryHandle == 0 || dispatchDesc->motionVectorMemoryHandle == 0 || dispatchDesc->outputMemoryHandle == 0 || - dispatchDesc->acquireSemaphoreHandle == 0 || dispatchDesc->releaseSemaphoreHandle == 0) { + dispatchDesc->acquireSemaphoreHandle == 0 || dispatchDesc->releaseSemaphoreHandle == 0 || + dispatchDesc->acquireSemaphoreValue == 0 || dispatchDesc->releaseSemaphoreValue == 0) { setContextError(ctx, "dx12_bridge dispatch missing required external handles for upscale"); return -1; } @@ -959,6 +960,11 @@ WOWEE_FSR3_WRAPPER_EXPORT int32_t wowee_fsr3_wrapper_dispatch_upscale(WoweeFsr3W setContextError(ctx, "dx12_bridge failed to close command list after upscale dispatch"); return -1; } + if (acquireFence && ctx->dx12Queue->Wait(acquireFence, dispatchDesc->acquireSemaphoreValue) != S_OK) { + cleanupDx12Imports(); + setContextError(ctx, "dx12_bridge failed to wait on shared acquire fence before upscale dispatch"); + return -1; + } ID3D12CommandList* lists[] = {ctx->dx12CommandList}; ctx->dx12Queue->ExecuteCommandLists(1, lists); const uint64_t waitValue = ctx->dx12FenceValue++; @@ -971,7 +977,7 @@ WOWEE_FSR3_WRAPPER_EXPORT int32_t wowee_fsr3_wrapper_dispatch_upscale(WoweeFsr3W ctx->dx12Fence->SetEventOnCompletion(waitValue, ctx->dx12FenceEvent); WaitForSingleObject(ctx->dx12FenceEvent, INFINITE); } - if (releaseFence && ctx->dx12Queue->Signal(releaseFence, waitValue) != S_OK) { + if (releaseFence && ctx->dx12Queue->Signal(releaseFence, dispatchDesc->releaseSemaphoreValue) != S_OK) { cleanupDx12Imports(); setContextError(ctx, "dx12_bridge failed to signal shared release fence after upscale dispatch"); return -1; @@ -1015,7 +1021,8 @@ WOWEE_FSR3_WRAPPER_EXPORT int32_t wowee_fsr3_wrapper_dispatch_framegen(WoweeFsr3 WOWEE_FSR3_WRAPPER_EXTERNAL_RELEASE_SEMAPHORE; if ((dispatchDesc->externalFlags & requiredMask) != requiredMask || dispatchDesc->outputMemoryHandle == 0 || dispatchDesc->frameGenOutputMemoryHandle == 0 || - dispatchDesc->acquireSemaphoreHandle == 0 || dispatchDesc->releaseSemaphoreHandle == 0) { + dispatchDesc->acquireSemaphoreHandle == 0 || dispatchDesc->releaseSemaphoreHandle == 0 || + dispatchDesc->acquireSemaphoreValue == 0 || dispatchDesc->releaseSemaphoreValue == 0) { setContextError(ctx, "dx12_bridge dispatch missing required external handles for frame generation"); return -1; } @@ -1097,6 +1104,11 @@ WOWEE_FSR3_WRAPPER_EXPORT int32_t wowee_fsr3_wrapper_dispatch_framegen(WoweeFsr3 setContextError(ctx, "dx12_bridge failed to close command list after frame generation dispatch"); return -1; } + if (acquireFence && ctx->dx12Queue->Wait(acquireFence, dispatchDesc->acquireSemaphoreValue) != S_OK) { + cleanupDx12Imports(); + setContextError(ctx, "dx12_bridge failed to wait on shared acquire fence before frame generation dispatch"); + return -1; + } ID3D12CommandList* lists[] = {ctx->dx12CommandList}; ctx->dx12Queue->ExecuteCommandLists(1, lists); const uint64_t waitValue = ctx->dx12FenceValue++; @@ -1109,7 +1121,7 @@ WOWEE_FSR3_WRAPPER_EXPORT int32_t wowee_fsr3_wrapper_dispatch_framegen(WoweeFsr3 ctx->dx12Fence->SetEventOnCompletion(waitValue, ctx->dx12FenceEvent); WaitForSingleObject(ctx->dx12FenceEvent, INFINITE); } - if (releaseFence && ctx->dx12Queue->Signal(releaseFence, waitValue) != S_OK) { + if (releaseFence && ctx->dx12Queue->Signal(releaseFence, dispatchDesc->releaseSemaphoreValue) != S_OK) { cleanupDx12Imports(); setContextError(ctx, "dx12_bridge failed to signal shared release fence after frame generation dispatch"); return -1; diff --git a/src/rendering/renderer.cpp b/src/rendering/renderer.cpp index 7c93f3a5..fec07b04 100644 --- a/src/rendering/renderer.cpp +++ b/src/rendering/renderer.cpp @@ -4606,6 +4606,8 @@ void Renderer::dispatchAmdFsr3Framegen() { fgDispatch.externalFlags |= WOWEE_FSR3_WRAPPER_EXTERNAL_RELEASE_SEMAPHORE; trackHandle(fgDispatch.releaseSemaphoreHandle); } + fgDispatch.acquireSemaphoreValue = 1; + fgDispatch.releaseSemaphoreValue = 1; #endif if (!fsr2_.amdFsr3Runtime->dispatchUpscale(fgDispatch)) {