Browse Source

Created separate class for Vulkan implementation based on FFX API, with some additional refactoring

master
Nico de Poel 10 months ago
parent
commit
88f5e78fc4
  1. 2
      FSR3UnityPlugin.cpp
  2. 2
      FSR3UnityPlugin.vcxproj
  3. 6
      FSR3UnityPlugin.vcxproj.filters
  4. 2
      FSR3UnityTypes.h
  5. 14
      FSR3Upscaler_DX12.cpp
  6. 6
      FSR3Upscaler_DX12.h
  7. 10
      FSR3Upscaler_FFXBase.h
  8. 149
      FSR3Upscaler_Vulkan.cpp
  9. 31
      FSR3Upscaler_Vulkan.h
  10. 7
      UpscalerGraphicsDevice.h

2
FSR3UnityPlugin.cpp

@ -703,7 +703,7 @@ static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data)
} }
else if (s_GraphicsVulkan != nullptr) else if (s_GraphicsVulkan != nullptr)
{ {
VkAccessFlags accessFlags = (textureSlot == FSR3Textures::tColorOutput) ? VK_ACCESS_SHADER_WRITE_BIT : VK_ACCESS_SHADER_READ_BIT;
VkAccessFlags accessFlags = (textureSlot == FSR3Texture::tColorOutput) ? VK_ACCESS_SHADER_WRITE_BIT : VK_ACCESS_SHADER_READ_BIT;
UnityVulkanImage image; UnityVulkanImage image;
if (s_GraphicsVulkan->AccessTextureByID((UnityTextureID)params->textureID, UnityVulkanWholeImage, if (s_GraphicsVulkan->AccessTextureByID((UnityTextureID)params->textureID, UnityVulkanWholeImage,

2
FSR3UnityPlugin.vcxproj

@ -153,11 +153,13 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="FSR3UnityPlugin.cpp" /> <ClCompile Include="FSR3UnityPlugin.cpp" />
<ClCompile Include="FSR3Upscaler_DX12.cpp" /> <ClCompile Include="FSR3Upscaler_DX12.cpp" />
<ClCompile Include="FSR3Upscaler_Vulkan.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="FSR3UnityTypes.h" /> <ClInclude Include="FSR3UnityTypes.h" />
<ClInclude Include="FSR3Upscaler_DX12.h" /> <ClInclude Include="FSR3Upscaler_DX12.h" />
<ClInclude Include="FSR3Upscaler_FFXBase.h" /> <ClInclude Include="FSR3Upscaler_FFXBase.h" />
<ClInclude Include="FSR3Upscaler_Vulkan.h" />
<ClInclude Include="UpscalerGraphicsDevice.h" /> <ClInclude Include="UpscalerGraphicsDevice.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

6
FSR3UnityPlugin.vcxproj.filters

@ -21,6 +21,9 @@
<ClCompile Include="FSR3Upscaler_DX12.cpp"> <ClCompile Include="FSR3Upscaler_DX12.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="FSR3Upscaler_Vulkan.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="FSR3UnityTypes.h"> <ClInclude Include="FSR3UnityTypes.h">
@ -35,5 +38,8 @@
<ClInclude Include="FSR3Upscaler_FFXBase.h"> <ClInclude Include="FSR3Upscaler_FFXBase.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="FSR3Upscaler_Vulkan.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

2
FSR3UnityTypes.h

@ -16,7 +16,7 @@ enum FSR3Quality: int32_t
qUltraPerformance qUltraPerformance
}; };
enum FSR3Textures: int32_t
enum FSR3Texture: int32_t
{ {
tColorInput, tColorInput,
tColorOutput, tColorOutput,

14
FSR3Upscaler_DX12.cpp

@ -25,9 +25,9 @@ bool FSR3Upscaler_DX12::InitFeature(FSR3Feature_FFX& feature, const FSR3CommandI
return FFX_API_RETURN_OK == m_ffxFunctions.CreateContext(&feature.upscalingContext, ffx::LinkHeaders(createUpscaling.header, m_DX12BackendDesc.header), nullptr); return FFX_API_RETURN_OK == m_ffxFunctions.CreateContext(&feature.upscalingContext, ffx::LinkHeaders(createUpscaling.header, m_DX12BackendDesc.header), nullptr);
} }
void FSR3Upscaler_DX12::SetTexture(FSR3TextureDesc* textureDesc, UnityTextureID textureID)
void FSR3Upscaler_DX12::SetTexture(FSR3Texture textureType, UnityTextureID textureID, const UnityRenderingExtTextureUpdateParamsV2* params, FSR3TextureDesc* outTextureDesc)
{ {
textureDesc->image = (intptr_t)m_GraphicsDevice->TextureFromNativeTexture(textureID);
outTextureDesc->image = (intptr_t)m_GraphicsDevice->TextureFromNativeTexture(textureID);
} }
void FSR3Upscaler_DX12::Execute(FSR3Feature_FFX& feature, const FSR3CommandExecutionData* execData) void FSR3Upscaler_DX12::Execute(FSR3Feature_FFX& feature, const FSR3CommandExecutionData* execData)
@ -81,11 +81,6 @@ void FSR3Upscaler_DX12::Execute(FSR3Feature_FFX& feature, const FSR3CommandExecu
m_ffxFunctions.Dispatch(&feature.upscalingContext, &dispatchUpscale.header); m_ffxFunctions.Dispatch(&feature.upscalingContext, &dispatchUpscale.header);
} }
bool FSR3Upscaler_DX12::IsValidFeature(FSR3Feature_FFX& feature)
{
return feature.upscalingContext != nullptr;
}
void FSR3Upscaler_DX12::AwaitEndOfFrame(uint64_t frameValue) void FSR3Upscaler_DX12::AwaitEndOfFrame(uint64_t frameValue)
{ {
// Thanks to https://alextardif.com/D3D11To12P1.html for explaining how fences work and how to make the CPU wait for a command queue to complete. // Thanks to https://alextardif.com/D3D11To12P1.html for explaining how fences work and how to make the CPU wait for a command queue to complete.
@ -97,11 +92,6 @@ void FSR3Upscaler_DX12::AwaitEndOfFrame(uint64_t frameValue)
} }
} }
void FSR3Upscaler_DX12::DestroyContext(FSR3Feature_FFX& feature)
{
m_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr);
}
void FSR3Upscaler_DX12::DoShutdown() void FSR3Upscaler_DX12::DoShutdown()
{ {
FSR3Upscaler_FFXBase::DoShutdown(); FSR3Upscaler_FFXBase::DoShutdown();

6
FSR3Upscaler_DX12.h

@ -18,15 +18,11 @@ public:
bool Init() override; bool Init() override;
protected: protected:
bool IsValidFeature(FSR3Feature_FFX& feature) override;
bool InitFeature(FSR3Feature_FFX& feature, const FSR3CommandInitializationData* initData) override; bool InitFeature(FSR3Feature_FFX& feature, const FSR3CommandInitializationData* initData) override;
void SetTexture(FSR3TextureDesc* textureDesc, UnityTextureID textureID) override;
void SetTexture(FSR3Texture textureType, UnityTextureID textureID, const UnityRenderingExtTextureUpdateParamsV2* params, FSR3TextureDesc* outTextureDesc) override;
void Execute(FSR3Feature_FFX& feature, const FSR3CommandExecutionData* execData) override; void Execute(FSR3Feature_FFX& feature, const FSR3CommandExecutionData* execData) override;
void AwaitEndOfFrame(uint64_t frameValue) override; void AwaitEndOfFrame(uint64_t frameValue) override;
void DestroyContext(FSR3Feature_FFX& feature) override;
void DoShutdown() override; void DoShutdown() override;
private: private:

10
FSR3Upscaler_FFXBase.h

@ -77,6 +77,16 @@ protected:
return true; return true;
} }
bool IsValidFeature(FSR3Feature_FFX& feature) override
{
return feature.upscalingContext != nullptr;
}
void DestroyContext(FSR3Feature_FFX& feature) override
{
m_ffxFunctions.DestroyContext(&feature.upscalingContext, nullptr);
}
void DoShutdown() override void DoShutdown() override
{ {
if (m_ffxModule != nullptr) if (m_ffxModule != nullptr)

149
FSR3Upscaler_Vulkan.cpp

@ -0,0 +1,149 @@
#include "FSR3Upscaler_Vulkan.h"
static VkInstance s_VulkanInstance;
static PFN_vkGetInstanceProcAddr s_GetInstanceProcAddr;
static PFN_vkVoidFunction GetVulkanDeviceProcAddr(VkDevice device, const char* pName)
{
if (s_GetInstanceProcAddr == nullptr)
return nullptr;
return s_GetInstanceProcAddr(s_VulkanInstance, pName);
}
bool FSR3Upscaler_Vulkan::Init()
{
UnityVulkanInstance instance = m_GraphicsDevice->Instance();
if (instance.device == nullptr)
return false;
s_VulkanInstance = instance.instance;
s_GetInstanceProcAddr = instance.getInstanceProcAddr;
m_VulkanBackendDesc.vkDevice = instance.device;
m_VulkanBackendDesc.vkPhysicalDevice = instance.physicalDevice;
m_VulkanBackendDesc.vkDeviceProcAddr = &GetVulkanDeviceProcAddr;
return LoadFidelityFXLibrary(TEXT("amd_fidelityfx_vk.dll"), nullptr);
}
bool FSR3Upscaler_Vulkan::InitFeature(FSR3Feature_FFX& feature, const FSR3CommandInitializationData* initData)
{
ffx::CreateContextDescUpscale createUpscaling;
createUpscaling.maxUpscaleSize = { initData->displaySizeWidth, initData->displaySizeHeight };
createUpscaling.maxRenderSize = { initData->maxRenderSizeWidth, initData->maxRenderSizeHeight };
createUpscaling.flags = initData->flags;
return FFX_API_RETURN_OK == m_ffxFunctions.CreateContext(&feature.upscalingContext, ffx::LinkHeaders(createUpscaling.header, m_VulkanBackendDesc.header), nullptr);
}
void FSR3Upscaler_Vulkan::SetTexture(FSR3Texture textureType, UnityTextureID textureID, const UnityRenderingExtTextureUpdateParamsV2* params, FSR3TextureDesc* outTextureDesc)
{
VkAccessFlags accessFlags = (textureType == FSR3Texture::tColorOutput) ? VK_ACCESS_SHADER_WRITE_BIT : VK_ACCESS_SHADER_READ_BIT;
UnityVulkanImage image;
if (m_GraphicsDevice->AccessTextureByID(textureID, UnityVulkanWholeImage,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, accessFlags,
kUnityVulkanResourceAccess_PipelineBarrier, &image))
{
outTextureDesc->image = (intptr_t)image.image;
outTextureDesc->width = params->width;
outTextureDesc->height = params->height;
outTextureDesc->format = (uint32_t)image.format;
}
else
{
outTextureDesc->image = 0;
}
}
static FfxApiResource GetVulkanTextureResource(UnityVulkanInstance& instance, FSR3TextureDesc& texture, FfxApiResourceState state = FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ)
{
FfxApiResourceDescription desc{};
if (texture.image != 0)
{
desc.type = FFX_API_RESOURCE_TYPE_TEXTURE2D;
desc.format = ffxApiGetSurfaceFormatVK((VkFormat)texture.format);
desc.width = texture.width;
desc.height = texture.height;
desc.depth = 1;
desc.mipCount = 1;
desc.flags = FFX_API_RESOURCE_FLAGS_NONE;
desc.usage = state == FFX_API_RESOURCE_STATE_UNORDERED_ACCESS ? FFX_API_RESOURCE_USAGE_UAV : FFX_API_RESOURCE_USAGE_READ_ONLY;
}
return ffxApiGetResourceVK((void*)texture.image, desc, state);
}
void FSR3Upscaler_Vulkan::Execute(FSR3Feature_FFX& feature, const FSR3CommandExecutionData* execData)
{
ffx::DispatchDescUpscale dispatchUpscale{};
UnityVulkanRecordingState state;
m_GraphicsDevice->CommandRecordingState(&state, kUnityVulkanGraphicsQueueAccess_DontCare);
dispatchUpscale.commandList = state.commandBuffer;
// Keep track of which frame this dispatch is happening on, so we can verify when it's finished
feature.dispatchFrameValue = state.currentFrameNumber;
UnityVulkanInstance instance = m_GraphicsDevice->Instance();
dispatchUpscale.color = GetVulkanTextureResource(instance, feature.textureTable.colorInput);
dispatchUpscale.depth = GetVulkanTextureResource(instance, feature.textureTable.depth);
dispatchUpscale.motionVectors = GetVulkanTextureResource(instance, feature.textureTable.motionVectors);
dispatchUpscale.exposure = GetVulkanTextureResource(instance, feature.textureTable.exposureTexture);
dispatchUpscale.reactive = GetVulkanTextureResource(instance, feature.textureTable.reactiveMask);
dispatchUpscale.transparencyAndComposition = GetVulkanTextureResource(instance, feature.textureTable.transparencyMask);
dispatchUpscale.output = GetVulkanTextureResource(instance, feature.textureTable.colorOutput, FFX_API_RESOURCE_STATE_UNORDERED_ACCESS);
if (dispatchUpscale.reactive.resource == nullptr)
dispatchUpscale.reactive = GetVulkanTextureResource(instance, feature.textureTable.biasColorMask);
dispatchUpscale.jitterOffset.x = execData->jitterOffsetX;
dispatchUpscale.jitterOffset.y = execData->jitterOffsetY;
dispatchUpscale.motionVectorScale.x = execData->MVScaleX;
dispatchUpscale.motionVectorScale.y = execData->MVScaleY;
dispatchUpscale.reset = execData->reset;
dispatchUpscale.enableSharpening = execData->enableSharpening;
dispatchUpscale.sharpness = execData->sharpness;
dispatchUpscale.frameTimeDelta = execData->frameTimeDelta;
dispatchUpscale.preExposure = execData->preExposure;
dispatchUpscale.renderSize.width = execData->renderSizeWidth;
dispatchUpscale.renderSize.height = execData->renderSizeHeight;
dispatchUpscale.upscaleSize.width = feature.upscaleSizeWidth;
dispatchUpscale.upscaleSize.height = feature.upscaleSizeHeight;
dispatchUpscale.cameraFovAngleVertical = execData->cameraFovAngleVertical;
if (feature.flags & FFX_UPSCALE_ENABLE_DEPTH_INVERTED)
{
dispatchUpscale.cameraFar = execData->cameraNear;
dispatchUpscale.cameraNear = execData->cameraFar;
}
else
{
dispatchUpscale.cameraFar = execData->cameraFar;
dispatchUpscale.cameraNear = execData->cameraNear;
}
m_ffxFunctions.Dispatch(&feature.upscalingContext, &dispatchUpscale.header);
}
void FSR3Upscaler_Vulkan::AwaitEndOfFrame(uint64_t frameValue)
{
UnityVulkanRecordingState state;
m_GraphicsDevice->CommandRecordingState(&state, kUnityVulkanGraphicsQueueAccess_DontCare);
if (frameValue > state.safeFrameNumber)
{
UnityVulkanInstance instance = m_GraphicsDevice->Instance();
vkQueueWaitIdle(instance.graphicsQueue);
}
}
void FSR3Upscaler_Vulkan::DoShutdown()
{
FSR3Upscaler_FFXBase::DoShutdown();
m_VulkanBackendDesc.vkDevice = nullptr;
m_VulkanBackendDesc.vkPhysicalDevice = nullptr;
m_VulkanBackendDesc.vkDeviceProcAddr = nullptr;
}

31
FSR3Upscaler_Vulkan.h

@ -0,0 +1,31 @@
#pragma once
#include "FSR3Upscaler_FFXBase.h"
#include "ffx_api/ffx_upscale.hpp"
#include "ffx_api/vk/ffx_api_vk.hpp"
#include "UnityPluginAPI/IUnityGraphicsVulkan.h"
class FSR3Upscaler_Vulkan : FSR3Upscaler_FFXBase
{
public:
FSR3Upscaler_Vulkan(IUnityInterfaces* unityInterfaces, IUnityGraphicsVulkan* graphicsDevice) :
FSR3Upscaler_FFXBase(unityInterfaces),
m_GraphicsDevice(graphicsDevice), m_VulkanBackendDesc()
{
}
bool Init() override;
protected:
bool InitFeature(FSR3Feature_FFX& feature, const FSR3CommandInitializationData* initData) override;
void SetTexture(FSR3Texture textureType, UnityTextureID textureID, const UnityRenderingExtTextureUpdateParamsV2* params, FSR3TextureDesc* outTextureDesc) override;
void Execute(FSR3Feature_FFX& feature, const FSR3CommandExecutionData* execData) override;
void AwaitEndOfFrame(uint64_t frameValue) override;
void DoShutdown() override;
private:
IUnityGraphicsVulkan* m_GraphicsDevice;
ffx::CreateBackendVKDesc m_VulkanBackendDesc;
};

7
UpscalerGraphicsDevice.h

@ -6,6 +6,7 @@
#include <mutex> #include <mutex>
#include "UnityPluginAPI/IUnityInterface.h" #include "UnityPluginAPI/IUnityInterface.h"
#include "UnityPluginAPI/IUnityRenderingExtensions.h"
#include "FSR3UnityTypes.h" #include "FSR3UnityTypes.h"
@ -87,7 +88,7 @@ public:
memset(&m_Features[featureSlot].textureTable, 0, sizeof(FSR3TextureTable)); memset(&m_Features[featureSlot].textureTable, 0, sizeof(FSR3TextureTable));
} }
virtual void SetTextureSlot(uint32_t featureSlot, uint32_t textureSlot, UnityTextureID textureID)
virtual void SetTextureSlot(uint32_t featureSlot, uint32_t textureSlot, UnityTextureID textureID, const UnityRenderingExtTextureUpdateParamsV2* params)
{ {
if (featureSlot < 0 || featureSlot >= m_Features.size()) if (featureSlot < 0 || featureSlot >= m_Features.size())
return; return;
@ -95,7 +96,7 @@ public:
// We organized the texture table struct to be ordered the same as the texture slot enum // We organized the texture table struct to be ordered the same as the texture slot enum
// 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*)&m_Features[featureSlot].textureTable) + textureSlot; FSR3TextureDesc* textureDesc = ((FSR3TextureDesc*)&m_Features[featureSlot].textureTable) + textureSlot;
SetTexture(textureDesc, textureID);
SetTexture((FSR3Texture)textureSlot, textureID, params, textureDesc);
} }
virtual void Execute(const FSR3CommandExecutionData* execData) virtual void Execute(const FSR3CommandExecutionData* execData)
@ -132,7 +133,7 @@ protected:
virtual bool IsValidFeature(TFeature& feature) = 0; virtual bool IsValidFeature(TFeature& feature) = 0;
virtual bool InitFeature(TFeature& feature, const FSR3CommandInitializationData* initData) = 0; virtual bool InitFeature(TFeature& feature, const FSR3CommandInitializationData* initData) = 0;
virtual void SetTexture(FSR3TextureDesc* textureDesc, UnityTextureID textureID) = 0;
virtual void SetTexture(FSR3Texture textureType, UnityTextureID textureID, const UnityRenderingExtTextureUpdateParamsV2* params, FSR3TextureDesc* outTextureDesc) = 0;
virtual void Execute(TFeature& feature, const FSR3CommandExecutionData* execData) = 0; virtual void Execute(TFeature& feature, const FSR3CommandExecutionData* execData) = 0;
virtual void PostExecute(TFeature& feature, const FSR3CommandExecutionData* execData) { } virtual void PostExecute(TFeature& feature, const FSR3CommandExecutionData* execData) { }

Loading…
Cancel
Save