Browse Source
Created separate class for Vulkan implementation based on FFX API, with some additional refactoring
master
Created separate class for Vulkan implementation based on FFX API, with some additional refactoring
master
10 changed files with 207 additions and 22 deletions
-
2FSR3UnityPlugin.cpp
-
2FSR3UnityPlugin.vcxproj
-
6FSR3UnityPlugin.vcxproj.filters
-
2FSR3UnityTypes.h
-
14FSR3Upscaler_DX12.cpp
-
6FSR3Upscaler_DX12.h
-
10FSR3Upscaler_FFXBase.h
-
149FSR3Upscaler_Vulkan.cpp
-
31FSR3Upscaler_Vulkan.h
-
7UpscalerGraphicsDevice.h
@ -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; |
||||
|
} |
||||
@ -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; |
||||
|
}; |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue