@ -41,9 +41,10 @@ namespace ArmASR
public readonly RenderTexture [ ] DilatedMotionVectors = new RenderTexture [ 2 ] ;
public readonly RenderTexture [ ] LockStatus = new RenderTexture [ 2 ] ;
public readonly RenderTexture [ ] InternalUpscaled = new RenderTexture [ 2 ] ;
public readonly RenderTexture [ ] InternalReactive = new RenderTexture [ 2 ] ;
public readonly RenderTexture [ ] LumaHistory = new RenderTexture [ 2 ] ;
public void Create ( Asr . ContextDescription contextDescription )
public void Create ( in Asr . ContextDescription contextDescription )
{
// Generate the data for the LUT
const int lanczos2LutWidth = 1 2 8 ;
@ -61,6 +62,8 @@ namespace ArmASR
maximumBias [ i ] = MaximumBias [ i ] / 2.0f ;
}
GetFormatRequirements ( contextDescription , out bool isBalancedOrPerformance , out bool preparedInputColorNeedsFp16 , out GraphicsFormat r8Format , out GraphicsFormat r16Format , out GraphicsFormat rg16Format ) ;
// Resource FSR2_LanczosLutData: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
// R16_SNorm textures are not supported by Unity on most platforms, strangely enough. So instead we use R32_SFloat and upload pre-normalized float data.
LanczosLut = new Texture2D ( lanczos2LutWidth , 1 , GraphicsFormat . R32_SFloat , TextureCreationFlags . None ) { name = "ASR_LanczosLutData" } ;
@ -88,14 +91,14 @@ namespace ArmASR
SpdAtomicCounter . Create ( ) ;
// Resource FSR2_AutoExposure: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
AutoExposure = new RenderTexture ( 1 , 1 , 0 , GraphicsFormat . R32G32_SFlo at) { name = "ASR_AutoExposure" , enableRandomWrite = true } ;
AutoExposure = new RenderTexture ( 1 , 1 , 0 , rg16Form at) { name = "ASR_AutoExposure" , enableRandomWrite = true } ;
AutoExposure . Create ( ) ;
// Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
// This is a rather special case: it's an aliasable resource, but because we require a mipmap chain and bind specific mip levels per shader, we can't easily use temporary RTs for this.
int w = contextDescription . MaxRenderSize . x / 2 , h = contextDescription . MaxRenderSize . y / 2 ;
int mipCount = 1 + Mathf . FloorToInt ( Mathf . Log ( Math . Max ( w , h ) , 2.0f ) ) ;
SceneLuminance = new RenderTexture ( w , h , 0 , G raphicsFormat . R 16_S Fl oat, mipCount ) { name = "ASR_ExposureMips" , enableRandomWrite = true , useMipMap = true , autoGenerateMips = false } ;
SceneLuminance = new RenderTexture ( w , h , 0 , r16Form at , mipCount ) { name = "ASR_ExposureMips" , enableRandomWrite = true , useMipMap = true , autoGenerateMips = false } ;
SceneLuminance . Create ( ) ;
// Resources FSR2_InternalDilatedVelocity1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE
@ -105,18 +108,29 @@ namespace ArmASR
CreateDoubleBufferedResource ( LockStatus , "ASR_LockStatus" , contextDescription . DisplaySize , GraphicsFormat . R16G16_SFloat ) ;
// Resources FSR2_InternalUpscaled1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource ( InternalUpscaled , "ASR_InternalUpscaled" , contextDescription . DisplaySize , GraphicsFormat . R16G16B16A16_SFloat ) ;
// Resources FSR2_LumaHistory1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource ( LumaHistory , "ASR_LumaHistory" , contextDescription . DisplaySize , GraphicsFormat . R8G8B8A8_UNorm ) ;
CreateDoubleBufferedResource ( InternalUpscaled , "ASR_InternalUpscaled" , contextDescription . DisplaySize , ! isBalancedOrPerformance ? GraphicsFormat . R16G16B16A16_SFloat : GraphicsFormat . B10G11R11_UFloatPack32 ) ;
// Additional textures used by either balanced or performance presets
if ( isBalancedOrPerformance )
{
// Resources FSR2_InternalReactive1/2: FFXM_RESOURCE_USAGE_RENDERTARGET, FFXM_SURFACE_FORMAT_R8_SNORM, FFXM_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource ( InternalReactive , "ASR_InternalReactive" , contextDescription . DisplaySize , GraphicsFormat . R8_SNorm ) ; // TODO: R8_SNorm *might* be a problem?
}
else // Quality preset specific
{
// Resources FSR2_LumaHistory1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource ( LumaHistory , "ASR_LumaHistory" , contextDescription . DisplaySize , GraphicsFormat . R8G8B8A8_UNorm ) ;
}
}
// Set up shared aliasable resources, i.e. temporary render textures
// These do not need to persist between frames, but they do need to be available between passes
public static void CreateAliasableResources ( CommandBuffer commandBuffer , Asr . ContextDescription contextDescription , Asr . DispatchDescription dispatchParams )
public static void CreateAliasableResources ( CommandBuffer commandBuffer , in Asr . ContextDescription contextDescription , in Asr . DispatchDescription dispatchParams )
{
Vector2Int displaySize = contextDescription . DisplaySize ;
Vector2Int maxRenderSize = contextDescription . MaxRenderSize ;
GetFormatRequirements ( contextDescription , out bool isBalancedOrPerformance , out bool preparedInputColorNeedsFp16 , out GraphicsFormat r8Format , out GraphicsFormat r16Format , out GraphicsFormat rg16Format ) ;
// FSR2_ReconstructedPrevNearestDepth: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer . GetTemporaryRT ( AsrShaderIDs . UavReconstructedPrevNearestDepth , maxRenderSize . x , maxRenderSize . y , 0 , default , GraphicsFormat . R32_UInt , 1 , true ) ;
@ -131,10 +145,26 @@ namespace ArmASR
commandBuffer . GetTemporaryRT ( AsrShaderIDs . UavDilatedReactiveMasks , maxRenderSize . x , maxRenderSize . y , 0 , default , GraphicsFormat . R8G8_UNorm , 1 , true ) ;
// FSR2_PreparedInputColor: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer . GetTemporaryRT ( AsrShaderIDs . UavPreparedInputColor , maxRenderSize . x , maxRenderSize . y , 0 , default , GraphicsFormat . R16G16B16A16_SFloat , 1 , true ) ;
commandBuffer . GetTemporaryRT ( AsrShaderIDs . UavPreparedInputColor , maxRenderSize . x , maxRenderSize . y , 0 , default , preparedInputColorNeedsFp16 ? GraphicsFormat . R16G16B16A16_SFloat : GraphicsFormat . R8G8B8A8_UNorm , 1 , true ) ;
// FSR2_NewLocks: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer . GetTemporaryRT ( AsrShaderIDs . UavNewLocks , displaySize . x , displaySize . y , 0 , default , GraphicsFormat . R8_UNorm , 1 , true ) ;
commandBuffer . GetTemporaryRT ( AsrShaderIDs . UavNewLocks , displaySize . x , displaySize . y , 0 , default , r8Format , 1 , true ) ;
}
private static void GetFormatRequirements ( in Asr . ContextDescription contextDescription ,
out bool isBalancedOrPerformance , out bool preparedInputColorNeedsFP16 ,
out GraphicsFormat r8Format , out GraphicsFormat r16Format , out GraphicsFormat rg16Format )
{
bool applyPerfModeOptimizations = contextDescription . Variant = = Asr . Variant . Performance ;
bool applyBalancedModeOptimizations = contextDescription . Variant = = Asr . Variant . Balanced ;
isBalancedOrPerformance = applyBalancedModeOptimizations | | applyPerfModeOptimizations ;
preparedInputColorNeedsFP16 = ! applyPerfModeOptimizations ;
// OpenGLES 3.2 specific: We need to work around some GLES limitations for some resources.
bool isOpenGLES = SystemInfo . graphicsDeviceType = = GraphicsDeviceType . OpenGLES3 ;
r8Format = isOpenGLES ? GraphicsFormat . R32_SFloat : GraphicsFormat . R8_UNorm ;
r16Format = isOpenGLES ? GraphicsFormat . R32_SFloat : GraphicsFormat . R16_SFloat ;
rg16Format = isOpenGLES ? GraphicsFormat . R16G16B16A16_SFloat : GraphicsFormat . R16G16_SFloat ;
}
public static void DestroyAliasableResources ( CommandBuffer commandBuffer )
@ -160,6 +190,7 @@ namespace ArmASR
public void Destroy ( )
{
DestroyResource ( LumaHistory ) ;
DestroyResource ( InternalReactive ) ;
DestroyResource ( InternalUpscaled ) ;
DestroyResource ( LockStatus ) ;
DestroyResource ( DilatedMotionVectors ) ;