forked from Nukem9/dlssg-to-fsr3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor FfxFrameInterpolationContext code into FFInterpolator
- Loading branch information
Showing
2 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
#include "FFInterpolator.h" | ||
|
||
FFInterpolator::FFInterpolator(const FfxInterface& BackendInterface, uint32_t MaxRenderWidth, uint32_t MaxRenderHeight) | ||
: m_BackendInterface(BackendInterface), | ||
m_MaxRenderWidth(MaxRenderWidth), | ||
m_MaxRenderHeight(MaxRenderHeight) | ||
{ | ||
} | ||
|
||
FFInterpolator::~FFInterpolator() | ||
{ | ||
if (m_ResourceCreationHackActive) | ||
{ | ||
const uint32_t resourceId = FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_PREVIOUS_INTERPOLATION_SOURCE; | ||
auto context = reinterpret_cast<FfxFrameInterpolationContext_Private *>(&m_Context); | ||
|
||
context->srvResources[resourceId] = m_OriginalPreviousInterpolationSource; | ||
context->uavResources[resourceId] = m_OriginalPreviousInterpolationSource; | ||
|
||
context->contextDescription.backendInterface.fpDestroyResource( | ||
&context->contextDescription.backendInterface, | ||
m_HackPreviousInterpolationSource, | ||
context->effectContextId); | ||
} | ||
|
||
if (m_ContextCreated) | ||
ffxFrameInterpolationContextDestroy(&m_Context); | ||
} | ||
|
||
FfxErrorCode FFInterpolator::Dispatch(const FFInterpolatorDispatchParameters& Parameters) | ||
{ | ||
FFX_RETURN_ON_FAIL(InternalDeferredSetupContext(Parameters)); // Massive frame hitch on first call | ||
|
||
FfxFrameInterpolationDispatchDescription desc = {}; | ||
|
||
if (Parameters.DebugTearLines) | ||
desc.flags |= FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_TEAR_LINES; | ||
|
||
if (Parameters.DebugView) | ||
desc.flags |= FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_VIEW; | ||
|
||
desc.commandList = Parameters.CommandList; | ||
desc.displaySize = Parameters.OutputSize; | ||
desc.renderSize = Parameters.RenderSize; | ||
|
||
desc.currentBackBuffer = Parameters.InputColorBuffer; | ||
desc.currentBackBuffer_HUDLess = Parameters.InputHUDLessColorBuffer; | ||
desc.output = Parameters.OutputColorBuffer; | ||
desc.dilatedDepth = Parameters.InputDilatedDepth; | ||
desc.dilatedMotionVectors = Parameters.InputDilatedMotionVectors; | ||
desc.reconstructPrevNearDepth = Parameters.InputReconstructedPreviousNearDepth; | ||
|
||
desc.interpolationRect = { 0, 0, static_cast<int>(desc.displaySize.width), static_cast<int>(desc.displaySize.height) }; | ||
|
||
desc.opticalFlowVector = Parameters.InputOpticalFlowVector; | ||
desc.opticalFlowSceneChangeDetection = Parameters.InputOpticalFlowSceneChangeDetection; | ||
desc.opticalFlowBufferSize = Parameters.OpticalFlowBufferSize; | ||
desc.opticalFlowScale = Parameters.OpticalFlowScale; | ||
desc.opticalFlowBlockSize = Parameters.OpticalFlowBlockSize; | ||
|
||
desc.cameraNear = Parameters.CameraNear; | ||
desc.cameraFar = Parameters.CameraFar; | ||
desc.cameraFovAngleVertical = Parameters.CameraFovAngleVertical; | ||
desc.viewSpaceToMetersFactor = Parameters.ViewSpaceToMetersFactor; | ||
|
||
desc.frameTimeDelta = 1000.0f / 60.0f; // Unused | ||
desc.reset = Parameters.Reset; | ||
|
||
desc.backBufferTransferFunction = Parameters.HDR ? FFX_BACKBUFFER_TRANSFER_FUNCTION_PQ : FFX_BACKBUFFER_TRANSFER_FUNCTION_SRGB; | ||
desc.minMaxLuminance[0] = Parameters.MinMaxLuminance.x; | ||
desc.minMaxLuminance[1] = Parameters.MinMaxLuminance.y; | ||
|
||
return ffxFrameInterpolationDispatch(&m_Context, &desc); | ||
} | ||
|
||
FfxErrorCode FFInterpolator::InternalDeferredSetupContext(const FFInterpolatorDispatchParameters& Parameters) | ||
{ | ||
if (!m_ContextCreated) | ||
{ | ||
FfxFrameInterpolationContextDescription desc = {}; | ||
desc.backendInterface = m_BackendInterface; | ||
|
||
if (Parameters.HDR) | ||
desc.flags |= FFX_FRAMEINTERPOLATION_ENABLE_HDR_COLOR_INPUT; | ||
|
||
if (Parameters.DepthInverted) | ||
desc.flags |= FFX_FRAMEINTERPOLATION_ENABLE_DEPTH_INVERTED; | ||
|
||
desc.maxRenderSize = { m_MaxRenderWidth, m_MaxRenderHeight }; | ||
desc.displaySize = desc.maxRenderSize; | ||
|
||
// If provided, pretend the input hudless color format is the back buffer format | ||
desc.backBufferFormat = Parameters.InputColorBuffer.description.format; | ||
|
||
if (Parameters.InputHUDLessColorBuffer.resource) | ||
desc.backBufferFormat = Parameters.InputHUDLessColorBuffer.description.format; | ||
|
||
FFX_RETURN_ON_FAIL(ffxFrameInterpolationContextCreate(&m_Context, &desc)); | ||
|
||
m_InitialBackBufferFormat = desc.backBufferFormat; | ||
m_ContextCreated = true; | ||
} | ||
|
||
// What FFX calls "backBufferFormat" is actually the format of the input color buffer. The input | ||
// color buffer could be the back buffer, or it could be a HUD-less equivalent. Either way, code | ||
// assumes they're identical formats and trips an assert if they're not. The assert is bogus since | ||
// AMD's new implementation is format-agnostic. We can work around this limitation by swapping | ||
// internal resource handles around. | ||
auto& currentInputColor = Parameters.InputHUDLessColorBuffer.resource ? Parameters.InputHUDLessColorBuffer | ||
: Parameters.InputColorBuffer; | ||
|
||
if (currentInputColor.description.format != m_InitialBackBufferFormat) | ||
FFX_RETURN_ON_FAIL(InternalSwapResources(currentInputColor.description.format)); | ||
|
||
return FFX_OK; | ||
} | ||
|
||
FfxErrorCode FFInterpolator::InternalSwapResources(FfxSurfaceFormat NewFormat) | ||
{ | ||
if (m_ResourceCreationHackActive) | ||
return FFX_OK; | ||
|
||
const uint32_t resourceId = FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_PREVIOUS_INTERPOLATION_SOURCE; | ||
auto context = reinterpret_cast<FfxFrameInterpolationContext_Private *>(&m_Context); | ||
|
||
// Create an exact texture copy but with the new format | ||
auto newCopyDescription = context->contextDescription.backendInterface.fpGetResourceDescription( | ||
&context->contextDescription.backendInterface, | ||
context->srvResources[resourceId]); | ||
|
||
newCopyDescription.format = NewFormat; | ||
|
||
const FfxCreateResourceDescription createResourceDescription = { FFX_HEAP_TYPE_DEFAULT, | ||
newCopyDescription, | ||
FFX_RESOURCE_STATE_UNORDERED_ACCESS, | ||
0, | ||
nullptr, | ||
L"FI_PreviousInterpolationSourceHACK", | ||
resourceId }; | ||
|
||
FFX_RETURN_ON_FAIL(context->contextDescription.backendInterface.fpCreateResource( | ||
&context->contextDescription.backendInterface, | ||
&createResourceDescription, | ||
context->effectContextId, | ||
&m_HackPreviousInterpolationSource)); | ||
|
||
m_OriginalPreviousInterpolationSource = context->srvResources[resourceId]; | ||
context->srvResources[resourceId] = m_HackPreviousInterpolationSource; | ||
context->uavResources[resourceId] = m_HackPreviousInterpolationSource; | ||
|
||
m_ResourceCreationHackActive = true; | ||
return FFX_OK; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#pragma once | ||
|
||
#include <FidelityFX/host/ffx_frameinterpolation.h> | ||
#include <FidelityFX/components/frameinterpolation/ffx_frameinterpolation_private.h> | ||
#include <FidelityFX/host/backends/dx12/ffx_dx12.h> | ||
#include "FFXCommon.h" | ||
|
||
struct FFInterpolatorDispatchParameters | ||
{ | ||
FfxCommandList CommandList; | ||
|
||
FfxDimensions2D RenderSize; | ||
FfxDimensions2D OutputSize; | ||
|
||
FfxResource InputColorBuffer; | ||
FfxResource InputHUDLessColorBuffer; | ||
FfxResource InputDilatedDepth; | ||
FfxResource InputDilatedMotionVectors; | ||
FfxResource InputReconstructedPreviousNearDepth; | ||
|
||
FfxResource InputOpticalFlowVector; | ||
FfxResource InputOpticalFlowSceneChangeDetection; | ||
FfxDimensions2D OpticalFlowBufferSize; | ||
FfxFloatCoords2D OpticalFlowScale; | ||
int OpticalFlowBlockSize; | ||
|
||
FfxResource OutputColorBuffer; | ||
|
||
bool HDR; | ||
bool DepthInverted; | ||
bool Reset; | ||
bool DebugTearLines; | ||
bool DebugView; | ||
|
||
float CameraNear; | ||
float CameraFar; | ||
float CameraFovAngleVertical; | ||
float ViewSpaceToMetersFactor; | ||
FfxFloatCoords2D MinMaxLuminance; | ||
}; | ||
|
||
class FFInterpolator | ||
{ | ||
private: | ||
const uint32_t m_MaxRenderWidth; | ||
const uint32_t m_MaxRenderHeight; | ||
|
||
FfxSurfaceFormat m_InitialBackBufferFormat = {}; | ||
|
||
FfxInterface m_BackendInterface = {}; | ||
uint32_t m_EffectContextId = 0; | ||
|
||
FfxFrameInterpolationContext m_Context = {}; | ||
bool m_ContextCreated = false; | ||
|
||
FfxResourceInternal m_HackPreviousInterpolationSource = {}; | ||
FfxResourceInternal m_OriginalPreviousInterpolationSource = {}; | ||
bool m_ResourceCreationHackActive = false; | ||
|
||
public: | ||
FFInterpolator(const FfxInterface& BackendInterface, uint32_t MaxRenderWidth, uint32_t MaxRenderHeight); | ||
FFInterpolator(const FFInterpolator&) = delete; | ||
FFInterpolator& operator=(const FFInterpolator&) = delete; | ||
~FFInterpolator(); | ||
|
||
FfxErrorCode Dispatch(const FFInterpolatorDispatchParameters& Parameters); | ||
|
||
private: | ||
FfxErrorCode InternalDeferredSetupContext(const FFInterpolatorDispatchParameters& Parameters); | ||
FfxErrorCode InternalSwapResources(FfxSurfaceFormat NewFormat); | ||
}; |