|
|
|
|
@ -5,12 +5,24 @@
|
|
|
|
|
#include <uf/ext/ffx/fsr.h>
|
|
|
|
|
#include <uf/engine/graph/graph.h>
|
|
|
|
|
|
|
|
|
|
#define FFX_FSR_BLOCK_SIZE 8
|
|
|
|
|
#define FFX_FSR_MAX_WIDTH 3840
|
|
|
|
|
#define FFX_FSR_MAX_HEIGHT 2160
|
|
|
|
|
|
|
|
|
|
#if UF_USE_FFX_SDK
|
|
|
|
|
#include <FidelityFX/host/backends/vk/ffx_vk.h>
|
|
|
|
|
#define UF_USE_FFX_SDK 3
|
|
|
|
|
|
|
|
|
|
#define FFX_SDK_2 2
|
|
|
|
|
#define FFX_SDK_3 3
|
|
|
|
|
#define FFX_SDK_3_1 31
|
|
|
|
|
|
|
|
|
|
#if UF_USE_FFX_SDK == 2
|
|
|
|
|
#define UF_USE_FFX_SDK FFX_SDK_3_1
|
|
|
|
|
#define UF_USE_FFX_SDR_FRAME_INTERP 1
|
|
|
|
|
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_2
|
|
|
|
|
#warning "Using FFX-FSR2"
|
|
|
|
|
#include <FidelityFX/host/ffx_fsr2.h>
|
|
|
|
|
|
|
|
|
|
#define FfxContext FfxFsr2Context
|
|
|
|
|
#define FfxContextDescription FfxFsr2ContextDescription
|
|
|
|
|
#define FfxGenerateReactiveDescription FfxFsr2GenerateReactiveDescription
|
|
|
|
|
@ -45,8 +57,53 @@
|
|
|
|
|
#define FSR_InputExposure L"FSR2_InputExposure"
|
|
|
|
|
#define FSR_InputReactiveMap L"FSR2_InputReactiveMap"
|
|
|
|
|
#define FSR_TransparencyAndCompositionMap L"FSR2_TransparencyAndCompositionMap"
|
|
|
|
|
#elif UF_USE_FFX_SDK == 3
|
|
|
|
|
#elif UF_USE_FFX_SDK == FFX_SDK_3
|
|
|
|
|
#warning "Using FFX-FSR3"
|
|
|
|
|
#include <FidelityFX/host/ffx_fsr3.h>
|
|
|
|
|
#define FfxContext FfxFsr3Context
|
|
|
|
|
#define FfxContextDescription FfxFsr3ContextDescription
|
|
|
|
|
#define FfxGenerateReactiveDescription FfxFsr3GenerateReactiveDescription
|
|
|
|
|
#define FfxDispatchDescription FfxFsr3DispatchUpscaleDescription
|
|
|
|
|
|
|
|
|
|
#define ffxContextGenerateReactiveMask ffxFsr3ContextGenerateReactiveMask
|
|
|
|
|
#define ffxContextDispatch ffxFsr3ContextDispatchUpscale
|
|
|
|
|
#define ffxContextCreate ffxFsr3ContextCreate
|
|
|
|
|
#define ffxContextDestroy ffxFsr3ContextDestroy
|
|
|
|
|
#define ffxGetJitterPhaseCount ffxFsr3GetJitterPhaseCount
|
|
|
|
|
#define ffxGetJitterOffset ffxFsr3GetJitterOffset
|
|
|
|
|
|
|
|
|
|
#define FFX_FSR_AUTOREACTIVEFLAGS_APPLY_TONEMAP FFX_FSR3_AUTOREACTIVEFLAGS_APPLY_TONEMAP
|
|
|
|
|
#define FFX_FSR_AUTOREACTIVEFLAGS_APPLY_INVERSETONEMAP FFX_FSR3_AUTOREACTIVEFLAGS_APPLY_INVERSETONEMAP
|
|
|
|
|
#define FFX_FSR_AUTOREACTIVEFLAGS_APPLY_THRESHOLD FFX_FSR3_AUTOREACTIVEFLAGS_APPLY_THRESHOLD
|
|
|
|
|
#define FFX_FSR_AUTOREACTIVEFLAGS_USE_COMPONENTS_MAX FFX_FSR3_AUTOREACTIVEFLAGS_USE_COMPONENTS_MAX
|
|
|
|
|
#define FFX_FSR_ENABLE_AUTO_EXPOSURE FFX_FSR3_ENABLE_AUTO_EXPOSURE
|
|
|
|
|
#define FFX_FSR_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION FFX_FSR3_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION
|
|
|
|
|
#define FFX_FSR_ENABLE_HIGH_DYNAMIC_RANGE FFX_FSR3_ENABLE_HIGH_DYNAMIC_RANGE
|
|
|
|
|
#define FFX_FSR_ENABLE_DEPTH_INVERTED FFX_FSR3_ENABLE_DEPTH_INVERTED
|
|
|
|
|
#define FFX_FSR_ENABLE_DEPTH_INFINITE FFX_FSR3_ENABLE_DEPTH_INFINITE
|
|
|
|
|
|
|
|
|
|
#define FSR_InputColor L"FSR3_InputColor"
|
|
|
|
|
#define FSR_InputDepth L"FSR3_InputDepth"
|
|
|
|
|
#define FSR_InputMotionVectors L"FSR3_InputMotionVectors"
|
|
|
|
|
#define FSR_OutputUpscaledColor L"FSR3_OutputUpscaledColor"
|
|
|
|
|
#define FSR_OutputUpscaledColor L"FSR3_OutputUpscaledColor"
|
|
|
|
|
#define FSR_InputColor L"FSR3_InputColor"
|
|
|
|
|
#define FSR_InputDepth L"FSR3_InputDepth"
|
|
|
|
|
#define FSR_InputMotionVectors L"FSR3_InputMotionVectors"
|
|
|
|
|
#define FSR_OutputUpscaledColor L"FSR3_OutputUpscaledColor"
|
|
|
|
|
#define FSR_InputExposure L"FSR3_InputExposure"
|
|
|
|
|
#define FSR_InputReactiveMap L"FSR3_InputReactiveMap"
|
|
|
|
|
#define FSR_TransparencyAndCompositionMap L"FSR3_TransparencyAndCompositionMap"
|
|
|
|
|
|
|
|
|
|
#define FSR_DilatedMotionVectors L"FSR_DilatedMotionVectors"
|
|
|
|
|
#define FSR_DilatedDepth L"FSR_DilatedDepth"
|
|
|
|
|
#define FSR_ReconstructedPrevNearestDepth L"FSR_ReconstructedPrevNearestDepth"
|
|
|
|
|
#elif UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
#warning "Using FFX-FSR3.1"
|
|
|
|
|
#include <FidelityFX/host/ffx_fsr3upscaler.h>
|
|
|
|
|
#include <FidelityFX/host/ffx_frameinterpolation.h>
|
|
|
|
|
#include <FidelityFX/host/ffx_opticalflow.h>
|
|
|
|
|
|
|
|
|
|
#define FfxContext FfxFsr3UpscalerContext
|
|
|
|
|
#define FfxContextDescription FfxFsr3UpscalerContextDescription
|
|
|
|
|
#define FfxGenerateReactiveDescription FfxFsr3UpscalerGenerateReactiveDescription
|
|
|
|
|
@ -132,19 +189,33 @@ namespace {
|
|
|
|
|
FfxContext context;
|
|
|
|
|
FfxContextDescription contextDescription;
|
|
|
|
|
|
|
|
|
|
#if UF_USE_FFX_SDR_FRAME_INTERP && UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
uf::stl::vector<uint8_t> scratchBufferFG;
|
|
|
|
|
uf::stl::vector<uint8_t> scratchBufferOF;
|
|
|
|
|
|
|
|
|
|
FfxFrameInterpolationContext contextFG;
|
|
|
|
|
FfxFrameInterpolationContextDescription contextDescriptionFG;
|
|
|
|
|
|
|
|
|
|
FfxOpticalflowContext contextOF;
|
|
|
|
|
FfxOpticalflowContextDescription contextDescriptionOF;
|
|
|
|
|
#endif
|
|
|
|
|
struct {
|
|
|
|
|
uf::renderer::Texture empty;
|
|
|
|
|
uf::renderer::Texture output;
|
|
|
|
|
#if UF_USE_FFX_SDK == 3
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
uf::renderer::Texture outputFG;
|
|
|
|
|
uf::renderer::Texture dilatedMotionVectors;
|
|
|
|
|
uf::renderer::Texture dilatedDepth;
|
|
|
|
|
uf::renderer::Texture reconstructedPrevNearestDepth;
|
|
|
|
|
uf::renderer::Texture opticalFlowVector;
|
|
|
|
|
uf::renderer::Texture opticalFlowSceneChangeDetection;
|
|
|
|
|
#endif
|
|
|
|
|
} resources;
|
|
|
|
|
|
|
|
|
|
void initializeResource( uf::renderer::Texture& resource, uint32_t width = 0, uint32_t height = 0 ) {
|
|
|
|
|
void initializeResource( uf::renderer::Texture& resource, uint32_t width = 0, uint32_t height = 0, VkImageUsageFlags usage = 0, VkImageLayout layout = VK_IMAGE_LAYOUT_GENERAL ) {
|
|
|
|
|
if ( width == 0 ) width = uf::renderer::settings::width;
|
|
|
|
|
if ( height == 0 ) height = uf::renderer::settings::height;
|
|
|
|
|
resource.mips = 0;
|
|
|
|
|
resource.destroy();
|
|
|
|
|
resource.fromBuffers(
|
|
|
|
|
NULL,
|
|
|
|
|
@ -153,8 +224,8 @@ namespace {
|
|
|
|
|
width, height,
|
|
|
|
|
1,
|
|
|
|
|
1,
|
|
|
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
|
|
|
|
|
VK_IMAGE_LAYOUT_GENERAL
|
|
|
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | usage,
|
|
|
|
|
layout
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -193,6 +264,7 @@ namespace {
|
|
|
|
|
desc.format = ffxGetSurfaceFormatVK(texture.format);
|
|
|
|
|
desc.flags = FFX_RESOURCE_FLAGS_NONE;
|
|
|
|
|
if ( texture.usage & VK_IMAGE_USAGE_STORAGE_BIT ) desc.usage = FFX_RESOURCE_USAGE_UAV;
|
|
|
|
|
if ( texture.layout == VK_IMAGE_LAYOUT_GENERAL ) state = FFX_RESOURCE_STATE_UNORDERED_ACCESS;
|
|
|
|
|
|
|
|
|
|
return ffxGetResourceVK(texture.image, desc, (wchar_t*) name, state);
|
|
|
|
|
};
|
|
|
|
|
@ -203,7 +275,31 @@ namespace {
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void draw(VkCommandBuffer commandBuffer, size_t swapchainIndex) {
|
|
|
|
|
void barrier( VkCommandBuffer commandBuffer, VkImage image ) {
|
|
|
|
|
VkImageMemoryBarrier barrier = {};
|
|
|
|
|
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
|
|
barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
|
|
|
|
barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; // FFX expects GENERAL
|
|
|
|
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
|
|
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
|
|
|
barrier.image = image;
|
|
|
|
|
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
|
barrier.subresourceRange.baseMipLevel = 0;
|
|
|
|
|
barrier.subresourceRange.levelCount = 1;
|
|
|
|
|
barrier.subresourceRange.baseArrayLayer = 0;
|
|
|
|
|
barrier.subresourceRange.layerCount = 1;
|
|
|
|
|
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
|
|
|
|
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
|
|
|
|
|
|
|
|
|
vkCmdPipelineBarrier(
|
|
|
|
|
commandBuffer,
|
|
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
|
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
|
|
|
|
0, 0, nullptr, 0, nullptr, 1, &barrier
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void upscale( VkCommandBuffer commandBuffer ) {
|
|
|
|
|
FfxDispatchDescription dispatchParameters = {};
|
|
|
|
|
dispatchParameters.commandList = ffxGetCommandListVK(commandBuffer);
|
|
|
|
|
|
|
|
|
|
@ -238,13 +334,17 @@ namespace {
|
|
|
|
|
dispatchParameters.reactive = createFfxResource(::resources.empty, FSR_InputReactiveMap);
|
|
|
|
|
dispatchParameters.transparencyAndComposition = createFfxResource(::resources.empty, FSR_TransparencyAndCompositionMap);
|
|
|
|
|
|
|
|
|
|
#if UF_USE_FFX_SDK == 3
|
|
|
|
|
dispatchParameters.dilatedMotionVectors = createFfxResource(::resources.dilatedMotionVectors, FSR_DilatedMotionVectors, FFX_RESOURCE_STATE_UNORDERED_ACCESS);
|
|
|
|
|
dispatchParameters.dilatedDepth = createFfxResource(::resources.dilatedDepth, FSR_DilatedDepth, FFX_RESOURCE_STATE_UNORDERED_ACCESS);
|
|
|
|
|
dispatchParameters.reconstructedPrevNearestDepth = createFfxResource(::resources.reconstructedPrevNearestDepth, FSR_ReconstructedPrevNearestDepth, FFX_RESOURCE_STATE_UNORDERED_ACCESS);
|
|
|
|
|
#endif
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
dispatchParameters.dilatedMotionVectors = createFfxResource(::resources.dilatedMotionVectors, FSR_DilatedMotionVectors);
|
|
|
|
|
dispatchParameters.dilatedDepth = createFfxResource(::resources.dilatedDepth, FSR_DilatedDepth);
|
|
|
|
|
dispatchParameters.reconstructedPrevNearestDepth = createFfxResource(::resources.reconstructedPrevNearestDepth, FSR_ReconstructedPrevNearestDepth);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
dispatchParameters.output = createFfxResource(::resources.output, FSR_OutputUpscaledColor, FFX_RESOURCE_STATE_UNORDERED_ACCESS );
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3
|
|
|
|
|
dispatchParameters.upscaleOutput = createFfxResource(::resources.output, FSR_OutputUpscaledColor );
|
|
|
|
|
#else
|
|
|
|
|
dispatchParameters.output = createFfxResource(::resources.output, FSR_OutputUpscaledColor );
|
|
|
|
|
#endif
|
|
|
|
|
#else
|
|
|
|
|
dispatchParameters.color = ffxGetTextureResourceVK(&::context, attachmentColor.image, attachmentColor.view, renderSize.x, renderSize.y, attachmentColor.descriptor.format, FSR_InputColor );
|
|
|
|
|
dispatchParameters.depth = ffxGetTextureResourceVK(&::context, attachmentDepth.image, attachmentDepth.view, renderSize.x, renderSize.y, attachmentDepth.descriptor.format, FSR_InputDepth );
|
|
|
|
|
@ -254,7 +354,7 @@ namespace {
|
|
|
|
|
dispatchParameters.reactive = ffxGetTextureResourceVK(&::context, nullptr, nullptr, 1, 1, VK_FORMAT_UNDEFINED, FSR_InputReactiveMap );
|
|
|
|
|
dispatchParameters.transparencyAndComposition = ffxGetTextureResourceVK(&::context, nullptr, nullptr, 1, 1, VK_FORMAT_UNDEFINED, FSR_TransparencyAndCompositionMap );
|
|
|
|
|
|
|
|
|
|
dispatchParameters.output = ffxGetTextureResourceVK(&::context, ::resources.output.image, ::resources.output.view, ::resources.output.width, ::resources.output.height, ::resources.output.format, FSR_OutputUpscaledColor, FFX_RESOURCE_STATE_UNORDERED_ACCESS );
|
|
|
|
|
dispatchParameters.output = ffxGetTextureResourceVK(&::context, ::resources.output.image, ::resources.output.view, ::resources.output.width, ::resources.output.height, ::resources.output.format, FSR_OutputUpscaledColor );
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
auto& controller = scene.getController();
|
|
|
|
|
@ -274,7 +374,119 @@ namespace {
|
|
|
|
|
dispatchParameters.cameraFovAngleVertical = 2.0f * std::atan(1.0f / fabs(projection(1,1)));
|
|
|
|
|
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextDispatch(&::context, &dispatchParameters));
|
|
|
|
|
barrier(commandBuffer, ::resources.output.image);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// finish filling out
|
|
|
|
|
#if UF_USE_FFX_SDR_FRAME_INTERP
|
|
|
|
|
void framegen( VkCommandBuffer commandBuffer ) {
|
|
|
|
|
if ( !uf::renderer::hasRenderMode("", true) ) return;
|
|
|
|
|
if ( !uf::renderer::hasRenderMode("Swapchain", true) ) return;
|
|
|
|
|
auto& swapchainRenderMode = uf::renderer::getRenderMode("Swapchain", true);
|
|
|
|
|
auto& renderMode = uf::renderer::getRenderMode("", true);
|
|
|
|
|
|
|
|
|
|
pod::Vector2ui renderSize = {
|
|
|
|
|
renderMode.width > 0 ? renderMode.width : (uf::renderer::settings::width * renderMode.scale),
|
|
|
|
|
renderMode.height > 0 ? renderMode.height : (uf::renderer::settings::height * renderMode.scale),
|
|
|
|
|
};
|
|
|
|
|
pod::Vector2ui displaySize = {
|
|
|
|
|
swapchainRenderMode.width > 0 ? swapchainRenderMode.width : uf::renderer::settings::width,
|
|
|
|
|
swapchainRenderMode.height > 0 ? swapchainRenderMode.height : uf::renderer::settings::height,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto& scene = uf::scene::getCurrentScene();
|
|
|
|
|
auto& controller = scene.getController();
|
|
|
|
|
auto& camera = controller.getComponent<uf::Camera>();
|
|
|
|
|
auto& projection = camera.getProjection();
|
|
|
|
|
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3
|
|
|
|
|
FfxFsr3DispatchFrameGenerationPrepareDescription dispatchParameters = {};
|
|
|
|
|
dispatchParameters.commandList = ffxGetCommandListVK(commandBuffer);
|
|
|
|
|
|
|
|
|
|
// ...
|
|
|
|
|
|
|
|
|
|
FFX_ERROR_CHECK(ffxFsr3ContextDispatchFrameGenerationPrepare(&::context, &dispatchParameters));
|
|
|
|
|
#elif UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
FfxFrameInterpolationDispatchDescription dispatchParameters = {};
|
|
|
|
|
dispatchParameters.commandList = ffxGetCommandListVK(commandBuffer);
|
|
|
|
|
|
|
|
|
|
dispatchParameters.displaySize.width = displaySize.x;
|
|
|
|
|
dispatchParameters.displaySize.height = displaySize.y;
|
|
|
|
|
dispatchParameters.renderSize.width = displaySize.x;
|
|
|
|
|
dispatchParameters.renderSize.height = displaySize.y;
|
|
|
|
|
|
|
|
|
|
// use output from rendermode
|
|
|
|
|
if ( ext::fsr::frameUpscale ) {
|
|
|
|
|
if ( !renderMode.hasAttachment("output") && !renderMode.hasAttachment("color") ) return;
|
|
|
|
|
auto& attachmentColor = renderMode.hasAttachment("output") ? renderMode.getAttachment("output") : renderMode.getAttachment("color");
|
|
|
|
|
dispatchParameters.currentBackBuffer = createFfxResource(attachmentColor, L"FSR3_InterpolationSource");
|
|
|
|
|
} else {
|
|
|
|
|
dispatchParameters.currentBackBuffer = createFfxResource(::resources.output, L"FSR3_InterpolationSource");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
dispatchParameters.output = createFfxResource(::resources.outputFG, L"FSR3_InterpolatedOutput");
|
|
|
|
|
|
|
|
|
|
dispatchParameters.cameraNear = projection(2,3);
|
|
|
|
|
dispatchParameters.cameraFar = FLT_MAX;
|
|
|
|
|
dispatchParameters.cameraFovAngleVertical = 2.0f * std::atan(1.0f / fabs(projection(1,1)));
|
|
|
|
|
dispatchParameters.viewSpaceToMetersFactor = 1.0f;
|
|
|
|
|
|
|
|
|
|
dispatchParameters.frameTimeDelta = uf::time::delta * 1000.0f;
|
|
|
|
|
dispatchParameters.reset = uf::renderer::states::frameAccumulateReset;
|
|
|
|
|
|
|
|
|
|
static uint64_t frameID = 0;
|
|
|
|
|
dispatchParameters.frameID = frameID++;
|
|
|
|
|
|
|
|
|
|
dispatchParameters.backBufferTransferFunction = uf::renderer::settings::pipelines::hdr ? FFX_BACKBUFFER_TRANSFER_FUNCTION_PQ : FFX_BACKBUFFER_TRANSFER_FUNCTION_SRGB;
|
|
|
|
|
dispatchParameters.minMaxLuminance[0] = 0.0f;
|
|
|
|
|
dispatchParameters.minMaxLuminance[1] = 1000.0f;
|
|
|
|
|
|
|
|
|
|
dispatchParameters.dilatedDepth = createFfxResource(::resources.dilatedDepth, FSR_DilatedDepth);
|
|
|
|
|
dispatchParameters.dilatedMotionVectors = createFfxResource(::resources.dilatedMotionVectors, FSR_DilatedMotionVectors);
|
|
|
|
|
dispatchParameters.reconstructedPrevDepth = createFfxResource(::resources.reconstructedPrevNearestDepth, FSR_ReconstructedPrevNearestDepth);
|
|
|
|
|
|
|
|
|
|
dispatchParameters.opticalFlowVector = createFfxResource(::resources.opticalFlowVector, L"OF_Vector");
|
|
|
|
|
dispatchParameters.opticalFlowSceneChangeDetection = createFfxResource(::resources.opticalFlowSceneChangeDetection, L"OF_SCD");
|
|
|
|
|
dispatchParameters.opticalFlowScale.x = 1.0f;
|
|
|
|
|
dispatchParameters.opticalFlowScale.y = 1.0f;
|
|
|
|
|
dispatchParameters.opticalFlowBlockSize = FFX_FSR_BLOCK_SIZE;
|
|
|
|
|
|
|
|
|
|
FFX_ERROR_CHECK(ffxFrameInterpolationDispatch(&::contextFG, &dispatchParameters));
|
|
|
|
|
barrier(commandBuffer, ::resources.outputFG.image);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
void computeOpticalFlow( VkCommandBuffer commandBuffer ) {
|
|
|
|
|
FfxOpticalflowDispatchDescription dispatchParameters = {};
|
|
|
|
|
dispatchParameters.commandList = ffxGetCommandListVK(commandBuffer);
|
|
|
|
|
|
|
|
|
|
// use output from rendermode
|
|
|
|
|
if ( !ext::fsr::frameUpscale ) {
|
|
|
|
|
if ( !uf::renderer::hasRenderMode("", true) ) return;
|
|
|
|
|
auto& renderMode = uf::renderer::getRenderMode("", true);
|
|
|
|
|
if ( !renderMode.hasAttachment("output") && !renderMode.hasAttachment("color") ) return;
|
|
|
|
|
auto& attachmentColor = renderMode.hasAttachment("output") ? renderMode.getAttachment("output") : renderMode.getAttachment("color");
|
|
|
|
|
dispatchParameters.color = createFfxResource(attachmentColor, L"OF_InputColor");
|
|
|
|
|
} else {
|
|
|
|
|
dispatchParameters.color = createFfxResource(::resources.output, L"OF_InputColor");
|
|
|
|
|
}
|
|
|
|
|
dispatchParameters.reset = uf::renderer::states::frameAccumulateReset;
|
|
|
|
|
|
|
|
|
|
dispatchParameters.backbufferTransferFunction = uf::renderer::settings::pipelines::hdr ? FFX_BACKBUFFER_TRANSFER_FUNCTION_PQ : FFX_BACKBUFFER_TRANSFER_FUNCTION_SRGB;
|
|
|
|
|
dispatchParameters.minMaxLuminance.x = 0.0f;
|
|
|
|
|
dispatchParameters.minMaxLuminance.y = 1000.0f;
|
|
|
|
|
|
|
|
|
|
dispatchParameters.opticalFlowVector = createFfxResource(::resources.opticalFlowVector, L"OF_Vector");
|
|
|
|
|
dispatchParameters.opticalFlowSCD = createFfxResource(::resources.opticalFlowSceneChangeDetection, L"OF_SCD");
|
|
|
|
|
|
|
|
|
|
FFX_ERROR_CHECK(ffxOpticalflowContextDispatch(&::contextOF, &dispatchParameters));
|
|
|
|
|
|
|
|
|
|
barrier(commandBuffer, ::resources.opticalFlowVector.image);
|
|
|
|
|
barrier(commandBuffer, ::resources.opticalFlowSceneChangeDetection.image);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uf::stl::string ext::fsr::preset = "native";
|
|
|
|
|
@ -282,28 +494,48 @@ pod::Vector2f ext::fsr::jitter = {};
|
|
|
|
|
float ext::fsr::sharpness = 1.0f;
|
|
|
|
|
float ext::fsr::jitterScale = 2.0f;
|
|
|
|
|
bool ext::fsr::initialized = false;
|
|
|
|
|
|
|
|
|
|
uf::renderer::Texture& ext::fsr::getRenderTarget() {
|
|
|
|
|
return ::resources.output;
|
|
|
|
|
}
|
|
|
|
|
bool ext::fsr::frameUpscale = true;
|
|
|
|
|
bool ext::fsr::frameInterpolation = true;
|
|
|
|
|
|
|
|
|
|
void ext::fsr::initialize() {
|
|
|
|
|
auto scratchSize = ffxGetScratchMemorySizeVK(uf::renderer::device.physicalDevice, MAX(uf::renderer::device.extensions.properties.device.size(), 1) );
|
|
|
|
|
::scratchBuffer.resize(scratchSize);
|
|
|
|
|
// setup scratch buffer
|
|
|
|
|
{
|
|
|
|
|
auto scratchSize = ffxGetScratchMemorySizeVK(uf::renderer::device.physicalDevice, MAX(uf::renderer::device.extensions.properties.device.size(), 1) );
|
|
|
|
|
if ( ext::fsr::frameUpscale ) {
|
|
|
|
|
::scratchBuffer.resize(scratchSize);
|
|
|
|
|
}
|
|
|
|
|
if ( ext::fsr::frameInterpolation ) {
|
|
|
|
|
#if UF_USE_FFX_SDR_FRAME_INTERP
|
|
|
|
|
::scratchBufferFG.resize(scratchSize);
|
|
|
|
|
#endif
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
::scratchBufferOF.resize(scratchSize);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::contextDescription.maxRenderSize.width = 3840;
|
|
|
|
|
::contextDescription.maxRenderSize.height = 2160;
|
|
|
|
|
#if UF_USE_FFX_SDK == 3
|
|
|
|
|
::contextDescription.maxUpscaleSize.width = uf::renderer::settings::width;
|
|
|
|
|
::contextDescription.maxUpscaleSize.height = uf::renderer::settings::height;
|
|
|
|
|
#else
|
|
|
|
|
::contextDescription.displaySize.width = uf::renderer::settings::width;
|
|
|
|
|
::contextDescription.displaySize.height = uf::renderer::settings::height;
|
|
|
|
|
#endif
|
|
|
|
|
::contextDescription.flags = FFX_FSR_ENABLE_AUTO_EXPOSURE | FFX_FSR_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION;
|
|
|
|
|
// setup context description
|
|
|
|
|
if ( ext::fsr::frameUpscale ) {
|
|
|
|
|
::contextDescription.maxRenderSize.width = FFX_FSR_MAX_WIDTH;
|
|
|
|
|
::contextDescription.maxRenderSize.height = FFX_FSR_MAX_HEIGHT;
|
|
|
|
|
#if UF_USE_FFX_SDK >= FFX_SDK_3
|
|
|
|
|
::contextDescription.maxUpscaleSize.width = uf::renderer::settings::width;
|
|
|
|
|
::contextDescription.maxUpscaleSize.height = uf::renderer::settings::height;
|
|
|
|
|
#else
|
|
|
|
|
::contextDescription.displaySize.width = uf::renderer::settings::width;
|
|
|
|
|
::contextDescription.displaySize.height = uf::renderer::settings::height;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// to-do: validate if motion vectors are rendered with jitter
|
|
|
|
|
//::contextDescription.flags = FFX_FSR_ENABLE_AUTO_EXPOSURE | FFX_FSR_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION;
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3
|
|
|
|
|
if ( !ext::fsr::frameInterpolation ) ::contextDescription.flags |= FFX_FSR3_ENABLE_UPSCALING_ONLY;
|
|
|
|
|
::contextDescription.backBufferFormat = ffxGetSurfaceFormatVK(ext::vulkan::settings::formats::color);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if ( uf::renderer::settings::pipelines::hdr ) ::contextDescription.flags |= FFX_FSR_ENABLE_HIGH_DYNAMIC_RANGE;
|
|
|
|
|
if ( uf::matrix::reverseInfiniteProjection ) ::contextDescription.flags |= FFX_FSR_ENABLE_DEPTH_INVERTED | FFX_FSR_ENABLE_DEPTH_INFINITE;
|
|
|
|
|
if ( uf::renderer::settings::pipelines::hdr ) ::contextDescription.flags |= FFX_FSR_ENABLE_HIGH_DYNAMIC_RANGE;
|
|
|
|
|
if ( uf::matrix::reverseInfiniteProjection ) ::contextDescription.flags |= FFX_FSR_ENABLE_DEPTH_INVERTED | FFX_FSR_ENABLE_DEPTH_INFINITE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if UF_USE_FFX_SDK
|
|
|
|
|
VkDeviceContext deviceContextVK = {};
|
|
|
|
|
@ -311,23 +543,78 @@ void ext::fsr::initialize() {
|
|
|
|
|
deviceContextVK.vkPhysicalDevice = uf::renderer::device.physicalDevice;
|
|
|
|
|
deviceContextVK.vkDeviceProcAddr = vkGetDeviceProcAddr;
|
|
|
|
|
FfxDevice ffxDevice = ffxGetDeviceVK(&deviceContextVK);
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescription.backendInterface, ffxDevice, ::scratchBuffer.data(), ::scratchBuffer.size(), 1 ));
|
|
|
|
|
#else
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescription.callbacks, ::scratchBuffer.data(), ::scratchBuffer.size(), uf::renderer::device.physicalDevice, &vkGetDeviceProcAddr ));
|
|
|
|
|
#endif
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextCreate( &::context, &::contextDescription ));
|
|
|
|
|
|
|
|
|
|
::resources.output.format = uf::renderer::settings::pipelines::hdr ? uf::renderer::enums::Format::HDR : uf::renderer::enums::Format::SDR;
|
|
|
|
|
::initializeResource( ::resources.output );
|
|
|
|
|
#if UF_USE_FFX_SDK == 3
|
|
|
|
|
::resources.dilatedMotionVectors.format = uf::renderer::enums::Format::R16G16_SFLOAT;
|
|
|
|
|
::resources.dilatedDepth.format = uf::renderer::enums::Format::R32_SFLOAT;
|
|
|
|
|
::resources.reconstructedPrevNearestDepth.format = uf::renderer::enums::Format::R32_UINT;
|
|
|
|
|
// setup context
|
|
|
|
|
if ( ext::fsr::frameUpscale ) {
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescription.backendInterfaceUpscaling, ffxDevice, ::scratchBuffer.data(), ::scratchBuffer.size(), 1 ));
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescription.backendInterfaceSharedResources, ffxDevice, ::scratchBuffer.data(), ::scratchBuffer.size(), 1 ));
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescription.backendInterfaceFrameInterpolation, ffxDevice, ::scratchBuffer.data(), ::scratchBuffer.size(), 1 ));
|
|
|
|
|
#elif UF_USE_FFX_SDK
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescription.backendInterface, ffxDevice, ::scratchBuffer.data(), ::scratchBuffer.size(), 1 ));
|
|
|
|
|
#else
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescription.callbacks, ::scratchBuffer.data(), ::scratchBuffer.size(), uf::renderer::device.physicalDevice, &vkGetDeviceProcAddr ));
|
|
|
|
|
#endif
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextCreate( &::context, &::contextDescription ));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::initializeResource( ::resources.dilatedMotionVectors );
|
|
|
|
|
::initializeResource( ::resources.dilatedDepth );
|
|
|
|
|
::initializeResource( ::resources.reconstructedPrevNearestDepth );
|
|
|
|
|
#endif
|
|
|
|
|
#if UF_USE_FFX_SDR_FRAME_INTERP && UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
// setup frame interpolation context
|
|
|
|
|
if ( ext::fsr::frameInterpolation ) {
|
|
|
|
|
::contextDescriptionFG.maxRenderSize.width = FFX_FSR_MAX_WIDTH;
|
|
|
|
|
::contextDescriptionFG.maxRenderSize.height = FFX_FSR_MAX_HEIGHT;
|
|
|
|
|
::contextDescriptionFG.displaySize.width = uf::renderer::settings::width;
|
|
|
|
|
::contextDescriptionFG.displaySize.height = uf::renderer::settings::height;
|
|
|
|
|
::contextDescriptionFG.previousInterpolationSourceFormat = ffxGetSurfaceFormatVK( uf::renderer::settings::pipelines::hdr ? uf::renderer::enums::Format::HDR : uf::renderer::enums::Format::SDR );
|
|
|
|
|
::contextDescriptionFG.backBufferFormat = ::contextDescriptionFG.previousInterpolationSourceFormat;
|
|
|
|
|
// ::contextDescriptionFG.backBufferFormat = ffxGetSurfaceFormatVK( ext::vulkan::settings::formats::color );
|
|
|
|
|
|
|
|
|
|
// to-do: validate if motion vectors are rendered with jitter
|
|
|
|
|
// ::contextDescriptionFG.flags = FFX_FRAMEINTERPOLATION_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS;
|
|
|
|
|
if ( uf::renderer::settings::pipelines::hdr ) ::contextDescriptionFG.flags |= FFX_FRAMEINTERPOLATION_ENABLE_HDR_COLOR_INPUT;
|
|
|
|
|
if ( uf::matrix::reverseInfiniteProjection ) ::contextDescriptionFG.flags |= FFX_FRAMEINTERPOLATION_ENABLE_DEPTH_INVERTED | FFX_FRAMEINTERPOLATION_ENABLE_DEPTH_INFINITE;
|
|
|
|
|
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescriptionFG.backendInterface, ffxDevice, ::scratchBufferFG.data(), ::scratchBufferFG.size(), 1 ));
|
|
|
|
|
FFX_ERROR_CHECK(ffxFrameInterpolationContextCreate( &::contextFG, &::contextDescriptionFG ));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// setup optical flow context
|
|
|
|
|
if ( ext::fsr::frameInterpolation ) {
|
|
|
|
|
::contextDescriptionOF.resolution.width = uf::renderer::settings::width;
|
|
|
|
|
::contextDescriptionOF.resolution.height = uf::renderer::settings::height;
|
|
|
|
|
|
|
|
|
|
FFX_ERROR_CHECK(ffxGetInterfaceVK( &::contextDescriptionOF.backendInterface, ffxDevice, ::scratchBufferOF.data(), ::scratchBufferOF.size(), 1 ));
|
|
|
|
|
FFX_ERROR_CHECK(ffxOpticalflowContextCreate( &::contextOF, &::contextDescriptionOF ));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// setup resources
|
|
|
|
|
{
|
|
|
|
|
::resources.output.format = uf::renderer::settings::pipelines::hdr ? uf::renderer::enums::Format::HDR : uf::renderer::enums::Format::SDR;
|
|
|
|
|
::initializeResource( ::resources.output );
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
::resources.outputFG.viewComponentMapping.a = VK_COMPONENT_SWIZZLE_ONE; // for some reason framegen has the alpha set to 1 (or never writes it)
|
|
|
|
|
|
|
|
|
|
::resources.outputFG.format = uf::renderer::settings::pipelines::hdr ? uf::renderer::enums::Format::HDR : uf::renderer::enums::Format::SDR;
|
|
|
|
|
::resources.dilatedMotionVectors.format = uf::renderer::enums::Format::R16G16_SFLOAT;
|
|
|
|
|
::resources.dilatedDepth.format = uf::renderer::enums::Format::R32_SFLOAT;
|
|
|
|
|
::resources.reconstructedPrevNearestDepth.format = uf::renderer::enums::Format::R32_UINT;
|
|
|
|
|
::resources.opticalFlowVector.format = uf::renderer::enums::Format::R16G16_SINT;
|
|
|
|
|
::resources.opticalFlowSceneChangeDetection.format = uf::renderer::enums::Format::R32_UINT;
|
|
|
|
|
|
|
|
|
|
uint32_t block_size = FFX_FSR_BLOCK_SIZE;
|
|
|
|
|
uint32_t ofWidth = (uf::renderer::settings::width + block_size) / block_size;
|
|
|
|
|
uint32_t ofHeight = (uf::renderer::settings::height + block_size) / block_size;
|
|
|
|
|
|
|
|
|
|
::initializeResource( ::resources.outputFG );
|
|
|
|
|
::initializeResource( ::resources.dilatedMotionVectors );
|
|
|
|
|
::initializeResource( ::resources.dilatedDepth );
|
|
|
|
|
::initializeResource( ::resources.reconstructedPrevNearestDepth );
|
|
|
|
|
::initializeResource( ::resources.opticalFlowVector, ofWidth, ofHeight );
|
|
|
|
|
::initializeResource( ::resources.opticalFlowSceneChangeDetection, ofWidth, ofHeight );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ext::fsr::initialized = true;
|
|
|
|
|
}
|
|
|
|
|
@ -338,67 +625,148 @@ void ext::fsr::tick() {
|
|
|
|
|
pod::Vector2ui displaySize = {};
|
|
|
|
|
|
|
|
|
|
if ( !uf::renderer::hasRenderMode("", true) ) return;
|
|
|
|
|
if ( !uf::renderer::hasRenderMode("Swapchain", true) ) return;
|
|
|
|
|
|
|
|
|
|
auto& renderMode = uf::renderer::getRenderMode("", true);
|
|
|
|
|
renderSize = {
|
|
|
|
|
renderMode.width > 0 ? renderMode.width : (uf::renderer::settings::width * renderMode.scale),
|
|
|
|
|
renderMode.height > 0 ? renderMode.height : (uf::renderer::settings::height * renderMode.scale),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto& swapchainRenderMode = uf::renderer::getRenderMode("Swapchain", true);
|
|
|
|
|
|
|
|
|
|
// update sizes
|
|
|
|
|
{
|
|
|
|
|
if ( !uf::renderer::hasRenderMode("Swapchain", true) ) return;
|
|
|
|
|
auto& swapchainRenderMode = uf::renderer::getRenderMode("Swapchain", true);
|
|
|
|
|
renderSize = {
|
|
|
|
|
renderMode.width > 0 ? renderMode.width : (uf::renderer::settings::width * renderMode.scale),
|
|
|
|
|
renderMode.height > 0 ? renderMode.height : (uf::renderer::settings::height * renderMode.scale),
|
|
|
|
|
};
|
|
|
|
|
displaySize = {
|
|
|
|
|
swapchainRenderMode.width > 0 ? swapchainRenderMode.width : uf::renderer::settings::width,
|
|
|
|
|
swapchainRenderMode.height > 0 ? swapchainRenderMode.height : uf::renderer::settings::height,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( uf::renderer::states::resized ) {
|
|
|
|
|
#if UF_USE_FFX_SDK == 3
|
|
|
|
|
::contextDescription.maxUpscaleSize.width = uf::renderer::settings::width;
|
|
|
|
|
::contextDescription.maxUpscaleSize.height = uf::renderer::settings::height;
|
|
|
|
|
#else
|
|
|
|
|
::contextDescription.displaySize.width = displaySize.x;
|
|
|
|
|
::contextDescription.displaySize.height = displaySize.y;
|
|
|
|
|
#endif
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextDestroy( &::context ));
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextCreate( &::context, &::contextDescription ));
|
|
|
|
|
if ( uf::renderer::states::resized || ::resources.output.width != displaySize.x || ::resources.output.height != displaySize.y ) {
|
|
|
|
|
// recreate context
|
|
|
|
|
// uf::renderer::states::rebuild = true;
|
|
|
|
|
if ( ext::fsr::frameUpscale ) {
|
|
|
|
|
#if UF_USE_FFX_SDK >= FFX_SDK_3
|
|
|
|
|
::contextDescription.maxUpscaleSize.width = displaySize.x;
|
|
|
|
|
::contextDescription.maxUpscaleSize.height = displaySize.y;
|
|
|
|
|
#else
|
|
|
|
|
::contextDescription.displaySize.width = displaySize.x;
|
|
|
|
|
::contextDescription.displaySize.height = displaySize.y;
|
|
|
|
|
#endif
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextDestroy( &::context ));
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextCreate( &::context, &::contextDescription ));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::initializeResource( ::resources.output, displaySize.x, displaySize.y );
|
|
|
|
|
#if UF_USE_FFX_SDK == 3
|
|
|
|
|
::initializeResource( ::resources.dilatedMotionVectors, displaySize.x, displaySize.y );
|
|
|
|
|
::initializeResource( ::resources.dilatedDepth, displaySize.x, displaySize.y );
|
|
|
|
|
::initializeResource( ::resources.reconstructedPrevNearestDepth, displaySize.x, displaySize.y );
|
|
|
|
|
#endif
|
|
|
|
|
#if UF_USE_FFX_SDR_FRAME_INTERP && UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
// recreate frame interpolation context
|
|
|
|
|
if ( ext::fsr::frameInterpolation ) {
|
|
|
|
|
::contextDescriptionFG.displaySize.width = displaySize.x;
|
|
|
|
|
::contextDescriptionFG.displaySize.height = displaySize.y;
|
|
|
|
|
|
|
|
|
|
FFX_ERROR_CHECK(ffxFrameInterpolationContextDestroy( &::contextFG ));
|
|
|
|
|
FFX_ERROR_CHECK(ffxFrameInterpolationContextCreate( &::contextFG, &::contextDescriptionFG ));
|
|
|
|
|
}
|
|
|
|
|
// recreate optical flow context
|
|
|
|
|
if ( ext::fsr::frameInterpolation ) {
|
|
|
|
|
::contextDescriptionOF.resolution.width = displaySize.x;
|
|
|
|
|
::contextDescriptionOF.resolution.height = displaySize.y;
|
|
|
|
|
|
|
|
|
|
FFX_ERROR_CHECK(ffxOpticalflowContextDestroy( &::contextOF ));
|
|
|
|
|
FFX_ERROR_CHECK(ffxOpticalflowContextCreate( &::contextOF, &::contextDescriptionOF ));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// recreate resources
|
|
|
|
|
{
|
|
|
|
|
::initializeResource( ::resources.output, displaySize.x, displaySize.y );
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
uint32_t block_size = FFX_FSR_BLOCK_SIZE;
|
|
|
|
|
uint32_t ofWidth = (displaySize.x + block_size) / block_size;
|
|
|
|
|
uint32_t ofHeight = (displaySize.y + block_size) / block_size;
|
|
|
|
|
|
|
|
|
|
::initializeResource( ::resources.outputFG, displaySize.x, displaySize.y );
|
|
|
|
|
::initializeResource( ::resources.dilatedMotionVectors, displaySize.x, displaySize.y );
|
|
|
|
|
::initializeResource( ::resources.dilatedDepth, displaySize.x, displaySize.y );
|
|
|
|
|
::initializeResource( ::resources.reconstructedPrevNearestDepth, displaySize.x, displaySize.y );
|
|
|
|
|
::initializeResource( ::resources.opticalFlowVector, ofWidth, ofHeight );
|
|
|
|
|
::initializeResource( ::resources.opticalFlowSceneChangeDetection, ofWidth, ofHeight );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int32_t jitterPhaseCount = ffxGetJitterPhaseCount(renderSize.x, displaySize.x);
|
|
|
|
|
static uint32_t index = 0;
|
|
|
|
|
index = (index + 1) % jitterPhaseCount;
|
|
|
|
|
// update jitter
|
|
|
|
|
{
|
|
|
|
|
const int32_t jitterPhaseCount = ffxGetJitterPhaseCount(renderSize.x, displaySize.x);
|
|
|
|
|
static uint32_t index = 0;
|
|
|
|
|
index = (index + 1) % jitterPhaseCount;
|
|
|
|
|
|
|
|
|
|
ffxGetJitterOffset(&ext::fsr::jitter.x, &ext::fsr::jitter.y, index, jitterPhaseCount);
|
|
|
|
|
ffxGetJitterOffset(&ext::fsr::jitter.x, &ext::fsr::jitter.y, index, jitterPhaseCount);
|
|
|
|
|
|
|
|
|
|
pod::Vector2f jitter = {};
|
|
|
|
|
pod::Vector2f jitter = {};
|
|
|
|
|
|
|
|
|
|
jitter.x = ext::fsr::jitterScale * ext::fsr::jitter.x / (float) renderSize.x;
|
|
|
|
|
jitter.y = ext::fsr::jitterScale * ext::fsr::jitter.y / (float) renderSize.y;
|
|
|
|
|
jitter.x = ext::fsr::jitterScale * ext::fsr::jitter.x / (float) renderSize.x;
|
|
|
|
|
jitter.y = ext::fsr::jitterScale * ext::fsr::jitter.y / (float) renderSize.y;
|
|
|
|
|
|
|
|
|
|
ext::fsr::jitter = jitter;
|
|
|
|
|
::jitterMatrix = uf::matrix::translate( uf::matrix::identity(), pod::Vector3f{ jitter.x, jitter.y, 0 } );
|
|
|
|
|
ext::fsr::jitter = jitter;
|
|
|
|
|
::jitterMatrix = uf::matrix::translate( uf::matrix::identity(), pod::Vector3f{ jitter.x, jitter.y, 0 } );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void ext::fsr::render() {
|
|
|
|
|
if ( !ext::fsr::initialized ) return;
|
|
|
|
|
|
|
|
|
|
auto commandBuffer = uf::renderer::device.fetchCommandBuffer(uf::renderer::QueueEnum::GRAPHICS, true); // immediately flush
|
|
|
|
|
draw(commandBuffer, uf::renderer::states::currentBuffer);
|
|
|
|
|
if ( ext::fsr::frameUpscale ) {
|
|
|
|
|
upscale( commandBuffer );
|
|
|
|
|
}
|
|
|
|
|
if ( ext::fsr::frameInterpolation ) {
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
computeOpticalFlow( commandBuffer );
|
|
|
|
|
#endif
|
|
|
|
|
#if UF_USE_FFX_SDR_FRAME_INTERP
|
|
|
|
|
framegen( commandBuffer );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
uf::renderer::device.flushCommandBuffer(commandBuffer);
|
|
|
|
|
}
|
|
|
|
|
void ext::fsr::terminate() {
|
|
|
|
|
if ( !ext::fsr::initialized ) return;
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextDestroy( &::context ));
|
|
|
|
|
|
|
|
|
|
// destroy context
|
|
|
|
|
if ( ext::fsr::frameUpscale ) {
|
|
|
|
|
FFX_ERROR_CHECK(ffxContextDestroy( &::context ));
|
|
|
|
|
}
|
|
|
|
|
// destroy framegen context
|
|
|
|
|
#if UF_USE_FFX_SDR_FRAME_INTERP && UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
if ( ext::fsr::frameInterpolation ) {
|
|
|
|
|
FFX_ERROR_CHECK(ffxFrameInterpolationContextDestroy( &::contextFG ));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// destroy resources
|
|
|
|
|
{
|
|
|
|
|
::resources.output.destroy();
|
|
|
|
|
#if UF_USE_FFX_SDK == FFX_SDK_3_1
|
|
|
|
|
::resources.outputFG.destroy();
|
|
|
|
|
::resources.dilatedMotionVectors.destroy();
|
|
|
|
|
::resources.dilatedDepth.destroy();
|
|
|
|
|
::resources.reconstructedPrevNearestDepth.destroy();
|
|
|
|
|
::resources.opticalFlowVector.destroy();
|
|
|
|
|
::resources.opticalFlowSceneChangeDetection.destroy();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pod::Matrix4f ext::fsr::getJitterMatrix() {
|
|
|
|
|
return ::jitterMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uf::renderer::Texture& ext::fsr::getRenderTarget() {
|
|
|
|
|
#if UF_USE_FFX_SDR_FRAME_INTERP
|
|
|
|
|
if ( ext::fsr::frameInterpolation ) return ::resources.outputFG;
|
|
|
|
|
#endif
|
|
|
|
|
return ::resources.output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// to-do: add functions to get framegen swapchain functions
|
|
|
|
|
|
|
|
|
|
#endif
|