FidelityFX Super Resolution 1.2 (FSR1)

Screenshot

Table of contents

Introduction

AMD FidelityFX Super Resolution (FSR1) is our open source, high-quality solution for producing high resolution frames from lower resolution inputs.

It uses a collection of cutting-edge algorithms with a particular emphasis on creating high-quality edges, giving large performance improvements compared to rendering at native resolution directly. FSR1 enables “practical performance” for costly render operations, such as hardware ray tracing.

Integration guidelines

Shading language and API requirements

DirectX 12 + HLSL

  • HLSL

    • CS_6_2

Vulkan + GLSL

  • Vulkan 1.x

  • GLSL 4.50 with the following extensions:

    • GL_EXT_samplerless_texture_functions

Note that the GLSL compiler must also support GL_GOOGLE_include_directive for #include handling used throughout the GLSL shader system.

Expected input

  • Image should already be well anti-aliased by a technique like TAA, MSAA etc.

  • Image should be normalized to [0-1] and be in perceptual color space (sRGB, not linear).

    • A negative input to RCAS will output NaN!

  • Image should be generated using negative MIP bias to increase texture detail.

  • Image should be noise free.

Where in the frame?

FSR1 should be integrated into your pipeline after anti-aliased rendering and tone mapping, but before any post-processing effects that introduce noise such as Film Grain, Chromatic Aberration etc or User Interface rendering.

alt text

Walkthrough

Include the ffx_fsr1.h header:

Copied!

#include <FidelityFX/host/ffx_fsr1.h>

Query the amount of scratch memory required for the FFX Backend using ffxGetScratchMemorySize :

Copied!

const size_t scratchBufferSize = ffxGetScratchMemorySize (FFX_FSR1_CONTEXT_COUNT );

Allocate the scratch memory for the backend and retrieve the interface using ffxGetInterface :

Copied!

void* scratchBuffer  = malloc(scratchBufferSize);
FfxErrorCode  errorCode = ffxGetInterface (&backendInterface, DevicePtr(), scratchBuffer, scratchBufferSize, FFX_FSR1_CONTEXT_COUNT );
FFX_ASSERT(errorCode == FFX_OK );

Create the FfxFsr1Context by filling out the FfxFsr1ContextDescription structure with the required arguments:

Copied!

FfxFsr1Context  fsr1Context;

FfxFsr1ContextDescription  contextDesc = {};

// Fill out arguments
// If RCAS sharpening is required, add the FFX_FSR1_ENABLE_RCAS flag
contextDesc.flags                 = FFX_FSR1_ENABLE_HIGH_DYNAMIC_RANGE ;
contextDesc.maxRenderSize .width   = resInfo.RenderWidth;
contextDesc.maxRenderSize .height  = resInfo.RenderHeight;
contextDesc.displaySize .width     = resInfo.DisplayWidth;
contextDesc.displaySize .height    = resInfo.DisplayHeight;
contextDesc.backendInterface      = backendInterface;

// Create the FSR1 context
ffxFsr1ContextCreate (&fsr1Context, &contextDesc);

When the time comes for upscaling, fill out the FfxFsr1DispatchDescription structure and call ffxFsr1ContextDispatch using it:

Copied!

FfxFsr1DispatchDescription  dispatchParameters = {};

dispatchParameters.commandList  = ffxGetCommandList (pCmdList);
dispatchParameters.renderSize  = { resInfo.RenderWidth, resInfo.RenderHeight };
dispatchParameters.enableSharpening  = m_RCASSharpen;
dispatchParameters.sharpness  = m_Sharpness;
dispatchParameters.color  = ffxGetResource (m_pTempColorTarget->GetResource(), L"FSR1_InputColor", FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ );
dispatchParameters.output  = ffxGetResource (m_pColorTarget->GetResource(), L"FSR1_OutputUpscaledColor", FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ );

FfxErrorCode  errorCode = ffxFsr1ContextDispatch (&m_FSR1Context, &dispatchParameters);
FFX_ASSERT(errorCode == FFX_OK );

During shutdown, destroy the FSR1 context:

Copied!

ffxFsr1ContextDestroy (&m_FSR1Context);

The technique

FidelityFX Super Resolution is a spatial upscaler: it works by taking the current anti-aliased frame at render resolution and upscaling it to display resolution without relying on other data such as frame history or motion vectors.

At the heart of FSR1 is a cutting-edge algorithm that detects and recreates high-resolution edges from the source image. Those high-resolution edges are a critical element required for turning the current frame into a “super resolution” image.

FSR1 provides consistent upscaling quality regardless of whether the frame is in movement, which can provide quality advantages compared to other types of upscalers.

FSR1 is composed of two main passes:

An upscaling pass called EASU (Edge-Adaptive Spatial Upsampling) that also performs edge reconstruction. In this pass the input frame is analyzed and the main part of the algorithm detects gradient reversals – essentially looking at how neighboring gradients differ – from a set of input pixels. The intensity of the gradient reversals defines the weights to apply to the reconstructed pixels at display resolution.

A sharpening pass called RCAS (Robust Contrast-Adaptive Sharpening) that extracts pixel detail in the upscaled image.

FSR1 also comes with helper functions for color space conversions, dithering, and tone mapping to assist with integrating it into common rendering pipelines used with today’s games.

alt text

See also