Browse Source

Merged FSR 2.2 implementation for DX11 into the plugin, so that it supports all three major Windows graphics APIs.

master
Nico de Poel 11 months ago
parent
commit
19fd96989e
  1. 119
      FSR3UnityPlugin.cpp
  2. 4
      FSR3UnityPlugin.vcxproj
  3. 2
      FSR3UnityTypes.h
  4. 27
      UnityPluginAPI/IUnityGraphicsD3D11.h

119
FSR3UnityPlugin.cpp

@ -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);

4
FSR3UnityPlugin.vcxproj

@ -124,7 +124,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);vulkan-1.lib</AdditionalDependencies>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);lib\ffx_fsr2_api\ffx_fsr2_api_x64d.lib;lib\ffx_fsr2_api\ffx_fsr2_api_dx11_x64d.lib;dxguid.lib;vulkan-1.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>%VULKAN_SDK%\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%VULKAN_SDK%\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -146,7 +146,7 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);vulkan-1.lib</AdditionalDependencies>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);lib\ffx_fsr2_api\ffx_fsr2_api_x64.lib;lib\ffx_fsr2_api\ffx_fsr2_api_dx11_x64.lib;dxguid.lib;vulkan-1.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>%VULKAN_SDK%\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%VULKAN_SDK%\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>

2
FSR3UnityTypes.h

@ -78,6 +78,4 @@ struct FSR3TextureTable
FSR3TextureDesc exposureTexture; FSR3TextureDesc exposureTexture;
FSR3TextureDesc reactiveMask; FSR3TextureDesc reactiveMask;
FSR3TextureDesc biasColorMask; FSR3TextureDesc biasColorMask;
uint32_t featureSlot;
}; };

27
UnityPluginAPI/IUnityGraphicsD3D11.h

@ -0,0 +1,27 @@
// Unity Native Plugin API copyright © 2015 Unity Technologies ApS
//
// Licensed under the Unity Companion License for Unity - dependent projects--see[Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
//
// Unless expressly provided otherwise, the Software under this license is made available strictly on an AS IS BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions.
#pragma once
#include "IUnityInterface.h"
// Should only be used on the rendering thread unless noted otherwise.
UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D11)
{
ID3D11Device* (UNITY_INTERFACE_API * GetDevice)();
ID3D11Resource* (UNITY_INTERFACE_API * TextureFromRenderBuffer)(UnityRenderBuffer buffer);
ID3D11Resource* (UNITY_INTERFACE_API * TextureFromNativeTexture)(UnityTextureID texture);
ID3D11RenderTargetView* (UNITY_INTERFACE_API * RTVFromRenderBuffer)(UnityRenderBuffer surface);
ID3D11ShaderResourceView* (UNITY_INTERFACE_API * SRVFromNativeTexture)(UnityTextureID texture);
IDXGISwapChain* (UNITY_INTERFACE_API * GetSwapChain)();
UINT32(UNITY_INTERFACE_API * GetSyncInterval)();
UINT(UNITY_INTERFACE_API * GetPresentFlags)();
};
UNITY_REGISTER_INTERFACE_GUID(0xAAB37EF87A87D748ULL, 0xBF76967F07EFB177ULL, IUnityGraphicsD3D11)
Loading…
Cancel
Save