|
|
@ -9,8 +9,10 @@ |
|
|
#include "UnityPluginAPI/IUnityGraphics.h"
|
|
|
#include "UnityPluginAPI/IUnityGraphics.h"
|
|
|
#include "UnityPluginAPI/IUnityRenderingExtensions.h"
|
|
|
#include "UnityPluginAPI/IUnityRenderingExtensions.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <d3d11.h>
|
|
|
#include <d3d12.h>
|
|
|
#include <d3d12.h>
|
|
|
#include <dxgi.h>
|
|
|
#include <dxgi.h>
|
|
|
|
|
|
#include "UnityPluginAPI/IUnityGraphicsD3D11.h"
|
|
|
#include "UnityPluginAPI/IUnityGraphicsD3D12.h"
|
|
|
#include "UnityPluginAPI/IUnityGraphicsD3D12.h"
|
|
|
#include "UnityPluginAPI/IUnityGraphicsVulkan.h"
|
|
|
#include "UnityPluginAPI/IUnityGraphicsVulkan.h"
|
|
|
|
|
|
|
|
|
@ -19,6 +21,9 @@ |
|
|
#include "ffx_api/dx12/ffx_api_dx12.hpp"
|
|
|
#include "ffx_api/dx12/ffx_api_dx12.hpp"
|
|
|
#include "ffx_api/vk/ffx_api_vk.hpp"
|
|
|
#include "ffx_api/vk/ffx_api_vk.hpp"
|
|
|
|
|
|
|
|
|
|
|
|
#include "ffx-fsr2-api/ffx_fsr2.h"
|
|
|
|
|
|
#include "ffx-fsr2-api/dx11/ffx_fsr2_dx11.h"
|
|
|
|
|
|
|
|
|
#include "FSR3UnityTypes.h"
|
|
|
#include "FSR3UnityTypes.h"
|
|
|
|
|
|
|
|
|
static const int32_t BaseEventId = 0; |
|
|
static const int32_t BaseEventId = 0; |
|
|
@ -26,6 +31,7 @@ static const int32_t BaseEventId = 0; |
|
|
static IUnityInterfaces* s_UnityInterfaces = nullptr; |
|
|
static IUnityInterfaces* s_UnityInterfaces = nullptr; |
|
|
static IUnityLog* s_Log = nullptr; |
|
|
static IUnityLog* s_Log = nullptr; |
|
|
static IUnityGraphics* s_Graphics = nullptr; |
|
|
static IUnityGraphics* s_Graphics = nullptr; |
|
|
|
|
|
static IUnityGraphicsD3D11* s_GraphicsD3D11 = nullptr; |
|
|
static IUnityGraphicsD3D12v7* s_GraphicsD3D12 = nullptr; |
|
|
static IUnityGraphicsD3D12v7* s_GraphicsD3D12 = nullptr; |
|
|
static IUnityGraphicsVulkan* s_GraphicsVulkan = nullptr; |
|
|
static IUnityGraphicsVulkan* s_GraphicsVulkan = nullptr; |
|
|
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull; |
|
|
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull; |
|
|
@ -37,6 +43,8 @@ static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data); |
|
|
struct FSR3Feature |
|
|
struct FSR3Feature |
|
|
{ |
|
|
{ |
|
|
ffx::Context upscalingContext; |
|
|
ffx::Context upscalingContext; |
|
|
|
|
|
FfxFsr2Context fsr2Context; |
|
|
|
|
|
bool isValid; |
|
|
|
|
|
|
|
|
uint32_t upscaleSizeWidth; |
|
|
uint32_t upscaleSizeWidth; |
|
|
uint32_t upscaleSizeHeight; |
|
|
uint32_t upscaleSizeHeight; |
|
|
@ -54,6 +62,9 @@ static ffxFunctions s_ffxFunctions{}; |
|
|
static ffx::CreateBackendDX12Desc s_DX12BackendDesc{}; |
|
|
static ffx::CreateBackendDX12Desc s_DX12BackendDesc{}; |
|
|
static ffx::CreateBackendVKDesc s_VulkanBackendDesc{}; |
|
|
static ffx::CreateBackendVKDesc s_VulkanBackendDesc{}; |
|
|
|
|
|
|
|
|
|
|
|
static FfxDevice s_DX11Device = nullptr; |
|
|
|
|
|
static FfxFsr2Interface s_Fsr2Interface; |
|
|
|
|
|
|
|
|
// Unity plugin load event
|
|
|
// Unity plugin load event
|
|
|
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces) |
|
|
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces) |
|
|
{ |
|
|
{ |
|
|
@ -83,6 +94,16 @@ static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType ev |
|
|
s_RendererType = s_Graphics->GetRenderer(); |
|
|
s_RendererType = s_Graphics->GetRenderer(); |
|
|
switch (s_RendererType) |
|
|
switch (s_RendererType) |
|
|
{ |
|
|
{ |
|
|
|
|
|
case kUnityGfxRendererD3D11: |
|
|
|
|
|
{ |
|
|
|
|
|
s_GraphicsD3D11 = s_UnityInterfaces->Get<IUnityGraphicsD3D11>(); |
|
|
|
|
|
if (s_GraphicsD3D11 == nullptr) |
|
|
|
|
|
{ |
|
|
|
|
|
UNITY_LOG_ERROR(s_Log, "Could not obtain D3D11 Graphics interface!"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
case kUnityGfxRendererD3D12: |
|
|
case kUnityGfxRendererD3D12: |
|
|
{ |
|
|
{ |
|
|
s_GraphicsD3D12 = s_UnityInterfaces->Get<IUnityGraphicsD3D12v7>(); |
|
|
s_GraphicsD3D12 = s_UnityInterfaces->Get<IUnityGraphicsD3D12v7>(); |
|
|
@ -111,6 +132,7 @@ static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType ev |
|
|
{ |
|
|
{ |
|
|
s_GraphicsVulkan = nullptr; |
|
|
s_GraphicsVulkan = nullptr; |
|
|
s_GraphicsD3D12 = nullptr; |
|
|
s_GraphicsD3D12 = nullptr; |
|
|
|
|
|
s_GraphicsD3D11 = nullptr; |
|
|
s_RendererType = kUnityGfxRendererNull; |
|
|
s_RendererType = kUnityGfxRendererNull; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
@ -135,6 +157,7 @@ static uint32_t AllocateFeatureSlot() |
|
|
// Create a new feature if there are no free slots
|
|
|
// Create a new feature if there are no free slots
|
|
|
uint32_t featureSlot = (uint32_t)s_Features.size(); |
|
|
uint32_t featureSlot = (uint32_t)s_Features.size(); |
|
|
s_Features.push_back(std::move(FSR3Feature())); |
|
|
s_Features.push_back(std::move(FSR3Feature())); |
|
|
|
|
|
memset(&s_Features[featureSlot], 0, sizeof(FSR3Feature)); |
|
|
return featureSlot; |
|
|
return featureSlot; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -180,6 +203,19 @@ static bool LoadFidelityFXLibrary(_In_ LPCWSTR lpLibFileName) |
|
|
|
|
|
|
|
|
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() |
|
|
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() |
|
|
{ |
|
|
{ |
|
|
|
|
|
if (s_GraphicsD3D11 != nullptr) |
|
|
|
|
|
{ |
|
|
|
|
|
ID3D11Device* device = s_GraphicsD3D11->GetDevice(); |
|
|
|
|
|
if (device == nullptr) |
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
s_DX11Device = ffxGetDeviceDX11(device); |
|
|
|
|
|
|
|
|
|
|
|
size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeDX11(); |
|
|
|
|
|
void* scratchBuffer = malloc(scratchBufferSize); |
|
|
|
|
|
ffxFsr2GetInterfaceDX11(&s_Fsr2Interface, device, scratchBuffer, scratchBufferSize); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
if (s_GraphicsD3D12 != nullptr) |
|
|
if (s_GraphicsD3D12 != nullptr) |
|
|
{ |
|
|
{ |
|
|
ID3D12Device* device = s_GraphicsD3D12->GetDevice(); |
|
|
ID3D12Device* device = s_GraphicsD3D12->GetDevice(); |
|
|
@ -216,6 +252,11 @@ extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_ShutdownApi() |
|
|
s_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr); |
|
|
s_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr); |
|
|
FreeFeatureSlot(slot); |
|
|
FreeFeatureSlot(slot); |
|
|
} |
|
|
} |
|
|
|
|
|
else if (feature.isValid) |
|
|
|
|
|
{ |
|
|
|
|
|
ffxFsr2ContextDestroy(&feature.fsr2Context); |
|
|
|
|
|
FreeFeatureSlot(slot); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (s_ffxModule != nullptr) |
|
|
if (s_ffxModule != nullptr) |
|
|
@ -223,12 +264,20 @@ extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_ShutdownApi() |
|
|
FreeLibrary(s_ffxModule); |
|
|
FreeLibrary(s_ffxModule); |
|
|
s_ffxModule = nullptr; |
|
|
s_ffxModule = nullptr; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (s_Fsr2Interface.scratchBuffer != nullptr) |
|
|
|
|
|
{ |
|
|
|
|
|
free(s_Fsr2Interface.scratchBuffer); |
|
|
|
|
|
s_Fsr2Interface.scratchBuffer = nullptr; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
s_VulkanBackendDesc.vkDevice = nullptr; |
|
|
s_VulkanBackendDesc.vkDevice = nullptr; |
|
|
s_VulkanBackendDesc.vkPhysicalDevice = nullptr; |
|
|
s_VulkanBackendDesc.vkPhysicalDevice = nullptr; |
|
|
s_VulkanBackendDesc.vkDeviceProcAddr = nullptr; |
|
|
s_VulkanBackendDesc.vkDeviceProcAddr = nullptr; |
|
|
|
|
|
|
|
|
s_DX12BackendDesc.device = nullptr; |
|
|
s_DX12BackendDesc.device = nullptr; |
|
|
|
|
|
|
|
|
|
|
|
s_DX11Device = nullptr; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetDeviceVersion() |
|
|
extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetDeviceVersion() |
|
|
@ -321,6 +370,11 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) |
|
|
s_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr); |
|
|
s_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr); |
|
|
FreeFeatureSlot(featureSlot); |
|
|
FreeFeatureSlot(featureSlot); |
|
|
} |
|
|
} |
|
|
|
|
|
else if (feature.isValid) |
|
|
|
|
|
{ |
|
|
|
|
|
ffxFsr2ContextDestroy(&feature.fsr2Context); |
|
|
|
|
|
FreeFeatureSlot(featureSlot); |
|
|
|
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case BaseEventId + FSR3PluginEvent::eExecute: |
|
|
case BaseEventId + FSR3PluginEvent::eExecute: |
|
|
@ -331,6 +385,52 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) |
|
|
|
|
|
|
|
|
auto& feature = s_Features[params->featureSlot]; |
|
|
auto& feature = s_Features[params->featureSlot]; |
|
|
|
|
|
|
|
|
|
|
|
if (s_GraphicsD3D11 != nullptr) |
|
|
|
|
|
{ |
|
|
|
|
|
// Execute FSR 2.2 on DX11
|
|
|
|
|
|
FfxFsr2DispatchDescription dispatchDescription{}; |
|
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext* ctx = nullptr; |
|
|
|
|
|
s_GraphicsD3D11->GetDevice()->GetImmediateContext(&ctx); |
|
|
|
|
|
dispatchDescription.commandList = ctx; |
|
|
|
|
|
|
|
|
|
|
|
dispatchDescription.color = ffxGetResourceDX11(&feature.fsr2Context, (ID3D11Resource*)feature.textureTable.colorInput.image); |
|
|
|
|
|
dispatchDescription.depth = ffxGetResourceDX11(&feature.fsr2Context, (ID3D11Resource*)feature.textureTable.depth.image); |
|
|
|
|
|
dispatchDescription.motionVectors = ffxGetResourceDX11(&feature.fsr2Context, (ID3D11Resource*)feature.textureTable.motionVectors.image); |
|
|
|
|
|
dispatchDescription.exposure = ffxGetResourceDX11(&feature.fsr2Context, (ID3D11Resource*)feature.textureTable.exposureTexture.image); |
|
|
|
|
|
dispatchDescription.reactive = ffxGetResourceDX11(&feature.fsr2Context, (ID3D11Resource*)feature.textureTable.reactiveMask.image); |
|
|
|
|
|
dispatchDescription.transparencyAndComposition = ffxGetResourceDX11(&feature.fsr2Context, (ID3D11Resource*)feature.textureTable.transparencyMask.image); |
|
|
|
|
|
dispatchDescription.output = ffxGetResourceDX11(&feature.fsr2Context, (ID3D11Resource*)feature.textureTable.colorOutput.image, nullptr, FFX_RESOURCE_STATE_UNORDERED_ACCESS); |
|
|
|
|
|
|
|
|
|
|
|
dispatchDescription.jitterOffset.x = params->jitterOffsetX; |
|
|
|
|
|
dispatchDescription.jitterOffset.y = params->jitterOffsetY; |
|
|
|
|
|
dispatchDescription.motionVectorScale.x = params->MVScaleX; |
|
|
|
|
|
dispatchDescription.motionVectorScale.y = params->MVScaleY; |
|
|
|
|
|
dispatchDescription.reset = params->reset; |
|
|
|
|
|
dispatchDescription.enableSharpening = params->enableSharpening; |
|
|
|
|
|
dispatchDescription.sharpness = params->sharpness; |
|
|
|
|
|
dispatchDescription.frameTimeDelta = params->frameTimeDelta; |
|
|
|
|
|
dispatchDescription.preExposure = params->preExposure; |
|
|
|
|
|
dispatchDescription.renderSize.width = params->renderSizeWidth; |
|
|
|
|
|
dispatchDescription.renderSize.height = params->renderSizeHeight; |
|
|
|
|
|
dispatchDescription.cameraFovAngleVertical = params->cameraFovAngleVertical; |
|
|
|
|
|
|
|
|
|
|
|
if (feature.flags & FFX_FSR2_ENABLE_DEPTH_INVERTED) |
|
|
|
|
|
{ |
|
|
|
|
|
dispatchDescription.cameraFar = params->cameraNear; |
|
|
|
|
|
dispatchDescription.cameraNear = params->cameraFar; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
dispatchDescription.cameraFar = params->cameraFar; |
|
|
|
|
|
dispatchDescription.cameraNear = params->cameraNear; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ffxFsr2ContextDispatch(&feature.fsr2Context, &dispatchDescription); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Execute FSR 3.1 or higher on DX12 and Vulkan
|
|
|
ffx::DispatchDescUpscale dispatchUpscale{}; |
|
|
ffx::DispatchDescUpscale dispatchUpscale{}; |
|
|
|
|
|
|
|
|
if (s_GraphicsD3D12 != nullptr) |
|
|
if (s_GraphicsD3D12 != nullptr) |
|
|
@ -408,6 +508,21 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) |
|
|
feature.upscaleSizeHeight = params->displaySizeHeight; |
|
|
feature.upscaleSizeHeight = params->displaySizeHeight; |
|
|
feature.flags = params->flags; |
|
|
feature.flags = params->flags; |
|
|
|
|
|
|
|
|
|
|
|
if (s_GraphicsD3D11 != nullptr) |
|
|
|
|
|
{ |
|
|
|
|
|
// Create an FSR 2.2 context on DX11
|
|
|
|
|
|
FfxFsr2ContextDescription contextDescription{}; |
|
|
|
|
|
contextDescription.callbacks = s_Fsr2Interface; |
|
|
|
|
|
contextDescription.device = s_DX11Device; |
|
|
|
|
|
contextDescription.displaySize = { params->displaySizeWidth, params->displaySizeHeight }; |
|
|
|
|
|
contextDescription.maxRenderSize = { params->maxRenderSizeWidth, params->maxRenderSizeHeight }; |
|
|
|
|
|
contextDescription.flags = params->flags; |
|
|
|
|
|
|
|
|
|
|
|
feature.isValid = ffxFsr2ContextCreate(&feature.fsr2Context, &contextDescription) == FFX_OK; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Create an FSR 3.1 or higher context on DX12 and Vulkan
|
|
|
ffx::CreateContextDescUpscale createUpscaling; |
|
|
ffx::CreateContextDescUpscale createUpscaling; |
|
|
createUpscaling.maxUpscaleSize = { params->displaySizeWidth, params->displaySizeHeight }; |
|
|
createUpscaling.maxUpscaleSize = { params->displaySizeWidth, params->displaySizeHeight }; |
|
|
createUpscaling.maxRenderSize = { params->maxRenderSizeWidth, params->maxRenderSizeHeight }; |
|
|
createUpscaling.maxRenderSize = { params->maxRenderSizeWidth, params->maxRenderSizeHeight }; |
|
|
@ -457,6 +572,10 @@ static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data) |
|
|
// This way we can use the texture slot value simply as a pointer offset into the texture table
|
|
|
// This way we can use the texture slot value simply as a pointer offset into the texture table
|
|
|
FSR3TextureDesc* textureDesc = ((FSR3TextureDesc*)&feature.textureTable) + textureSlot; |
|
|
FSR3TextureDesc* textureDesc = ((FSR3TextureDesc*)&feature.textureTable) + textureSlot; |
|
|
|
|
|
|
|
|
|
|
|
if (s_GraphicsD3D11 != nullptr) |
|
|
|
|
|
{ |
|
|
|
|
|
textureDesc->image = (intptr_t)s_GraphicsD3D11->TextureFromNativeTexture((UnityTextureID)params->textureID); |
|
|
|
|
|
} |
|
|
if (s_GraphicsD3D12 != nullptr) |
|
|
if (s_GraphicsD3D12 != nullptr) |
|
|
{ |
|
|
{ |
|
|
textureDesc->image = (intptr_t)s_GraphicsD3D12->TextureFromNativeTexture((UnityTextureID)params->textureID); |
|
|
textureDesc->image = (intptr_t)s_GraphicsD3D12->TextureFromNativeTexture((UnityTextureID)params->textureID); |
|
|
|