r.TSR.WaveOps

r.TSR.WaveOps

#Overview

name: r.TSR.WaveOps

This variable is created as a Console Variable (cvar).

It is referenced in 3 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.TSR.WaveOps is to control whether wave operations are used in the shading rejection heuristics to speed up convolutions in Temporal Super Resolution (TSR).

This setting variable is primarily used in the rendering system, specifically in the Temporal Super Resolution module of Unreal Engine 5. The Renderer module relies on this setting variable, as evidenced by its location in the TemporalSuperResolution.cpp file.

The value of this variable is set using a console variable (CVarTSRWaveOps) with a default value of 1, meaning it’s enabled by default. It can be changed at runtime through the console or configuration files.

The associated variable CVarTSRWaveOps directly interacts with r.TSR.WaveOps, as they share the same value. This console variable is used to retrieve the setting’s value in the code.

Developers must be aware of several important aspects when using this variable:

  1. The optimization can be challenging for shader compilers and may cause corruption or quality loss due to compiler bugs.
  2. It’s currently disabled on SPIRV platforms (mainly Vulkan and Metal) due to extremely long compilation times (5+ minutes) in the SPIRV backend of DXC, which can significantly impact editor startup times.
  3. The actual use of wave operations depends on hardware support and other runtime conditions.

Best practices when using this variable include:

  1. Test thoroughly on target platforms to ensure shader compilation works correctly and doesn’t introduce visual artifacts.
  2. Be cautious when enabling this on SPIRV platforms, considering the potential impact on compilation times.
  3. Consider providing user-facing options to toggle this setting, allowing end-users to disable it if they experience issues.
  4. Monitor performance impacts and visual quality when enabling or disabling this feature.

Regarding the associated variable CVarTSRWaveOps:

The purpose of CVarTSRWaveOps is to provide a runtime-configurable way to control the r.TSR.WaveOps setting. It’s an instance of TAutoConsoleVariable, which allows for easy integration with Unreal Engine’s console variable system.

This console variable is used in the Renderer module, specifically in the Temporal Super Resolution implementation. Its value is checked in the AddTemporalSuperResolutionPasses function to determine whether to use wave operations.

The value of CVarTSRWaveOps is set when the console variable is initialized, but it can be changed at runtime through the console or configuration files.

Other variables that interact with CVarTSRWaveOps include GRHISupportsWaveOperations and CVarTSRWaveSize. These are used in conjunction to determine if and how wave operations should be used.

Developers should be aware that changing this variable at runtime will affect the TSR implementation’s behavior and potentially impact performance and visual quality.

Best practices for using CVarTSRWaveOps include:

  1. Providing clear documentation on its effects and potential performance implications.
  2. Implementing appropriate error handling or fallback mechanisms if wave operations are not supported on the target hardware.
  3. Considering exposing this setting in user-facing graphics options for advanced users.
  4. Thoroughly testing the impact of enabling/disabling this setting across various hardware configurations.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/TemporalSuperResolution.cpp:64

Scope (from outer to inner):

file
namespace    anonymous

Source code excerpt:


TAutoConsoleVariable<int32> CVarTSRWaveOps(
	TEXT("r.TSR.WaveOps"), 1,
	TEXT("Whether to use wave ops in the shading rejection heuristics to speeds up convolutions.\n")
	TEXT("\n")
	TEXT("The shading rejection heuristic optimisation can be particularily hard for shader compiler and hit bug in them causing corruption/quality loss.\n")
	TEXT("\n")
	TEXT("Note this optimisation is currently disabled on SPIRV platforms (mainly Vulkan and Metal) due to 5min+ compilation times in SPIRV ")
	TEXT("backend of DXC which is not great for editor startup."),

#Associated Variable and Callsites

This variable is associated with another variable named CVarTSRWaveOps. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/TemporalSuperResolution.cpp:63

Scope (from outer to inner):

file
namespace    anonymous

Source code excerpt:

	ECVF_Scalability | ECVF_RenderThreadSafe);

TAutoConsoleVariable<int32> CVarTSRWaveOps(
	TEXT("r.TSR.WaveOps"), 1,
	TEXT("Whether to use wave ops in the shading rejection heuristics to speeds up convolutions.\n")
	TEXT("\n")
	TEXT("The shading rejection heuristic optimisation can be particularily hard for shader compiler and hit bug in them causing corruption/quality loss.\n")
	TEXT("\n")
	TEXT("Note this optimisation is currently disabled on SPIRV platforms (mainly Vulkan and Metal) due to 5min+ compilation times in SPIRV ")

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/TemporalSuperResolution.cpp:1270

Scope (from outer to inner):

file
function     FDefaultTemporalUpscaler::FOutputs AddTemporalSuperResolutionPasses

Source code excerpt:

	// Whether to use wave ops optimizations.
	const ERHIFeatureSupport WaveOpsSupport = FTSRShader::SupportsWaveOps(View.GetShaderPlatform());
	const bool bUseWaveOps = (CVarTSRWaveOps.GetValueOnRenderThread() != 0 && GRHISupportsWaveOperations && (WaveOpsSupport == ERHIFeatureSupport::RuntimeDependent || WaveOpsSupport == ERHIFeatureSupport::RuntimeGuaranteed));
	const int32 WaveSizeOverride = bUseWaveOps ? CVarTSRWaveSize.GetValueOnAnyThread() : 0;
	
	// Whether to use 16bit VALU
	const ERHIFeatureSupport VALU16BitSupport = FTSRShader::Supports16BitVALU(View.GetShaderPlatform());
	bool bUse16BitVALU = (CVarTSR16BitVALU.GetValueOnRenderThread() != 0 && GRHIGlobals.SupportsNative16BitOps && VALU16BitSupport == ERHIFeatureSupport::RuntimeDependent) || VALU16BitSupport == ERHIFeatureSupport::RuntimeGuaranteed;