Refactoring
This commit is contained in:
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TpsData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Name> FidelityFX-FSR </Name>
|
||||
<Location> //UE5/Main/Engine/Shaders/Private/Mobile/FSR <Location>
|
||||
<Function> The implementation here is HLSL shader source code that will be distributed to the general public with all versions of Unreal Engine (Github., Epic Games Launcher, Perforce) in the Engine/Shaders folder. All of our Unreal-engine products such as Fortnite will also ship a compiled version of this code.It's neither statically or dynamically linked, because it's not CPU code, it's shader code that</Function>
|
||||
<Eula> https://github.com/GPUOpen-Effects/FidelityFX-FSR/blob/master/license.txt </Eula>
|
||||
<RedistributeTo>
|
||||
<EndUserGroup>Licensees</EndUserGroup>
|
||||
<EndUserGroup>Git</EndUserGroup>
|
||||
<EndUserGroup>P4</EndUserGroup>
|
||||
</RedistributeTo>
|
||||
<LicenseFolder></LicenseFolder>
|
||||
</TpsData>
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"FileVersion": 1,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "Mobile FSR",
|
||||
"Description": "Mobile FSR 1.0",
|
||||
"Category": "Rendering",
|
||||
"CreatedBy": "Epic Games, Inc.",
|
||||
"CreatedByURL": "https://epicgames.com",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"EnabledByDefault": false,
|
||||
"CanContainContent": true,
|
||||
"IsBetaVersion": false,
|
||||
"Installed": false,
|
||||
"SupportedTargetPlatforms": [
|
||||
"IOS",
|
||||
"Android"
|
||||
],
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "MobileFSR",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "PostConfigInit"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// 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.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// !!!
|
||||
// FidelityFX Super Resolution - Common
|
||||
// This header should be included after ffx_a.ush
|
||||
// !!!
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// EOTF Conversions
|
||||
//
|
||||
// =====================================================================================
|
||||
// FSR output device definitions : matching EFSR_OutputDevice enum in PostProcessFSR.cpp
|
||||
#define FSR_SRGB 0
|
||||
#define FSR_LINEAR 1
|
||||
#define FSR_ST2084 2
|
||||
#define FSR_scRGB 3
|
||||
|
||||
#define MAX_ODT_NITS_ENUM 0
|
||||
#define CONVERT_TO_OUTPUT_DEVICE 0
|
||||
|
||||
#include "/Engine/Private/ACES/ACESCommon.ush"
|
||||
#include "/Engine/Private/GammaCorrectionCommon.ush"
|
||||
|
||||
float4 LinearToGamma2(float4 Color) { return sqrt(Color); }
|
||||
float3 LinearToGamma2(float3 Color) { return sqrt(Color); }
|
||||
float2 LinearToGamma2(float2 Color) { return sqrt(Color); }
|
||||
float LinearToGamma2(float Color) { return sqrt(Color); }
|
||||
|
||||
float4 Gamma2ToLinear(float4 Color) { return Color * Color; }
|
||||
float3 Gamma2ToLinear(float3 Color) { return Color * Color; }
|
||||
float2 Gamma2ToLinear(float2 Color) { return Color * Color; }
|
||||
float Gamma2ToLinear(float Color) { return Color * Color; }
|
||||
|
||||
#if ENABLE_FP16
|
||||
AH4 LinearToGamma2(AH4 Color) { return sqrt(Color); }
|
||||
AH3 LinearToGamma2(AH3 Color) { return sqrt(Color); }
|
||||
AH2 LinearToGamma2(AH2 Color) { return sqrt(Color); }
|
||||
AH1 LinearToGamma2(AH1 Color) { return sqrt(Color); }
|
||||
|
||||
AH4 Gamma2ToLinear(AH4 Color) { return Color * Color; }
|
||||
AH3 Gamma2ToLinear(AH3 Color) { return Color * Color; }
|
||||
AH2 Gamma2ToLinear(AH2 Color) { return Color * Color; }
|
||||
AH1 Gamma2ToLinear(AH1 Color) { return Color * Color; }
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
// only float3 ST2084ToLinear() is defined in GammaCorrectionCommon.ush
|
||||
float ST2084ToLinear_F(float pq)
|
||||
{
|
||||
const float m1 = 0.1593017578125; // = 2610. / 4096. * .25;
|
||||
const float m2 = 78.84375; // = 2523. / 4096. * 128;
|
||||
const float c1 = 0.8359375; // = 2392. / 4096. * 32 - 2413./4096.*32 + 1;
|
||||
const float c2 = 18.8515625; // = 2413. / 4096. * 32;
|
||||
const float c3 = 18.6875; // = 2392. / 4096. * 32;
|
||||
const float C = 10000.;
|
||||
|
||||
float Np = pow(pq, 1. / m2);
|
||||
float L = Np - c1;
|
||||
L = max(0., L);
|
||||
L = L / (c2 - c3 * Np);
|
||||
L = pow(L, 1. / m1);
|
||||
float P = L * C;
|
||||
|
||||
return P;
|
||||
}
|
||||
float ST2084ToGamma2(float pq) { return LinearToGamma2(ST2084ToLinear_F(pq)); }
|
||||
float2 ST2084ToGamma2(float2 pq) { return LinearToGamma2(float2(ST2084ToLinear_F(pq.r), ST2084ToLinear_F(pq.g))); }
|
||||
float3 ST2084ToGamma2(float3 pq) { return LinearToGamma2(ST2084ToLinear(pq)); }
|
||||
float4 ST2084ToGamma2(float4 pq) { return LinearToGamma2(float4(ST2084ToLinear(pq.rgb), ST2084ToLinear_F(pq.a))); }
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
// Either 1000 or 2000 depending on UE4 Tonemapper enum,
|
||||
// should be provided by the engine
|
||||
#if MAX_ODT_NITS_ENUM == 1
|
||||
#define HDR_MAX_ODT_NITS 2000
|
||||
#else
|
||||
#define HDR_MAX_ODT_NITS 1000
|
||||
#endif
|
||||
|
||||
#define HDR_MAX_NITS 10000
|
||||
#define HDR_MAX_NITS_INV 0.0001f
|
||||
|
||||
// matches white point in ST2084ToScRGB()
|
||||
#define HDR_WHITE_POINT 80.0f
|
||||
|
||||
float3 Gamma2ToScRGB(float3 Color)
|
||||
{
|
||||
const float3x3 Rec2020_2_sRGB = mul(XYZ_2_sRGB_MAT, Rec2020_2_XYZ_MAT);
|
||||
const float MaxODTNits = HDR_MAX_ODT_NITS;
|
||||
const float scRGBScale = MaxODTNits / HDR_WHITE_POINT;
|
||||
|
||||
// Gamma2 -> Linear encoding
|
||||
float3 LinearColor_Rec2020 = Gamma2ToLinear(Color);
|
||||
|
||||
// Rec2020 -> sRGB primaries
|
||||
float3 LinearColor_sRGB = mul(Rec2020_2_sRGB, LinearColor_Rec2020);
|
||||
|
||||
// Linear_sRGB -> scRGB
|
||||
return LinearColor_sRGB * scRGBScale;
|
||||
}
|
||||
|
||||
float3 scRGBToGamma2(float3 Color_scRGB)
|
||||
{
|
||||
const float3x3 sRGB_2_Rec2020 = mul(XYZ_2_Rec2020_MAT, sRGB_2_XYZ_MAT);
|
||||
const float MaxODTNits = HDR_MAX_ODT_NITS;
|
||||
const float scRGBScale = MaxODTNits / HDR_WHITE_POINT;
|
||||
const float scRGBScaleInv = HDR_WHITE_POINT / MaxODTNits;
|
||||
|
||||
// normalize to [0-1]
|
||||
Color_scRGB *= scRGBScaleInv;
|
||||
|
||||
// convert primaries sRGB -> Rec2020
|
||||
float3 Color_Rec2020 = mul(sRGB_2_Rec2020, Color_scRGB);
|
||||
|
||||
// clamp negatives
|
||||
Color_Rec2020 = max(Color_Rec2020, 0);
|
||||
|
||||
// Gamma2-encode
|
||||
return LinearToGamma2(Color_Rec2020);
|
||||
}
|
||||
|
||||
float3 LinearToScRGB(float3 LinearColor_Rec2020)
|
||||
{
|
||||
const float3x3 Rec2020_2_sRGB = mul(XYZ_2_sRGB_MAT, Rec2020_2_XYZ_MAT);
|
||||
const float MaxODTNits = HDR_MAX_ODT_NITS;
|
||||
const float scRGBScale = MaxODTNits / HDR_WHITE_POINT;
|
||||
|
||||
// Rec2020 -> sRGB primaries
|
||||
float3 LinearColor_sRGB = mul(Rec2020_2_sRGB, LinearColor_Rec2020);
|
||||
|
||||
// Linear_sRGB -> scRGB
|
||||
return LinearColor_sRGB * scRGBScale;
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// 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.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "/Engine/Private/Common.ush"
|
||||
#include "/Engine/Private/ScreenPass.ush"
|
||||
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// SHADER RESOURCES
|
||||
//
|
||||
// =====================================================================================
|
||||
uint4 Const0;
|
||||
uint4 Const1;
|
||||
uint4 Const2;
|
||||
uint4 Const3;
|
||||
|
||||
SamplerState samLinearClamp;
|
||||
|
||||
// UE4 GrainIntensity
|
||||
float4 GrainRandomFull; // zw:unused
|
||||
float4 GrainScaleBiasJitter; // x:Scale y:Bias z:Jitter
|
||||
|
||||
float2 VPColor_ExtentInverse;
|
||||
float2 VPColor_ViewportMin;
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// FIDELITYFX SETUP
|
||||
//
|
||||
// =====================================================================================
|
||||
#define A_GPU 1
|
||||
#define A_HLSL 1
|
||||
|
||||
// Note: Input is expected to be in Gamma2-encoding.
|
||||
// LDR: This is already the case.
|
||||
// HDR: A ColorConversionCS runs before FSR to provide Gamma2 input to FSR passes
|
||||
#if ENABLE_FP16
|
||||
#define A_HALF
|
||||
#include "ffx_a.ush"
|
||||
Texture2D<AH4> InputTexture;
|
||||
RWTexture2D<AH4> OutputTexture;
|
||||
#define FSR_EASU_H 1
|
||||
AH4 FsrEasuRH(AF2 p) { AH4 res = InputTexture.GatherRed (samLinearClamp, p, ASU2(0, 0)); return res; }
|
||||
AH4 FsrEasuGH(AF2 p) { AH4 res = InputTexture.GatherGreen(samLinearClamp, p, ASU2(0, 0)); return res; }
|
||||
AH4 FsrEasuBH(AF2 p) { AH4 res = InputTexture.GatherBlue (samLinearClamp, p, ASU2(0, 0)); return res; }
|
||||
AH4 FsrEasuAH(AF2 p) { AH4 res = InputTexture.GatherAlpha(samLinearClamp, p, ASU2(0, 0)); return res; }
|
||||
AH4 FsrEasuRHO(AF2 p, ASW2 o) { AH4 res = InputTexture.GatherRed (samLinearClamp, p, o); return res; }
|
||||
AH4 FsrEasuGHO(AF2 p, ASW2 o) { AH4 res = InputTexture.GatherGreen(samLinearClamp, p, o); return res; }
|
||||
AH4 FsrEasuBHO(AF2 p, ASW2 o) { AH4 res = InputTexture.GatherBlue (samLinearClamp, p, o); return res; }
|
||||
AH4 FsrEasuAHO(AF2 p, ASW2 o) { AH4 res = InputTexture.GatherAlpha(samLinearClamp, p, o); return res; }
|
||||
AH4 FsrEasuSampleH(AF2 p) { AH4 res = InputTexture.SampleLevel(samLinearClamp, p, 0); return res; }
|
||||
#else
|
||||
#include "ffx_a.ush"
|
||||
Texture2D InputTexture;
|
||||
RWTexture2D<float4> OutputTexture;
|
||||
#define FSR_EASU_F 1
|
||||
AF4 FsrEasuRF(AF2 p) { AF4 res = InputTexture.GatherRed (samLinearClamp, p, ASU2(0, 0)); return res; }
|
||||
AF4 FsrEasuGF(AF2 p) { AF4 res = InputTexture.GatherGreen(samLinearClamp, p, ASU2(0, 0)); return res; }
|
||||
AF4 FsrEasuBF(AF2 p) { AF4 res = InputTexture.GatherBlue (samLinearClamp, p, ASU2(0, 0)); return res; }
|
||||
AF4 FsrEasuAF(AF2 p) { AF4 res = InputTexture.GatherAlpha(samLinearClamp, p, ASU2(0, 0)); return res; }
|
||||
#endif
|
||||
|
||||
// should be included after ffx_a.ush, defines FSR_OUTPUTDEVICE
|
||||
#include "PostProcessMobileFFX_Common.ush"
|
||||
|
||||
#include "ffx_fsr1.ush"
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// FIDELITYFX SUPER RESOLUTION
|
||||
//
|
||||
// =====================================================================================
|
||||
|
||||
#if ENABLE_FP16
|
||||
AH4 FidelityFXSuperResolution(AU2 gxy)
|
||||
#else
|
||||
AF4 FidelityFXSuperResolution(AU2 gxy)
|
||||
#endif
|
||||
{
|
||||
|
||||
//
|
||||
// FSR / EASU()
|
||||
//
|
||||
#if ENABLE_FP16
|
||||
AH4 Gamma2Color = AH4(0,0,0,0);
|
||||
#if ES3_1_PROFILE
|
||||
FsrEasuL(Gamma2Color, gxy, Const0, Const1, Const2, Const3);
|
||||
#else
|
||||
FsrEasuH(Gamma2Color, gxy, Const0, Const1, Const2, Const3);
|
||||
#endif
|
||||
#else
|
||||
AF4 Gamma2Color = AF4(0,0,0,0);
|
||||
FsrEasuF(Gamma2Color, gxy, Const0, Const1, Const2, Const3);
|
||||
#endif // ENABLE_FP16
|
||||
|
||||
#if !USE_PASSTHROUGH_ALPHA
|
||||
Gamma2Color.a = 1;
|
||||
#endif // !USE_PASSTHROUGH_ALPHA
|
||||
|
||||
return Gamma2Color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// ENTRY POINTS
|
||||
//
|
||||
// =====================================================================================
|
||||
#if COMPUTE_SHADER
|
||||
[numthreads(THREADGROUP_SIZEX, THREADGROUP_SIZEY, THREADGROUP_SIZEZ)]
|
||||
void MainCS(uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID, uint3 Dtid : SV_DispatchThreadID)
|
||||
{
|
||||
// Do remapping of local xy in workgroup for a more PS-like swizzle pattern.
|
||||
// Threadgroup of 64 threads, each working on a cache-friendly 2x2 region (= 16x16 workgroup if 1px/thread assumed)
|
||||
AU2 gxy = ARmp8x8(LocalThreadId.x) + AU2(WorkGroupId.x << 4u, WorkGroupId.y << 4u);
|
||||
|
||||
OutputTexture[gxy + VPColor_ViewportMin] = FidelityFXSuperResolution(gxy);
|
||||
|
||||
gxy.x += 8u;
|
||||
OutputTexture[gxy + VPColor_ViewportMin] = FidelityFXSuperResolution(gxy);
|
||||
|
||||
gxy.y += 8u;
|
||||
OutputTexture[gxy + VPColor_ViewportMin] = FidelityFXSuperResolution(gxy);
|
||||
|
||||
gxy.x -= 8u;
|
||||
OutputTexture[gxy + VPColor_ViewportMin] = FidelityFXSuperResolution(gxy);
|
||||
}
|
||||
#endif // COMPUTE SHADER
|
||||
|
||||
#if ENABLE_FP16
|
||||
void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out AH4 OutColor : SV_Target0)
|
||||
{
|
||||
AU2 gxy = AU2(SvPosition.xy - VPColor_ViewportMin);
|
||||
OutColor = FidelityFXSuperResolution(gxy);
|
||||
}
|
||||
#else
|
||||
void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out float4 OutColor : SV_Target0)
|
||||
{
|
||||
AU2 gxy = AU2(SvPosition.xy - VPColor_ViewportMin);
|
||||
OutColor = FidelityFXSuperResolution(gxy);
|
||||
}
|
||||
#endif
|
||||
@@ -1,190 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// 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.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// FidelityFX Super Resolution - Robust Contrast Adaptive Sharpening
|
||||
|
||||
#include "/Engine/Private/Common.ush"
|
||||
#include "/Engine/Private/ScreenPass.ush"
|
||||
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// SHADER RESOURCES
|
||||
//
|
||||
// =====================================================================================
|
||||
|
||||
// RCAS params
|
||||
uint4 Const0;
|
||||
float2 VPColor_ExtentInverse;
|
||||
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// FIDELITYFX SETUP
|
||||
//
|
||||
// =====================================================================================
|
||||
#define A_HLSL 1
|
||||
#define A_GPU 1
|
||||
|
||||
#if USE_RCAS_DENOISE
|
||||
#define FSR_RCAS_DENOISE 1
|
||||
#endif
|
||||
|
||||
#if USE_PASSTHROUGH_ALPHA
|
||||
#define FSR_RCAS_PASSTHROUGH_ALPHA 1
|
||||
#endif
|
||||
|
||||
#if ENABLE_FP16
|
||||
#define FSR_RCAS_H 1
|
||||
#define FSR_RCAS_HX2 1
|
||||
#define A_HALF 1
|
||||
#include "ffx_a.ush"
|
||||
|
||||
Texture2D<AH4> InputTexture;
|
||||
RWTexture2D<AH4> OutputTexture;
|
||||
AH4 FsrRcasLoadH(min16int2 p) {return InputTexture.Load(int3(p, 0));}
|
||||
AH4 FsrRcasLoadHx2(min16int2 p){return InputTexture.Load(int3(p, 0));}
|
||||
#else
|
||||
#define FSR_RCAS_F 1
|
||||
#include "ffx_a.ush"
|
||||
|
||||
Texture2D InputTexture;
|
||||
RWTexture2D<float4> OutputTexture;
|
||||
AF4 FsrRcasLoadF(int2 p){return InputTexture.Load(int3(p, 0));}
|
||||
#endif
|
||||
|
||||
// should be included after ffx_a.ush, defines FSR_OUTPUTDEVICE
|
||||
#include "PostProcessMobileFFX_Common.ush"
|
||||
|
||||
|
||||
// Note: Input is expected to be in Gamma2-encoding.
|
||||
// LDR: This is already the case.
|
||||
// HDR: A ColorConversionCS runs before FSR to provide Gamma2 input to FSR passes
|
||||
#if ENABLE_FP16
|
||||
void FsrRcasInputH (inout AH1 r,inout AH1 g,inout AH1 b){} // RCAS is done in perceptual space (sRGB~Gamma2)
|
||||
void FsrRcasInputHx2(inout AH2 r,inout AH2 g,inout AH2 b){} // Hence, no need to modify r/g/b
|
||||
#else
|
||||
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b){}
|
||||
#endif
|
||||
|
||||
|
||||
#include "ffx_fsr1.ush"
|
||||
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// RCAS IMPLEMENTATION
|
||||
//
|
||||
// =====================================================================================
|
||||
#if ENABLE_FP16 // half precision floating point
|
||||
AH4 RCASPassCommon(AU2 gxy)
|
||||
#else
|
||||
AF4 RCASPassCommon(AU2 gxy)
|
||||
#endif
|
||||
{
|
||||
//
|
||||
// RCAS()
|
||||
//
|
||||
#if ENABLE_FP16 // half precision floating point
|
||||
|
||||
#if USE_PASSTHROUGH_ALPHA
|
||||
|
||||
AH4 Gamma2Color = AH4(0, 0, 0, 0);
|
||||
FsrRcasH(Gamma2Color.r, Gamma2Color.g, Gamma2Color.b, Gamma2Color.a, gxy, Const0);
|
||||
|
||||
#else
|
||||
|
||||
AH4 Gamma2Color = AH4(0, 0, 0, 1);
|
||||
FsrRcasH(Gamma2Color.r, Gamma2Color.g, Gamma2Color.b, gxy, Const0);
|
||||
|
||||
#endif // USE_PASSTHROUGH_ALPHA
|
||||
|
||||
#else // FP32 - full precision floating point
|
||||
|
||||
#if USE_PASSTHROUGH_ALPHA
|
||||
|
||||
AF4 Gamma2Color = AF4(0, 0, 0, 0);
|
||||
FsrRcasF(Gamma2Color.r, Gamma2Color.g, Gamma2Color.b, Gamma2Color.a, gxy, Const0);
|
||||
|
||||
#else
|
||||
|
||||
AF4 Gamma2Color = AF4(0, 0, 0, 1);
|
||||
FsrRcasF(Gamma2Color.r, Gamma2Color.g, Gamma2Color.b, gxy, Const0);
|
||||
|
||||
#endif // USE_PASSTHROUGH_ALPHA
|
||||
|
||||
#endif // ENABLE_FP16
|
||||
|
||||
return Gamma2Color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =====================================================================================
|
||||
//
|
||||
// ENTRY POINTS
|
||||
//
|
||||
// =====================================================================================
|
||||
#if COMPUTE_SHADER
|
||||
[numthreads(THREADGROUP_SIZEX, THREADGROUP_SIZEY, THREADGROUP_SIZEZ)]
|
||||
void MainCS(uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID, uint3 Dtid : SV_DispatchThreadID)
|
||||
{
|
||||
// Do remapping of local xy in workgroup for a more PS-like swizzle pattern.
|
||||
AU2 gxy = ARmp8x8(LocalThreadId.x) + AU2(WorkGroupId.x << 4u, WorkGroupId.y << 4u);
|
||||
|
||||
#if ENABLE_FP16
|
||||
OutputTexture[gxy] = RCASPassCommon(gxy);
|
||||
|
||||
gxy.x += 8u;
|
||||
OutputTexture[gxy] = RCASPassCommon(gxy);
|
||||
|
||||
gxy.y += 8u;
|
||||
OutputTexture[gxy] = RCASPassCommon(gxy);
|
||||
|
||||
gxy.x -= 8u;
|
||||
OutputTexture[gxy] = RCASPassCommon(gxy);
|
||||
#else
|
||||
OutputTexture[gxy] = RCASPassCommon(gxy);
|
||||
|
||||
gxy.x += 8u;
|
||||
OutputTexture[gxy] = RCASPassCommon(gxy);
|
||||
|
||||
gxy.y += 8u;
|
||||
OutputTexture[gxy] = RCASPassCommon(gxy);
|
||||
|
||||
gxy.x -= 8u;
|
||||
OutputTexture[gxy] = RCASPassCommon(gxy);
|
||||
#endif
|
||||
}
|
||||
#endif // COMPUTE_SHADER
|
||||
|
||||
#if ENABLE_FP16
|
||||
void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out AH4 OutColor : SV_Target0)
|
||||
{
|
||||
AU2 gxy = AU2(SvPosition.xy);
|
||||
OutColor = RCASPassCommon(gxy);
|
||||
}
|
||||
#else
|
||||
void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out float4 OutColor : SV_Target0)
|
||||
{
|
||||
AU2 gxy = AU2(SvPosition.xy);
|
||||
OutColor = RCASPassCommon(gxy);
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,35 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using System.IO;
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class MobileFSR : ModuleRules
|
||||
{
|
||||
public MobileFSR(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
Path.Combine(GetModuleDirectory("Renderer"), "Private"),
|
||||
Path.Combine(GetModuleDirectory("Renderer"), "Internal"),
|
||||
PluginDirectory + "/Shaders/Private",
|
||||
}
|
||||
);
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"Engine",
|
||||
"Projects",
|
||||
"RenderCore",
|
||||
"Renderer",
|
||||
"RHI",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrecompileForTargets = PrecompileTargetsType.Any;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--MobileFSR plugin additions-->
|
||||
<root xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- init section is always evaluated once per architecture -->
|
||||
<init>
|
||||
<log text="MobileFSR init"/>
|
||||
<setBool result="bSupported" value="false"/>
|
||||
<isArch arch="armeabi-v7a">
|
||||
<setBool result="bSupported" value="true"/>
|
||||
</isArch>
|
||||
<isArch arch="arm64-v8a">
|
||||
<setBool result="bSupported" value="true"/>
|
||||
</isArch>
|
||||
</init>
|
||||
</root>
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "MobileFSRModule.h"
|
||||
|
||||
#include "ShaderCore.h"
|
||||
#include "Interfaces/IPluginManager.h"
|
||||
#include "Misc/Paths.h"
|
||||
#include "MobileFSRViewExtension.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "MobileFSR"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogMobileFSR);
|
||||
|
||||
void FMobileFSRModule::StartupModule()
|
||||
{
|
||||
FString PluginShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin(TEXT("MobileFSR"))->GetBaseDir(), TEXT("Shaders"));
|
||||
AddShaderSourceDirectoryMapping(TEXT("/Plugin/MobileFSR"), PluginShaderDir);
|
||||
|
||||
FCoreDelegates::OnPostEngineInit.AddRaw(this, &FMobileFSRModule::OnPostEngineInit);
|
||||
|
||||
UE_LOG(LogMobileFSR, Log, TEXT("Mobile FSR Started"));
|
||||
}
|
||||
|
||||
void FMobileFSRModule::OnPostEngineInit()
|
||||
{
|
||||
ViewExtension = FSceneViewExtensions::NewExtension<FMobileFSRViewExtension>();
|
||||
|
||||
UE_LOG(LogMobileFSR, Log, TEXT("Mobile FSR OnPostEngineInit"));
|
||||
}
|
||||
|
||||
void FMobileFSRModule::ShutdownModule()
|
||||
{
|
||||
ViewExtension = nullptr;
|
||||
FCoreDelegates::OnPostEngineInit.RemoveAll(this);
|
||||
|
||||
UE_LOG(LogMobileFSR, Log, TEXT("Mobile FSR Shutdown"));
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FMobileFSRModule, MobileFSR)
|
||||
@@ -1,462 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "MobileFSRUpscaler.h"
|
||||
#include "DataDrivenShaderPlatformInfo.h"
|
||||
#include "ScenePrivate.h"
|
||||
|
||||
namespace MobileFSRPrivate
|
||||
{
|
||||
bool IsPostProcessingWithAlphaChannelSupported()
|
||||
{
|
||||
static IConsoleVariable* CVarPropagateAlpha = IConsoleManager::Get().FindConsoleVariable(TEXT("r.PostProcessing.PropagateAlpha"));
|
||||
return CVarPropagateAlpha ? CVarPropagateAlpha->GetBool() : false;
|
||||
}
|
||||
}
|
||||
|
||||
#define A_CPU 1
|
||||
// ffx_a.ush will override these definitions
|
||||
#ifdef A_STATIC
|
||||
#undef A_STATIC
|
||||
#endif
|
||||
#ifdef A_RESTRICT
|
||||
#undef A_RESTRICT
|
||||
#endif
|
||||
#include "ffx_a.ush"
|
||||
#include "ffx_fsr1.ush"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! FSR
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// permutation domains
|
||||
class FMobileFSR_UseFP16Dim : SHADER_PERMUTATION_BOOL("ENABLE_FP16");
|
||||
class FMobileFSR_UsePassthroughAlpha : SHADER_PERMUTATION_BOOL("USE_PASSTHROUGH_ALPHA");
|
||||
class FMobileRCAS_DenoiseDim : SHADER_PERMUTATION_BOOL("USE_RCAS_DENOISE");
|
||||
|
||||
BEGIN_SHADER_PARAMETER_STRUCT(FMobileFSRPassParameters, )
|
||||
SHADER_PARAMETER(FUintVector4, Const0)
|
||||
SHADER_PARAMETER(FUintVector4, Const1)
|
||||
SHADER_PARAMETER(FUintVector4, Const2)
|
||||
SHADER_PARAMETER(FUintVector4, Const3)
|
||||
SHADER_PARAMETER(FVector2f, VPColor_ExtentInverse)
|
||||
SHADER_PARAMETER(FVector2f, VPColor_ViewportMin)
|
||||
SHADER_PARAMETER_SAMPLER(SamplerState, samLinearClamp)
|
||||
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture)
|
||||
END_SHADER_PARAMETER_STRUCT()
|
||||
|
||||
BEGIN_SHADER_PARAMETER_STRUCT(FMobileRCASPassParameters, )
|
||||
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture)
|
||||
SHADER_PARAMETER(FUintVector4, Const0)
|
||||
SHADER_PARAMETER(FVector2f, VPColor_ExtentInverse)
|
||||
END_SHADER_PARAMETER_STRUCT()
|
||||
|
||||
static float GMobileFSRCASSharpness = 0.2; // 0.2 stops = 1 / (2^N) ~= 0.87 in linear [0-1] sharpening of CAS
|
||||
static FAutoConsoleVariableRef CVarMobileFSRCASSharpness(
|
||||
TEXT("r.Mobile.FSR.RCAS.Sharpness"),
|
||||
GMobileFSRCASSharpness,
|
||||
TEXT("FSR RCAS Sharpness in stops (0: sharpest, 1: 1/2 as sharp, 2: 1/4 as sharp, 3: 1/8 as sharp, etc.). A value of 0.2 would correspond to a ~0.87 sharpness in [0-1] linear scale"),
|
||||
ECVF_Default);
|
||||
|
||||
static int32 GMobileFSRCASDenoise = 0;
|
||||
static FAutoConsoleVariableRef CVarMobileFSRCASDenoise(
|
||||
TEXT("r.Mobile.FSR.RCAS.Denoise"),
|
||||
GMobileFSRCASDenoise,
|
||||
TEXT("FSR RCAS Denoise support for grainy input such as dithered images or input with custom film grain effects applied prior to FSR. 1:On, 0:Off"),
|
||||
ECVF_Default);
|
||||
|
||||
static int32 GMobileFSRDisableCompute = 0;
|
||||
static FAutoConsoleVariableRef CVarMobileFSRDisableCompute(
|
||||
TEXT("r.Mobile.FSR.DisableCompute"),
|
||||
GMobileFSRDisableCompute,
|
||||
TEXT("FSR Disable compute shaders for FSR (Recommended for Adreno). 1: Compute Disabled, 0: Compute Enabled (default)"),
|
||||
ECVF_Default);
|
||||
|
||||
///
|
||||
/// FSR COMPUTE SHADER
|
||||
///
|
||||
class FMobileFSRCS : public FGlobalShader
|
||||
{
|
||||
public:
|
||||
DECLARE_GLOBAL_SHADER(FMobileFSRCS);
|
||||
SHADER_USE_PARAMETER_STRUCT(FMobileFSRCS, FGlobalShader);
|
||||
|
||||
using FPermutationDomain = TShaderPermutationDomain<FMobileFSR_UseFP16Dim, FMobileFSR_UsePassthroughAlpha>;
|
||||
|
||||
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
||||
SHADER_PARAMETER_STRUCT_INCLUDE(FMobileFSRPassParameters, FSR)
|
||||
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, OutputTexture)
|
||||
END_SHADER_PARAMETER_STRUCT()
|
||||
|
||||
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
||||
{
|
||||
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
||||
|
||||
if (PermutationVector.Get<FMobileFSR_UseFP16Dim>())
|
||||
{
|
||||
if (IsSimulatedPlatform(Parameters.Platform) || !IsDxcEnabledForPlatform(Parameters.Platform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return IsMobilePlatform(Parameters.Platform);
|
||||
}
|
||||
|
||||
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
|
||||
{
|
||||
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
||||
|
||||
OutEnvironment.SetDefine(TEXT("COMPUTE_SHADER"), 1);
|
||||
|
||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEX"), 64);
|
||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEY"), 1);
|
||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEZ"), 1);
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_GLOBAL_SHADER(FMobileFSRCS, "/Plugin/MobileFSR/Private/PostProcessMobileFFX_FSR.usf", "MainCS", SF_Compute);
|
||||
|
||||
class FMobileFSRPS : public FGlobalShader
|
||||
{
|
||||
public:
|
||||
DECLARE_GLOBAL_SHADER(FMobileFSRPS);
|
||||
SHADER_USE_PARAMETER_STRUCT(FMobileFSRPS, FGlobalShader);
|
||||
|
||||
using FPermutationDomain = TShaderPermutationDomain<FMobileFSR_UseFP16Dim, FMobileFSR_UsePassthroughAlpha>;
|
||||
|
||||
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
||||
SHADER_PARAMETER_STRUCT_INCLUDE(FMobileFSRPassParameters, FSR)
|
||||
RENDER_TARGET_BINDING_SLOTS()
|
||||
END_SHADER_PARAMETER_STRUCT()
|
||||
|
||||
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
||||
{
|
||||
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
||||
|
||||
if (PermutationVector.Get<FMobileFSR_UseFP16Dim>())
|
||||
{
|
||||
if (IsSimulatedPlatform(Parameters.Platform) || !IsDxcEnabledForPlatform(Parameters.Platform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return IsMobilePlatform(Parameters.Platform);
|
||||
}
|
||||
|
||||
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_GLOBAL_SHADER(FMobileFSRPS, "/Plugin/MobileFSR/Private/PostProcessMobileFFX_FSR.usf", "MainPS", SF_Pixel);
|
||||
|
||||
FScreenPassTexture AddEASUPass(FRDGBuilder& GraphBuilder, const FViewInfo& View, const ISpatialUpscaler::FInputs& PassInputs)
|
||||
{
|
||||
using namespace MobileFSRPrivate;
|
||||
|
||||
FScreenPassTexture OutputTexture;
|
||||
bool bUseFP16 = !IsSimulatedPlatform(View.GetShaderPlatform()) && IsDxcEnabledForPlatform(View.GetShaderPlatform());
|
||||
|
||||
FRDGTextureDesc FSROutputTextureDesc = PassInputs.SceneColor.Texture->Desc;
|
||||
FSROutputTextureDesc.Reset();
|
||||
FSROutputTextureDesc.Extent = View.UnscaledViewRect.Max;
|
||||
FSROutputTextureDesc.ClearValue = FClearValueBinding::Black;
|
||||
FSROutputTextureDesc.Flags = TexCreate_ShaderResource | TexCreate_UAV | TexCreate_RenderTargetable;
|
||||
|
||||
if (PassInputs.OverrideOutput.IsValid())
|
||||
{
|
||||
OutputTexture = PassInputs.OverrideOutput;
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputTexture = FScreenPassTexture(PassInputs.SceneColor);
|
||||
OutputTexture.Texture = GraphBuilder.CreateTexture(FSROutputTextureDesc, TEXT("FSR-Output"), ERDGTextureFlags::MultiFrame);
|
||||
}
|
||||
|
||||
OutputTexture.ViewRect = View.UnscaledViewRect;
|
||||
FScreenPassTextureViewport OutputViewport = FScreenPassTextureViewport(OutputTexture);
|
||||
FScreenPassTextureViewport InputViewport = FScreenPassTextureViewport(PassInputs.SceneColor);
|
||||
FScreenPassTextureViewportParameters PassOutputViewportParams = GetScreenPassTextureViewportParameters(OutputViewport);
|
||||
|
||||
AU1 const0[4];
|
||||
AU1 const1[4];
|
||||
AU1 const2[4];
|
||||
AU1 const3[4]; // Configure FSR
|
||||
|
||||
FsrEasuConOffset(const0, const1, const2, const3,
|
||||
static_cast<AF1>(InputViewport.Rect.Width())
|
||||
, static_cast<AF1>(InputViewport.Rect.Height()) // current frame render resolution
|
||||
, static_cast<AF1>(PassInputs.SceneColor.Texture->Desc.Extent.X)
|
||||
, static_cast<AF1>(PassInputs.SceneColor.Texture->Desc.Extent.Y) // input container resolution (for DRS)
|
||||
, static_cast<AF1>(OutputViewport.Rect.Width())
|
||||
, static_cast<AF1>(OutputViewport.Rect.Height()) // upscaled-to resolution
|
||||
, static_cast<AF1>(InputViewport.Rect.Min.X)
|
||||
, static_cast<AF1>(InputViewport.Rect.Min.Y)
|
||||
);
|
||||
|
||||
const bool bOutputSupportsUAV = (OutputTexture.Texture->Desc.Flags & TexCreate_UAV) == TexCreate_UAV;
|
||||
|
||||
if (!bOutputSupportsUAV || GMobileFSRDisableCompute)
|
||||
{
|
||||
FMobileFSRPS::FParameters* PassParameters = GraphBuilder.AllocParameters<FMobileFSRPS::FParameters>();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
PassParameters->FSR.Const0[i] = const0[i];
|
||||
PassParameters->FSR.Const1[i] = const1[i];
|
||||
PassParameters->FSR.Const2[i] = const2[i];
|
||||
PassParameters->FSR.Const3[i] = const3[i];
|
||||
}
|
||||
PassParameters->FSR.InputTexture = PassInputs.SceneColor.Texture;
|
||||
PassParameters->FSR.samLinearClamp = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
||||
PassParameters->FSR.VPColor_ExtentInverse = PassOutputViewportParams.ExtentInverse;
|
||||
PassParameters->FSR.VPColor_ViewportMin = PassOutputViewportParams.ViewportMin;
|
||||
PassParameters->RenderTargets[0] = FRenderTargetBinding(OutputTexture.Texture, ERenderTargetLoadAction::EClear);
|
||||
|
||||
FMobileFSRPS::FPermutationDomain PSPermutationVector;
|
||||
PSPermutationVector.Set<FMobileFSR_UseFP16Dim>(bUseFP16);
|
||||
PSPermutationVector.Set<FMobileFSR_UsePassthroughAlpha>(IsPostProcessingWithAlphaChannelSupported());
|
||||
|
||||
TShaderMapRef<FMobileFSRPS> PixelShader(View.ShaderMap, PSPermutationVector);
|
||||
|
||||
AddDrawScreenPass(GraphBuilder,
|
||||
RDG_EVENT_NAME("FSR/Upscale %dx%d -> %dx%d (PS)"
|
||||
, InputViewport.Rect.Width(), InputViewport.Rect.Height()
|
||||
, OutputViewport.Rect.Width(), OutputViewport.Rect.Height()),
|
||||
View, OutputViewport, InputViewport,
|
||||
PixelShader, PassParameters,
|
||||
EScreenPassDrawFlags::None
|
||||
);
|
||||
}
|
||||
// CS
|
||||
else
|
||||
{
|
||||
FMobileFSRCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FMobileFSRCS::FParameters>();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
PassParameters->FSR.Const0[i] = const0[i];
|
||||
PassParameters->FSR.Const1[i] = const1[i];
|
||||
PassParameters->FSR.Const2[i] = const2[i];
|
||||
PassParameters->FSR.Const3[i] = const3[i];
|
||||
}
|
||||
PassParameters->FSR.InputTexture = PassInputs.SceneColor.Texture;
|
||||
PassParameters->FSR.samLinearClamp = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
||||
PassParameters->FSR.VPColor_ExtentInverse = PassOutputViewportParams.ExtentInverse;
|
||||
PassParameters->FSR.VPColor_ViewportMin = PassOutputViewportParams.ViewportMin;
|
||||
PassParameters->OutputTexture = GraphBuilder.CreateUAV(OutputTexture.Texture);
|
||||
|
||||
FMobileFSRCS::FPermutationDomain CSPermutationVector;
|
||||
CSPermutationVector.Set<FMobileFSR_UseFP16Dim>(bUseFP16);
|
||||
CSPermutationVector.Set<FMobileFSR_UsePassthroughAlpha>(IsPostProcessingWithAlphaChannelSupported());
|
||||
|
||||
TShaderMapRef<FMobileFSRCS> ComputeShaderFSR(View.ShaderMap, CSPermutationVector);
|
||||
FComputeShaderUtils::AddPass(
|
||||
GraphBuilder,
|
||||
RDG_EVENT_NAME("FSR/Upscale %dx%d -> %dx%d (CS)"
|
||||
, InputViewport.Rect.Width(), InputViewport.Rect.Height()
|
||||
, OutputViewport.Rect.Width(), OutputViewport.Rect.Height()),
|
||||
ComputeShaderFSR,
|
||||
PassParameters,
|
||||
FComputeShaderUtils::GetGroupCount(OutputViewport.Rect.Size(), 16));
|
||||
}
|
||||
|
||||
return MoveTemp(OutputTexture);
|
||||
}
|
||||
|
||||
///
|
||||
/// RCAS COMPUTE SHADER
|
||||
///
|
||||
class FMobileRCASCS : public FGlobalShader
|
||||
{
|
||||
public:
|
||||
DECLARE_GLOBAL_SHADER(FMobileRCASCS);
|
||||
SHADER_USE_PARAMETER_STRUCT(FMobileRCASCS, FGlobalShader);
|
||||
|
||||
using FPermutationDomain = TShaderPermutationDomain<FMobileFSR_UseFP16Dim, FMobileFSR_UsePassthroughAlpha, FMobileRCAS_DenoiseDim>;
|
||||
|
||||
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
||||
SHADER_PARAMETER_STRUCT_INCLUDE(FMobileRCASPassParameters, RCAS)
|
||||
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, OutputTexture)
|
||||
END_SHADER_PARAMETER_STRUCT()
|
||||
|
||||
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
||||
{
|
||||
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
||||
|
||||
if (PermutationVector.Get<FMobileFSR_UseFP16Dim>())
|
||||
{
|
||||
if (IsSimulatedPlatform(Parameters.Platform) || !IsDxcEnabledForPlatform(Parameters.Platform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return IsMobilePlatform(Parameters.Platform);
|
||||
}
|
||||
|
||||
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
|
||||
{
|
||||
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
||||
|
||||
OutEnvironment.SetDefine(TEXT("COMPUTE_SHADER"), 1);
|
||||
|
||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEX"), 64);
|
||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEY"), 1);
|
||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEZ"), 1);
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_GLOBAL_SHADER(FMobileRCASCS, "/Plugin/MobileFSR/Private/PostProcessMobileFFX_RCAS.usf", "MainCS", SF_Compute);
|
||||
|
||||
|
||||
///
|
||||
/// RCAS PIXEL SHADER
|
||||
///
|
||||
class FMobileRCASPS : public FGlobalShader
|
||||
{
|
||||
public:
|
||||
DECLARE_GLOBAL_SHADER(FMobileRCASPS);
|
||||
SHADER_USE_PARAMETER_STRUCT(FMobileRCASPS, FGlobalShader);
|
||||
|
||||
using FPermutationDomain = TShaderPermutationDomain<FMobileFSR_UseFP16Dim, FMobileFSR_UsePassthroughAlpha, FMobileRCAS_DenoiseDim>;
|
||||
|
||||
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
||||
SHADER_PARAMETER_STRUCT_INCLUDE(FMobileRCASPassParameters, RCAS)
|
||||
RENDER_TARGET_BINDING_SLOTS()
|
||||
END_SHADER_PARAMETER_STRUCT()
|
||||
|
||||
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
||||
{
|
||||
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
||||
if (PermutationVector.Get<FMobileFSR_UseFP16Dim>())
|
||||
{
|
||||
if (IsSimulatedPlatform(Parameters.Platform) || !IsDxcEnabledForPlatform(Parameters.Platform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return IsMobilePlatform(Parameters.Platform);
|
||||
}
|
||||
|
||||
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_GLOBAL_SHADER(FMobileRCASPS, "/Plugin/MobileFSR/Private/PostProcessMobileFFX_RCAS.usf", "MainPS", SF_Pixel);
|
||||
|
||||
FScreenPassTexture AddCASPass(FRDGBuilder& GraphBuilder, const FViewInfo& View, const ISpatialUpscaler::FInputs& PassInputs)
|
||||
{
|
||||
using namespace MobileFSRPrivate;
|
||||
|
||||
FScreenPassTexture OutputTexture;
|
||||
bool bUseFP16 = !IsSimulatedPlatform(View.GetShaderPlatform()) && IsDxcEnabledForPlatform(View.GetShaderPlatform());
|
||||
|
||||
if (PassInputs.OverrideOutput.IsValid())
|
||||
{
|
||||
OutputTexture = PassInputs.OverrideOutput;
|
||||
}
|
||||
else
|
||||
{
|
||||
FRDGTextureDesc RCASOutputTextureDesc = PassInputs.SceneColor.Texture->Desc;
|
||||
|
||||
OutputTexture = FScreenPassTexture(PassInputs.SceneColor);
|
||||
OutputTexture.Texture = GraphBuilder.CreateTexture(RCASOutputTextureDesc, TEXT("RCAS-Output"), ERDGTextureFlags::MultiFrame);
|
||||
}
|
||||
|
||||
FScreenPassTextureViewport OutputViewport = FScreenPassTextureViewport(OutputTexture);
|
||||
FScreenPassTextureViewportParameters PassOutputViewportParams = GetScreenPassTextureViewportParameters(OutputViewport);
|
||||
|
||||
AU1 const0[4]; // Configure FSR
|
||||
FsrRcasCon(const0, GMobileFSRCASSharpness);
|
||||
|
||||
const bool bOutputSupportsUAV = (OutputTexture.Texture->Desc.Flags & TexCreate_UAV) == TexCreate_UAV;
|
||||
|
||||
if (!bOutputSupportsUAV || GMobileFSRDisableCompute)
|
||||
{
|
||||
FMobileRCASPS::FParameters* PassParameters = GraphBuilder.AllocParameters<FMobileRCASPS::FParameters>();
|
||||
|
||||
// set pass inputs
|
||||
for (int i = 0; i < 4; i++) { PassParameters->RCAS.Const0[i] = const0[i]; }
|
||||
PassParameters->RCAS.InputTexture = PassInputs.SceneColor.Texture;
|
||||
PassParameters->RCAS.VPColor_ExtentInverse = PassOutputViewportParams.ExtentInverse;
|
||||
PassParameters->RenderTargets[0] = FRenderTargetBinding(OutputTexture.Texture, ERenderTargetLoadAction::EClear);
|
||||
|
||||
// grab shaders
|
||||
FMobileRCASPS::FPermutationDomain PSPermutationVector;
|
||||
PSPermutationVector.Set<FMobileFSR_UseFP16Dim>(bUseFP16);
|
||||
PSPermutationVector.Set<FMobileFSR_UsePassthroughAlpha>(IsPostProcessingWithAlphaChannelSupported());
|
||||
PSPermutationVector.Set<FMobileRCAS_DenoiseDim>(GMobileFSRCASDenoise > 0);
|
||||
|
||||
TShaderMapRef<FMobileRCASPS> PixelShader(View.ShaderMap, PSPermutationVector);
|
||||
|
||||
AddDrawScreenPass(GraphBuilder,
|
||||
RDG_EVENT_NAME("FSR/RCAS Sharpness=%.2f(PS)"
|
||||
, GMobileFSRCASSharpness),
|
||||
View, OutputViewport, OutputViewport,
|
||||
PixelShader, PassParameters,
|
||||
EScreenPassDrawFlags::None
|
||||
);
|
||||
}
|
||||
// CS
|
||||
else
|
||||
{
|
||||
FMobileRCASCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FMobileRCASCS::FParameters>();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
PassParameters->RCAS.Const0[i] = const0[i];
|
||||
}
|
||||
PassParameters->RCAS.InputTexture = PassInputs.SceneColor.Texture;
|
||||
PassParameters->RCAS.VPColor_ExtentInverse = PassOutputViewportParams.ExtentInverse;
|
||||
PassParameters->OutputTexture = GraphBuilder.CreateUAV(OutputTexture.Texture);
|
||||
|
||||
FMobileRCASCS::FPermutationDomain CSPermutationVector;
|
||||
CSPermutationVector.Set<FMobileFSR_UseFP16Dim>(bUseFP16);
|
||||
CSPermutationVector.Set<FMobileFSR_UsePassthroughAlpha>(IsPostProcessingWithAlphaChannelSupported());
|
||||
CSPermutationVector.Set<FMobileRCAS_DenoiseDim>(GMobileFSRCASDenoise > 0);
|
||||
|
||||
TShaderMapRef<FMobileRCASCS> ComputeShaderRCASPass(View.ShaderMap, CSPermutationVector);
|
||||
FComputeShaderUtils::AddPass(
|
||||
GraphBuilder,
|
||||
RDG_EVENT_NAME("FSR/RCAS Sharpness=%.2f (CS)", GMobileFSRCASSharpness),
|
||||
ComputeShaderRCASPass,
|
||||
PassParameters,
|
||||
FComputeShaderUtils::GetGroupCount(OutputViewport.Rect.Size(), 16));
|
||||
}
|
||||
|
||||
return MoveTemp(OutputTexture);
|
||||
}
|
||||
|
||||
DECLARE_GPU_STAT(MobileFSRUpscaler);
|
||||
|
||||
FMobileFSRUpscaler::FMobileFSRUpscaler(bool bInIsEASUPass) : bIsEASUPass(bInIsEASUPass)
|
||||
{
|
||||
}
|
||||
|
||||
ISpatialUpscaler* FMobileFSRUpscaler::Fork_GameThread(const class FSceneViewFamily& ViewFamily) const
|
||||
{
|
||||
return new FMobileFSRUpscaler(bIsEASUPass);
|
||||
}
|
||||
|
||||
FScreenPassTexture FMobileFSRUpscaler::AddPasses(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) const
|
||||
{
|
||||
RDG_EVENT_SCOPE_STAT(GraphBuilder, MobileFSRUpscaler, "MobileFSRUpscaler");
|
||||
RDG_GPU_STAT_SCOPE(GraphBuilder, MobileFSRUpscaler);
|
||||
|
||||
FScreenPassTexture SceneColor;
|
||||
|
||||
if (bIsEASUPass)
|
||||
{
|
||||
SceneColor = AddEASUPass(GraphBuilder, View, PassInputs);
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneColor = AddCASPass(GraphBuilder, View, PassInputs);
|
||||
}
|
||||
|
||||
return MoveTemp(SceneColor);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PostProcess/PostProcessUpscale.h"
|
||||
|
||||
class FMobileFSRUpscaler final : public ISpatialUpscaler
|
||||
{
|
||||
public:
|
||||
FMobileFSRUpscaler(bool bInIsEASUPass);
|
||||
|
||||
// ISpatialUpscaler interface
|
||||
const TCHAR* GetDebugName() const override { return TEXT("FMobileFSRUpscaler"); }
|
||||
|
||||
ISpatialUpscaler* Fork_GameThread(const class FSceneViewFamily& ViewFamily) const override;
|
||||
FScreenPassTexture AddPasses(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) const override;
|
||||
|
||||
private:
|
||||
bool bIsEASUPass = false;
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "MobileFSRViewExtension.h"
|
||||
#include "MobileFSRUpscaler.h"
|
||||
|
||||
static TAutoConsoleVariable<int32> CVarEnableFSR(
|
||||
TEXT("r.Mobile.FSR.Enabled"),
|
||||
1,
|
||||
TEXT("Enable Mobile FSR for Primary Upscale"),
|
||||
ECVF_RenderThreadSafe);
|
||||
|
||||
TAutoConsoleVariable<int32> CVarMobileFSRCASEnabled(
|
||||
TEXT("r.Mobile.FSR.RCAS.Enabled"),
|
||||
1,
|
||||
TEXT("FidelityFX FSR/RCAS : Robust Contrast Adaptive Sharpening Filter"),
|
||||
ECVF_RenderThreadSafe);
|
||||
|
||||
TAutoConsoleVariable<int32>CVarMobileFSRUpsamplingEnabled(
|
||||
TEXT("r.Mobile.FSR.Upsampling.Enabled"),
|
||||
1,
|
||||
TEXT("FidelityFX FSR/RCAS : Robust Contrast Adaptive Sharpening Filter"),
|
||||
ECVF_Default);
|
||||
|
||||
void FMobileFSRViewExtension::BeginRenderViewFamily(FSceneViewFamily& InViewFamily)
|
||||
{
|
||||
if (InViewFamily.GetFeatureLevel() == ERHIFeatureLevel::ES3_1 && CVarEnableFSR.GetValueOnAnyThread() > 0)
|
||||
{
|
||||
if (CVarMobileFSRUpsamplingEnabled.GetValueOnAnyThread())
|
||||
{
|
||||
InViewFamily.SetPrimarySpatialUpscalerInterface(new FMobileFSRUpscaler(true));
|
||||
}
|
||||
if (CVarMobileFSRCASEnabled.GetValueOnAnyThread())
|
||||
{
|
||||
InViewFamily.SetSecondarySpatialUpscalerInterface(new FMobileFSRUpscaler(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
#include "Logging/LogMacros.h"
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogMobileFSR, Verbose, All);
|
||||
|
||||
class FMobileFSRViewExtension;
|
||||
|
||||
class FMobileFSRModule final : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
void StartupModule() override;
|
||||
void ShutdownModule() override;
|
||||
void OnPostEngineInit();
|
||||
|
||||
TSharedPtr<FMobileFSRViewExtension, ESPMode::ThreadSafe> ViewExtension;
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SceneViewExtension.h"
|
||||
|
||||
class FMobileFSRViewExtension final : public FSceneViewExtensionBase
|
||||
{
|
||||
public:
|
||||
FMobileFSRViewExtension(const FAutoRegister& AutoRegister) : FSceneViewExtensionBase(AutoRegister) {}
|
||||
|
||||
MOBILEFSR_API void BeginRenderViewFamily(FSceneViewFamily& InViewFamily) override;
|
||||
};
|
||||
Reference in New Issue
Block a user