Add FidelityFX Super Resolution 2.2 (FSR 2.2.1) support.
Introduces support for FSR2 as a new upscaler option available from the project settings. Also introduces an specific render list for surfaces that require motion and the ability to derive motion vectors from depth buffer and camera motion.
Use AMD FidelityFX Super Resolution 1.0 upscaling for the viewport's 3D buffer. The amount of scaling can be set using [member Viewport.scaling_3d_scale]. Values less than [code]1.0[/code] will be result in the viewport being upscaled using FSR. Values greater than [code]1.0[/code] are not supported and bilinear downsampling will be used instead. A value of [code]1.0[/code] disables scaling.
+ Use AMD FidelityFX Super Resolution 2.2 upscaling for the viewport's 3D buffer. The amount of scaling can be set using [member Viewport.scaling_3d_scale]. Values less than [code]1.0[/code] will be result in the viewport being upscaled using FSR2. Values greater than [code]1.0[/code] are not supported and bilinear downsampling will be used instead. A value of [code]1.0[/code] will use FSR2 at native resolution as a TAA solution.
Use AMD FidelityFX Super Resolution 1.0 upscaling for the viewport's 3D buffer. The amount of scaling can be set using [member scaling_3d_scale]. Values less than [code]1.0[/code] will be result in the viewport being upscaled using FSR. Values greater than [code]1.0[/code] are not supported and bilinear downsampling will be used instead. A value of [code]1.0[/code] disables scaling.
+ Use AMD FidelityFX Super Resolution 2.2 upscaling for the viewport's 3D buffer. The amount of scaling can be set using [member Viewport.scaling_3d_scale]. Values less than [code]1.0[/code] will be result in the viewport being upscaled using FSR2. Values greater than [code]1.0[/code] are not supported and bilinear downsampling will be used instead. A value of [code]1.0[/code] will use FSR2 at native resolution as a TAA solution.
bool can_use_effects = target_size.x >= 8 && target_size.y >= 8; // FIXME I think this should check internal size, we do all our post processing at this size...
buffers.base_fb = FramebufferCacheRD::get_singleton()->get_cache(buffers.base_texture); // TODO move this into bokeh_dof_raster, we can do this internally
tf.format = RD::DATA_FORMAT_R16_SFLOAT; // We could probably use DATA_FORMAT_R8_SNORM if we don't pre-multiply by blur_size but that depends on whether we can remove DEPTH_GAP
- tf.width = internal_size.x;
- tf.height = internal_size.y;
+ tf.width = blur_size.x;
+ tf.height = blur_size.y;
tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.array_layers = 1; // Our DOF effect handles one eye per turn
thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)WorkerThreadPool::get_singleton()->get_thread_count()); //make sure there is at least one thread per CPU
+ ERR_FAIL_COND_EDMSG(p_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR2 && OS::get_singleton()->get_current_rendering_method() != "forward_plus", "FSR2 is only available when using the Forward+ renderer.");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Bilinear (Fastest),FSR 1.0 (Fast)"), "set_scaling_3d_mode", "get_scaling_3d_mode"); // TODO VIEWPORT_SCALING_3D_MODE_OFF is possible here too, but we can't specify an enum string for it.
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Bilinear (Fastest),FSR 1.0 (Fast),FSR 2.2 (Slow)"), "set_scaling_3d_mode", "get_scaling_3d_mode"); // TODO VIEWPORT_SCALING_3D_MODE_OFF is possible here too, but we can't specify an enum string for it.
+ context->contextDescription.fpMessage(FFX_FSR2_MESSAGE_TYPE_WARNING, L"renderSize is greater than context maxRenderSize");
+ }
+ if ((params->renderSize.width == 0) ||
+ (params->renderSize.height == 0))
+ {
+ context->contextDescription.fpMessage(FFX_FSR2_MESSAGE_TYPE_WARNING, L"renderSize contains zero dimension");
+ }
+
+ if (params->sharpness < 0.0f || params->sharpness > 1.0f)
+ {
+ context->contextDescription.fpMessage(FFX_FSR2_MESSAGE_TYPE_WARNING, L"sharpness contains value outside of expected range [0.0, 1.0]");
+ }
+
+ if (params->frameTimeDelta < 1.0f)
+ {
+ context->contextDescription.fpMessage(FFX_FSR2_MESSAGE_TYPE_WARNING, L"frameTimeDelta is less than 1.0f - this value should be milliseconds (~16.6f for 60fps)");
+ }
+
+ if (params->preExposure == 0.0f)
+ {
+ context->contextDescription.fpMessage(FFX_FSR2_MESSAGE_TYPE_ERROR, L"preExposure provided as 0.0f which is invalid");
+ L"FFX_FSR2_ENABLE_DEPTH_INFINITE and FFX_FSR2_ENABLE_DEPTH_INVERTED present, cameraFar value is very low which may result in depth separation artefacting");
+ L"FFX_FSR2_ENABLE_DEPTH_INFINITE and FFX_FSR2_ENABLE_DEPTH_INVERTED present, cameraNear value is very low which may result in depth separation artefacting");
+ }
+ }
+
+ if (params->cameraFovAngleVertical <= 0.0f)
+ {
+ context->contextDescription.fpMessage(FFX_FSR2_MESSAGE_TYPE_ERROR, L"cameraFovAngleVertical is 0.0f - this value should be > 0.0f");
+ }
+ if (params->cameraFovAngleVertical > FFX_PI)
+ {
+ context->contextDescription.fpMessage(FFX_FSR2_MESSAGE_TYPE_ERROR, L"cameraFovAngleVertical is greater than 180 degrees/PI");
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+// @defgroup FSR2
+
+#pragma once
+
+// Include the interface for the backend of the FSR2 API.
+#include "ffx_fsr2_interface.h"
+
+/// FidelityFX Super Resolution 2 major version.
+///
+/// @ingroup FSR2
+#define FFX_FSR2_VERSION_MAJOR (2)
+
+/// FidelityFX Super Resolution 2 minor version.
+///
+/// @ingroup FSR2
+#define FFX_FSR2_VERSION_MINOR (2)
+
+/// FidelityFX Super Resolution 2 patch version.
+///
+/// @ingroup FSR2
+#define FFX_FSR2_VERSION_PATCH (1)
+
+/// The size of the context specified in 32bit values.
+///
+/// @ingroup FSR2
+#define FFX_FSR2_CONTEXT_SIZE (16536)
+
+#if defined(__cplusplus)
+extern "C" {
+#endif // #if defined(__cplusplus)
+
+/// An enumeration of all the quality modes supported by FidelityFX Super
+/// Resolution 2 upscaling.
+///
+/// In order to provide a consistent user experience across multiple
+/// applications which implement FSR2. It is strongly recommended that the
+/// following preset scaling factors are made available through your
+/// application's user interface.
+///
+/// If your application does not expose the notion of preset scaling factors
+/// for upscaling algorithms (perhaps instead implementing a fixed ratio which
+/// is immutable) or implementing a more dynamic scaling scheme (such as
+/// dynamic resolution scaling), then there is no need to use these presets.
+///
+/// Please note that <c><i>FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE</i></c> is
+/// an optional mode which may introduce significant quality degradation in the
+/// final image. As such it is recommended that you evaluate the final results
+/// of using this scaling mode before deciding if you should include it in your
+/// application.
+///
+/// @ingroup FSR2
+typedef enum FfxFsr2QualityMode {
+
+ FFX_FSR2_QUALITY_MODE_QUALITY = 1, ///< Perform upscaling with a per-dimension upscaling ratio of 1.5x.
+ FFX_FSR2_QUALITY_MODE_BALANCED = 2, ///< Perform upscaling with a per-dimension upscaling ratio of 1.7x.
+ FFX_FSR2_QUALITY_MODE_PERFORMANCE = 3, ///< Perform upscaling with a per-dimension upscaling ratio of 2.0x.
+ FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE = 4 ///< Perform upscaling with a per-dimension upscaling ratio of 3.0x.
+} FfxFsr2QualityMode;
+
+/// An enumeration of bit flags used when creating a
+/// <c><i>FfxFsr2Context</i></c>. See <c><i>FfxFsr2ContextDescription</i></c>.
+///
+/// @ingroup FSR2
+typedef enum FfxFsr2InitializationFlagBits {
+
+ FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE = (1<<0), ///< A bit indicating if the input color data provided is using a high-dynamic range.
+ FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS = (1<<1), ///< A bit indicating if the motion vectors are rendered at display resolution.
+ FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION = (1<<2), ///< A bit indicating that the motion vectors have the jittering pattern applied to them.
+ FFX_FSR2_ENABLE_DEPTH_INVERTED = (1<<3), ///< A bit indicating that the input depth buffer data provided is inverted [1..0].
+ FFX_FSR2_ENABLE_DEPTH_INFINITE = (1<<4), ///< A bit indicating that the input depth buffer data provided is using an infinite far plane.
+ FFX_FSR2_ENABLE_AUTO_EXPOSURE = (1<<5), ///< A bit indicating if automatic exposure should be applied to input color data.
+ FFX_FSR2_ENABLE_DYNAMIC_RESOLUTION = (1<<6), ///< A bit indicating that the application uses dynamic resolution scaling.
+ FFX_FSR2_ENABLE_TEXTURE1D_USAGE = (1<<7), ///< A bit indicating that the backend should use 1D textures.
+ FFX_FSR2_ENABLE_DEBUG_CHECKING = (1<<8), ///< A bit indicating that the runtime should check some API values and report issues.
+} FfxFsr2InitializationFlagBits;
+
+/// A structure encapsulating the parameters required to initialize FidelityFX
+/// Super Resolution 2 upscaling.
+///
+/// @ingroup FSR2
+typedef struct FfxFsr2ContextDescription {
+
+ uint32_t flags; ///< A collection of <c><i>FfxFsr2InitializationFlagBits</i></c>.
+ FfxDimensions2D maxRenderSize; ///< The maximum size that rendering will be performed at.
+ FfxDimensions2D displaySize; ///< The size of the presentation resolution targeted by the upscaling process.
+ FfxFsr2Interface callbacks; ///< A set of pointers to the backend implementation for FSR 2.0.
+ FfxDevice device; ///< The abstracted device which is passed to some callback functions.
+
+ FfxFsr2Message fpMessage; ///< A pointer to a function that can recieve messages from the runtime.
+} FfxFsr2ContextDescription;
+
+/// A structure encapsulating the parameters for dispatching the various passes
+/// of FidelityFX Super Resolution 2.
+///
+/// @ingroup FSR2
+typedef struct FfxFsr2DispatchDescription {
+
+ FfxCommandList commandList; ///< The <c><i>FfxCommandList</i></c> to record FSR2 rendering commands into.
+ FfxResource color; ///< A <c><i>FfxResource</i></c> containing the color buffer for the current frame (at render resolution).
+ FfxResource depth; ///< A <c><i>FfxResource</i></c> containing 32bit depth values for the current frame (at render resolution).
+ FfxResource motionVectors; ///< A <c><i>FfxResource</i></c> containing 2-dimensional motion vectors (at render resolution if <c><i>FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS</i></c> is not set).
+ FfxResource exposure; ///< A optional <c><i>FfxResource</i></c> containing a 1x1 exposure value.
+ FfxResource reactive; ///< A optional <c><i>FfxResource</i></c> containing alpha value of reactive objects in the scene.
+ FfxResource transparencyAndComposition; ///< A optional <c><i>FfxResource</i></c> containing alpha value of special objects in the scene.
+ FfxResource output; ///< A <c><i>FfxResource</i></c> containing the output color buffer for the current frame (at presentation resolution).
+ FfxFloatCoords2D jitterOffset; ///< The subpixel jitter offset applied to the camera.
+ FfxFloatCoords2D motionVectorScale; ///< The scale factor to apply to motion vectors.
+ FfxDimensions2D renderSize; ///< The resolution that was used for rendering the input resources.
+ bool enableSharpening; ///< Enable an additional sharpening pass.
+ float sharpness; ///< The sharpness value between 0 and 1, where 0 is no additional sharpness and 1 is maximum additional sharpness.
+ float frameTimeDelta; ///< The time elapsed since the last frame (expressed in milliseconds).
+ float preExposure; ///< The pre exposure value (must be > 0.0f)
+ bool reset; ///< A boolean value which when set to true, indicates the camera has moved discontinuously.
+ float cameraNear; ///< The distance to the near plane of the camera.
+ float cameraFar; ///< The distance to the far plane of the camera.
+ float cameraFovAngleVertical; ///< The camera angle field of view in the vertical direction (expressed in radians).
+ float viewSpaceToMetersFactor; ///< The scale factor to convert view space units to meters
+ FfxCommandList commandList; ///< The <c><i>FfxCommandList</i></c> to record FSR2 rendering commands into.
+ FfxResource colorOpaqueOnly; ///< A <c><i>FfxResource</i></c> containing the opaque only color buffer for the current frame (at render resolution).
+ FfxResource colorPreUpscale; ///< A <c><i>FfxResource</i></c> containing the opaque+translucent color buffer for the current frame (at render resolution).
+ FfxResource outReactive; ///< A <c><i>FfxResource</i></c> containing the surface to generate the reactive mask into.
+ FfxDimensions2D renderSize; ///< The resolution that was used for rendering the input resources.
+ float scale; ///< A value to scale the output
+ float cutoffThreshold; ///< A threshold value to generate a binary reactive mask
+ float binaryValue; ///< A value to set for the binary reactive mask
+ uint32_t flags; ///< Flags to determine how to generate the reactive mask
+} FfxFsr2GenerateReactiveDescription;
+
+/// A structure encapsulating the FidelityFX Super Resolution 2 context.
+///
+/// This sets up an object which contains all persistent internal data and
+/// resources that are required by FSR2.
+///
+/// The <c><i>FfxFsr2Context</i></c> object should have a lifetime matching
+/// your use of FSR2. Before destroying the FSR2 context care should be taken
+/// to ensure the GPU is not accessing the resources created or used by FSR2.
+/// It is therefore recommended that the GPU is idle before destroying the
+/// FSR2 context.
+///
+/// @ingroup FSR2
+typedef struct FfxFsr2Context {
+
+ uint32_t data[FFX_FSR2_CONTEXT_SIZE]; ///< An opaque set of <c>uint32_t</c> which contain the data for the context.
+} FfxFsr2Context;
+
+/// Create a FidelityFX Super Resolution 2 context from the parameters
+/// programmed to the <c><i>FfxFsr2CreateParams</i></c> structure.
+///
+/// The context structure is the main object used to interact with the FSR2
+/// API, and is responsible for the management of the internal resources used
+/// by the FSR2 algorithm. When this API is called, multiple calls will be
+/// made via the pointers contained in the <c><i>callbacks</i></c> structure.
+/// These callbacks will attempt to retreive the device capabilities, and
+/// create the internal resources, and pipelines required by FSR2's
+/// frame-to-frame function. Depending on the precise configuration used when
+/// creating the <c><i>FfxFsr2Context</i></c> a different set of resources and
+/// pipelines might be requested via the callback functions.
+///
+/// The flags included in the <c><i>flags</i></c> field of
+/// <c><i>FfxFsr2Context</i></c> how match the configuration of your
+/// application as well as the intended use of FSR2. It is important that these
+/// flags are set correctly (as well as a correct programmed
+/// <c><i>FfxFsr2DispatchDescription</i></c>) to ensure correct operation. It is
+/// recommended to consult the overview documentation for further details on
+/// how FSR2 should be integerated into an application.
+///
+/// When the <c><i>FfxFsr2Context</i></c> is created, you should use the
+/// <c><i>ffxFsr2ContextDispatch</i></c> function each frame where FSR2
+/// upscaling should be applied. See the documentation of
+/// <c><i>ffxFsr2ContextDispatch</i></c> for more details.
+///
+/// The <c><i>FfxFsr2Context</i></c> should be destroyed when use of it is
+/// completed, typically when an application is unloaded or FSR2 upscaling is
+/// disabled by a user. To destroy the FSR2 context you should call
+/// <c><i>ffxFsr2ContextDestroy</i></c>.
+///
+/// @param [out] context A pointer to a <c><i>FfxFsr2Context</i></c> structure to populate.
+/// @param [in] contextDescription A pointer to a <c><i>FfxFsr2ContextDescription</i></c> structure.
+///
+/// @retval
+/// FFX_OK The operation completed successfully.
+/// @retval
+/// FFX_ERROR_CODE_NULL_POINTER The operation failed because either <c><i>context</i></c> or <c><i>contextDescription</i></c> was <c><i>NULL</i></c>.
+/// @retval
+/// FFX_ERROR_INCOMPLETE_INTERFACE The operation failed because the <c><i>FfxFsr2ContextDescription.callbacks</i></c> was not fully specified.
+/// @retval
+/// FFX_ERROR_BACKEND_API_ERROR The operation failed because of an error returned from the backend.
+/// Dispatch the various passes that constitute FidelityFX Super Resolution 2.
+///
+/// FSR2 is a composite effect, meaning that it is compromised of multiple
+/// constituent passes (implemented as one or more clears, copies and compute
+/// dispatches). The <c><i>ffxFsr2ContextDispatch</i></c> function is the
+/// function which (via the use of the functions contained in the
+/// <c><i>callbacks</i></c> field of the <c><i>FfxFsr2Context</i></c>
+/// structure) utlimately generates the sequence of graphics API calls required
+/// each frame.
+///
+/// As with the creation of the <c><i>FfxFsr2Context</i></c> correctly
+/// programming the <c><i>FfxFsr2DispatchDescription</i></c> is key to ensuring
+/// the correct operation of FSR2. It is particularly important to ensure that
+/// camera jitter is correctly applied to your application's projection matrix
+/// (or camera origin for raytraced applications). FSR2 provides the
+/// <c><i>ffxFsr2GetJitterPhaseCount</i></c> and
+/// <c><i>ffxFsr2GetJitterOffset</i></c> entry points to help applications
+/// correctly compute the camera jitter. Whatever jitter pattern is used by the
+/// application it should be correctly programmed to the
+/// <c><i>jitterOffset</i></c> field of the <c><i>dispatchDescription</i></c>
+/// structure. For more guidance on camera jitter please consult the
+/// documentation for <c><i>ffxFsr2GetJitterOffset</i></c> as well as the
+/// accompanying overview documentation for FSR2.
+///
+/// @param [in] context A pointer to a <c><i>FfxFsr2Context</i></c> structure.
+/// @param [in] dispatchDescription A pointer to a <c><i>FfxFsr2DispatchDescription</i></c> structure.
+///
+/// @retval
+/// FFX_OK The operation completed successfully.
+/// @retval
+/// FFX_ERROR_CODE_NULL_POINTER The operation failed because either <c><i>context</i></c> or <c><i>dispatchDescription</i></c> was <c><i>NULL</i></c>.
+/// @retval
+/// FFX_ERROR_OUT_OF_RANGE The operation failed because <c><i>dispatchDescription.renderSize</i></c> was larger than the maximum render resolution.
+/// @retval
+/// FFX_ERROR_NULL_DEVICE The operation failed because the device inside the context was <c><i>NULL</i></c>.
+/// @retval
+/// FFX_ERROR_BACKEND_API_ERROR The operation failed because of an error returned from the backend.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[8:15] into r.x[0:7] and i.y[8:15] into r.y[0:7] using 2 ops.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[16:23] into r.x[0:7] and i.y[16:23] into r.y[0:7] using 2 ops.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[24:31] into r.x[0:7] and i.y[24:31] into r.y[0:7] using 2 ops.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[8:15] into r.x[0:7] and i.y[8:15] into r.y[0:7] using 2 ops.
+///
+/// Handles signed byte values.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[16:23] into r.x[0:7] and i.y[16:23] into r.y[0:7] using 2 ops.
+///
+/// Handles signed byte values.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[24:31] into r.x[0:7] and i.y[24:31] into r.y[0:7] using 2 ops.
+///
+/// Handles signed byte values.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[8:15] into r.x[0:7] and i.y[8:15] into r.y[0:7] using 2 ops.
+///
+/// Handles signed byte values.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[16:23] into r.x[0:7] and i.y[16:23] into r.y[0:7] using 2 ops.
+///
+/// Handles signed byte values.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+/// Given a FfxUInt32x2 value i and a resulting Float16x2 value r, this function packs i.x[24:31] into r.x[0:7] and i.y[24:31] into r.y[0:7] using 2 ops.
+///
+/// Handles signed byte values.
+///
+/// @param [in] i The FfxUInt32x2 value to be unpacked.
+// Shading change detection mip level setting, value must be in the range [FFX_FSR2_RESOURCE_IDENTIFIER_SCENE_LUMINANCE_MIPMAP_0, FFX_FSR2_RESOURCE_IDENTIFIER_SCENE_LUMINANCE_MIPMAP_12]