From 2d5b13383369fb9972d686506c797e84a89e534c Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Mon, 10 Mar 2025 16:05:36 +0100 Subject: [PATCH] Implemented thread-safe allocation/freeing of feature slots, plus decoding of texture userdata --- FSR3UnityPlugin.cpp | 53 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/FSR3UnityPlugin.cpp b/FSR3UnityPlugin.cpp index 89ecd97..fc04a0a 100644 --- a/FSR3UnityPlugin.cpp +++ b/FSR3UnityPlugin.cpp @@ -1,5 +1,9 @@ #include +#include +#include +#include + #include "UnityPluginAPI/IUnityInterface.h" #include "UnityPluginAPI/IUnityLog.h" #include "UnityPluginAPI/IUnityGraphics.h" @@ -19,6 +23,15 @@ static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType ev static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data); static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data); +struct FSR3Context +{ + // TODO: contains FSR3 context object + related metadata (texture table etc) +}; + +static std::vector s_Contexts; +static std::queue s_FeatureSlots; +static std::mutex s_FeatureMutex; + // Unity plugin load event extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces) { @@ -68,6 +81,32 @@ static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType ev }; } +// Thread-safe allocation of FSR3 Context feature slot +static uint32_t AllocateFeatureSlot() +{ + std::lock_guard lock(s_FeatureMutex); + + if (s_FeatureSlots.empty()) + { + uint32_t featureSlot = (uint32_t)s_Contexts.size(); + s_Contexts.push_back(std::move(FSR3Context())); + return featureSlot; + } + + uint32_t featureSlot = s_FeatureSlots.front(); + s_FeatureSlots.pop(); + return featureSlot; +} + +// Thread-safe freeing and clearing of FSR3 Context feature slot +static void FreeFeatureSlot(uint32_t featureSlot) +{ + std::lock_guard lock(s_FeatureMutex); + + s_FeatureSlots.push(featureSlot); + memset(&s_Contexts[featureSlot], 0, sizeof(FSR3Context)); +} + extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() { // TODO: implement @@ -96,18 +135,15 @@ extern "C" UnityRenderingEventAndData UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_CreateFeatureSlot() { - // TODO: thread-safe allocation of slot - return 0u; + return AllocateFeatureSlot(); } -// TODO: use FSR2Quality enum for qualityMode extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetRenderResolutionFromQualityMode(FSR3Quality qualityMode, uint32_t displayWidth, uint32_t displayHeight, uint32_t* renderWidth, uint32_t* renderHeight) { // TODO: implement return false; } -// TODO: use FSR2Quality enum for qualityMode extern "C" float UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetUpscaleRatioFromQualityMode(FSR3Quality qualityMode) { // TODO: implement @@ -127,8 +163,9 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) { case BaseEventId + FSR3PluginEvent::eDestroyFeature: { - // TODO: thread-safe freeing of slot (data = feature slot int64_t, cast as pointer) uint32_t featureSlot = (uint32_t)(int64_t)data; + // TODO: destroy FSR3Context at feature slot index + FreeFeatureSlot(featureSlot); break; } case BaseEventId + FSR3PluginEvent::eExecute: @@ -151,11 +188,11 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data) { - // TODO userData field in UnityRenderingExtTextureUpdateParamsV2 is an encoded value: (featureId & (int) ushort.MaxValue) << 16 | (textureSlot & (int) short.MaxValue) << 1 | (clearTextureTable ? 1 : 0); auto* params = (UnityRenderingExtTextureUpdateParamsV2*)data; - // TODO: featureId => featureSlot - // TODO: textureSlot => FSR3Textures enum (could just use as numeric index to calculate a pointer offset) + uint32_t featureSlot = (params->userData >> 16) & 0xFFFF; + uint32_t textureSlot = (params->userData >> 1) & 0x7FFF; // TODO: could just use as numeric index to calculate a pointer offset + uint32_t clearTextureTable = params->userData & 0x1; // User rendering code switch (eventID)