|
|
|
@ -28,7 +28,9 @@ static const int32_t BaseEventId = 0; |
|
|
|
static IUnityInterfaces* s_UnityInterfaces = nullptr; |
|
|
|
static IUnityLog* s_Log = nullptr; |
|
|
|
static IUnityGraphics* s_Graphics = nullptr; |
|
|
|
static IUnityGraphicsD3D11* s_GraphicsD3D11 = nullptr; |
|
|
|
static IUnityGraphicsD3D12v7* s_GraphicsD3D12 = nullptr; |
|
|
|
static IUnityGraphicsVulkanV2* s_GraphicsVulkan = nullptr; |
|
|
|
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull; |
|
|
|
|
|
|
|
static FfxDevice s_Device = nullptr; |
|
|
|
@ -80,6 +82,16 @@ static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType ev |
|
|
|
s_RendererType = s_Graphics->GetRenderer(); |
|
|
|
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: |
|
|
|
{ |
|
|
|
s_GraphicsD3D12 = s_UnityInterfaces->Get<IUnityGraphicsD3D12v7>(); |
|
|
|
@ -90,13 +102,25 @@ static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType ev |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
case kUnityGfxRendererVulkan: |
|
|
|
{ |
|
|
|
s_GraphicsVulkan = s_UnityInterfaces->Get<IUnityGraphicsVulkanV2>(); |
|
|
|
if (s_GraphicsVulkan == nullptr) |
|
|
|
{ |
|
|
|
UNITY_LOG_ERROR(s_Log, "Could not obtain Vulkan Graphics interface!"); |
|
|
|
return; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
case kUnityGfxDeviceEventShutdown: |
|
|
|
{ |
|
|
|
s_GraphicsVulkan = nullptr; |
|
|
|
s_GraphicsD3D12 = nullptr; |
|
|
|
s_GraphicsD3D11 = nullptr; |
|
|
|
s_RendererType = kUnityGfxRendererNull; |
|
|
|
break; |
|
|
|
} |
|
|
|
@ -139,9 +163,28 @@ static void FreeFeatureSlot(uint32_t featureSlot) |
|
|
|
memset(&s_Features[featureSlot], 0, sizeof(FSR2Feature)); |
|
|
|
} |
|
|
|
|
|
|
|
static PFN_vkVoidFunction GetVulkanDeviceProcAddr(VkDevice device, const char* pName) |
|
|
|
{ |
|
|
|
UnityVulkanInstance instance = s_GraphicsVulkan->Instance(); |
|
|
|
return instance.getInstanceProcAddr(instance.instance, pName); |
|
|
|
} |
|
|
|
|
|
|
|
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() |
|
|
|
{ |
|
|
|
if (s_GraphicsD3D12 != nullptr) |
|
|
|
if (s_GraphicsD3D11 != nullptr) |
|
|
|
{ |
|
|
|
//ID3D11Device* device = s_GraphicsD3D11->GetDevice();
|
|
|
|
//if (device == nullptr)
|
|
|
|
// return false;
|
|
|
|
|
|
|
|
//s_Device = ffxGetDeviceDX11(device);
|
|
|
|
|
|
|
|
//size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeDX11();
|
|
|
|
//void* scratchBuffer = malloc(scratchBufferSize);
|
|
|
|
//ffxFsr2GetInterfaceDX11(&s_Fsr2Interface, device, scratchBuffer, scratchBufferSize);
|
|
|
|
//return true;
|
|
|
|
} |
|
|
|
else if (s_GraphicsD3D12 != nullptr) |
|
|
|
{ |
|
|
|
ID3D12Device* device = s_GraphicsD3D12->GetDevice(); |
|
|
|
if (device == nullptr) |
|
|
|
@ -154,6 +197,19 @@ extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() |
|
|
|
ffxFsr2GetInterfaceDX12(&s_Fsr2Interface, device, scratchBuffer, scratchBufferSize); |
|
|
|
return true; |
|
|
|
} |
|
|
|
else if (s_GraphicsVulkan != nullptr) |
|
|
|
{ |
|
|
|
UnityVulkanInstance instance = s_GraphicsVulkan->Instance(); |
|
|
|
if (instance.device == nullptr) |
|
|
|
return false; |
|
|
|
|
|
|
|
s_Device = ffxGetDeviceVK(instance.device); |
|
|
|
|
|
|
|
size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeVK(instance.physicalDevice); |
|
|
|
void* scratchBuffer = malloc(scratchBufferSize); |
|
|
|
ffxFsr2GetInterfaceVK(&s_Fsr2Interface, scratchBuffer, scratchBufferSize, instance.physicalDevice, &GetVulkanDeviceProcAddr); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
@ -232,6 +288,37 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetBaseEvent |
|
|
|
return BaseEventId; |
|
|
|
} |
|
|
|
|
|
|
|
static FfxResource GetVulkanTextureResource(UnityVulkanInstance& instance, FSR2Feature& feature, FSR2TextureDesc& texture, FfxResourceStates state = FFX_RESOURCE_STATE_COMPUTE_READ) |
|
|
|
{ |
|
|
|
VkImageView imageView = nullptr; |
|
|
|
|
|
|
|
if (texture.image != 0) |
|
|
|
{ |
|
|
|
VkImageViewCreateInfo createInfo{}; |
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; |
|
|
|
createInfo.image = (VkImage)texture.image; |
|
|
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; |
|
|
|
createInfo.format = (VkFormat)texture.format; |
|
|
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
|
|
|
createInfo.subresourceRange.levelCount = 1; |
|
|
|
createInfo.subresourceRange.layerCount = 1; |
|
|
|
|
|
|
|
vkCreateImageView(instance.device, &createInfo, nullptr, &imageView); |
|
|
|
} |
|
|
|
|
|
|
|
texture.view = (intptr_t)imageView; |
|
|
|
return ffxGetTextureResourceVK(&feature.upscalingContext, (VkImage)texture.image, imageView, texture.width, texture.height, (VkFormat)texture.format, nullptr, state); |
|
|
|
} |
|
|
|
|
|
|
|
static void DestroyVulkanImageView(UnityVulkanInstance& instance, FSR2TextureDesc& texture) |
|
|
|
{ |
|
|
|
if (texture.view == 0) |
|
|
|
return; |
|
|
|
|
|
|
|
vkDestroyImageView(instance.device, (VkImageView)texture.view, nullptr); |
|
|
|
texture.view = 0; |
|
|
|
} |
|
|
|
|
|
|
|
// Plugin function to handle a specific rendering event
|
|
|
|
static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) |
|
|
|
{ |
|
|
|
@ -271,13 +358,28 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) |
|
|
|
s_GraphicsD3D12->CommandRecordingState(&state); |
|
|
|
dispatchDescription.commandList = ffxGetCommandListDX12(state.commandList); |
|
|
|
|
|
|
|
dispatchDescription.color = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.colorInput); |
|
|
|
dispatchDescription.depth = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.depth); |
|
|
|
dispatchDescription.motionVectors = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.motionVectors); |
|
|
|
dispatchDescription.exposure = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.exposureTexture); |
|
|
|
dispatchDescription.reactive = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.reactiveMask); |
|
|
|
dispatchDescription.transparencyAndComposition = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.transparencyMask); |
|
|
|
dispatchDescription.output = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.colorOutput, nullptr, FFX_RESOURCE_STATE_UNORDERED_ACCESS); |
|
|
|
dispatchDescription.color = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.colorInput.image); |
|
|
|
dispatchDescription.depth = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.depth.image); |
|
|
|
dispatchDescription.motionVectors = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.motionVectors.image); |
|
|
|
dispatchDescription.exposure = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.exposureTexture.image); |
|
|
|
dispatchDescription.reactive = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.reactiveMask.image); |
|
|
|
dispatchDescription.transparencyAndComposition = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.transparencyMask.image); |
|
|
|
dispatchDescription.output = ffxGetResourceDX12(&feature.upscalingContext, (ID3D12Resource*)feature.textureTable.colorOutput.image, nullptr, FFX_RESOURCE_STATE_UNORDERED_ACCESS); |
|
|
|
} |
|
|
|
else if (s_GraphicsVulkan != nullptr) |
|
|
|
{ |
|
|
|
UnityVulkanRecordingState state; |
|
|
|
s_GraphicsVulkan->CommandRecordingState(&state, kUnityVulkanGraphicsQueueAccess_DontCare); |
|
|
|
dispatchDescription.commandList = ffxGetCommandListVK(state.commandBuffer); |
|
|
|
|
|
|
|
UnityVulkanInstance instance = s_GraphicsVulkan->Instance(); |
|
|
|
dispatchDescription.color = GetVulkanTextureResource(instance, feature, feature.textureTable.colorInput); |
|
|
|
dispatchDescription.depth = GetVulkanTextureResource(instance, feature, feature.textureTable.depth); |
|
|
|
dispatchDescription.motionVectors = GetVulkanTextureResource(instance, feature, feature.textureTable.motionVectors); |
|
|
|
dispatchDescription.exposure = GetVulkanTextureResource(instance, feature, feature.textureTable.exposureTexture); |
|
|
|
dispatchDescription.reactive = GetVulkanTextureResource(instance, feature, feature.textureTable.reactiveMask); |
|
|
|
dispatchDescription.transparencyAndComposition = GetVulkanTextureResource(instance, feature, feature.textureTable.transparencyMask); |
|
|
|
dispatchDescription.output = GetVulkanTextureResource(instance, feature, feature.textureTable.colorOutput, FFX_RESOURCE_STATE_UNORDERED_ACCESS); |
|
|
|
} |
|
|
|
|
|
|
|
dispatchDescription.jitterOffset.x = params->jitterOffsetX; |
|
|
|
@ -310,6 +412,23 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) |
|
|
|
case BaseEventId + FSR2PluginEvent::ePostExecute: |
|
|
|
{ |
|
|
|
auto* params = (FSR2CommandExecutionData*)data; |
|
|
|
if (params->featureSlot < 0 || params->featureSlot >= s_Features.size()) |
|
|
|
return; |
|
|
|
|
|
|
|
auto& feature = s_Features[params->featureSlot]; |
|
|
|
|
|
|
|
if (s_GraphicsVulkan != nullptr) |
|
|
|
{ |
|
|
|
UnityVulkanInstance instance = s_GraphicsVulkan->Instance(); |
|
|
|
DestroyVulkanImageView(instance, feature.textureTable.colorInput); |
|
|
|
DestroyVulkanImageView(instance, feature.textureTable.depth); |
|
|
|
DestroyVulkanImageView(instance, feature.textureTable.motionVectors); |
|
|
|
DestroyVulkanImageView(instance, feature.textureTable.exposureTexture); |
|
|
|
DestroyVulkanImageView(instance, feature.textureTable.reactiveMask); |
|
|
|
DestroyVulkanImageView(instance, feature.textureTable.transparencyMask); |
|
|
|
DestroyVulkanImageView(instance, feature.textureTable.colorOutput); |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
case BaseEventId + FSR2PluginEvent::eInit: |
|
|
|
@ -361,15 +480,36 @@ static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data) |
|
|
|
} |
|
|
|
case kUnityRenderingExtEventUpdateTextureEndV2: |
|
|
|
{ |
|
|
|
intptr_t texturePtr = 0; |
|
|
|
// 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
|
|
|
|
FSR2TextureDesc* textureDesc = ((FSR2TextureDesc*)&feature.textureTable) + textureSlot; |
|
|
|
|
|
|
|
if (s_GraphicsD3D12 != nullptr) |
|
|
|
{ |
|
|
|
texturePtr = (intptr_t)s_GraphicsD3D12->TextureFromNativeTexture((UnityTextureID)params->textureID); |
|
|
|
textureDesc->image = (intptr_t)s_GraphicsD3D12->TextureFromNativeTexture((UnityTextureID)params->textureID); |
|
|
|
} |
|
|
|
else if (s_GraphicsVulkan != nullptr) |
|
|
|
{ |
|
|
|
VkAccessFlags accessFlags = (textureSlot == FSR2Textures::tColorOutput) ? VK_ACCESS_SHADER_WRITE_BIT : VK_ACCESS_SHADER_READ_BIT; |
|
|
|
|
|
|
|
UnityVulkanImage image; |
|
|
|
if (s_GraphicsVulkan->AccessTextureByID((UnityTextureID)params->textureID, UnityVulkanWholeImage, |
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, accessFlags, |
|
|
|
kUnityVulkanResourceAccess_PipelineBarrier, &image)) |
|
|
|
{ |
|
|
|
textureDesc->image = (intptr_t)image.image; |
|
|
|
textureDesc->view = 0; |
|
|
|
textureDesc->width = params->width; |
|
|
|
textureDesc->height = params->height; |
|
|
|
textureDesc->format = (uint32_t)image.format; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
textureDesc->image = 0; |
|
|
|
textureDesc->view = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 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
|
|
|
|
*(((intptr_t*)&feature.textureTable) + textureSlot) = texturePtr; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|