diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0f2d24ea2b..acd6da5238 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -8,6 +8,8 @@ A new header is inserted each time a *tag* is created. - engine: New night adaptation API on `ColorGrading`. This API can be used to create an effect that that simulates color and brightness shits in human vision in low-light conditions. +- engine: improved performance of AMD FidelityFX FSR1 by 4.6x, it now runs in about 2ms in 4K. + ## v1.12.3 - engine: Support AMD FidelityFX Super Resolution for dynamic resolution scaling diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index 45dbd33278..1af9efef6c 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -165,6 +165,7 @@ set(PRIVATE_HDRS src/fsr.h src/materials/fsr/ffx_a.h src/materials/fsr/ffx_fsr1.h + src/materials/fsr/ffx_fsr1_mobile.h src/upcast.h ) @@ -362,6 +363,7 @@ add_custom_command( OUTPUT "${MATERIAL_DIR}/fsr_easu.filamat" DEPENDS src/materials/fsr/ffx_a.h DEPENDS src/materials/fsr/ffx_fsr1.h + DEPENDS src/materials/fsr/ffx_fsr1_mobile.h APPEND ) diff --git a/filament/src/materials/fsr/ffx_fsr1_mobile.h b/filament/src/materials/fsr/ffx_fsr1_mobile.h index 010e152a81..4851cffe50 100644 --- a/filament/src/materials/fsr/ffx_fsr1_mobile.h +++ b/filament/src/materials/fsr/ffx_fsr1_mobile.h @@ -6,13 +6,19 @@ // -- FsrEasuSampleH should be implemented by calling shader, like following: // half3 FsrEasuSampleH(float2 p) { return MyTex.SampleLevel(LinearSampler, p, 0).xyz; } //============================================================================================================================== + +#define rcp(x) (1.0/(x)) +#define rsqrt inversesqrt + +AF3 FsrEasuSampleF(AF2 p); + void FsrEasuL( - out AH3 pix, - AF2 ip, - AF4 con0, - AF4 con1, - AF4 con2, - AF4 con3){ + out AF3 pix, + highp AF2 ip, + highp AF4 con0, + highp AF4 con1, + highp AF4 con2, + highp AF4 con3){ //------------------------------------------------------------------------------------------------------------------------------ // Direction is the '+' diff. // A @@ -20,83 +26,97 @@ void FsrEasuL( // E AF2 pp=(ip)*(con0.xy)+(con0.zw); AF2 tc=(pp+AF2_(0.5))*con1.xy; - AH3 sA=FsrEasuSampleH(tc-AF2(0, con1.y)); - AH3 sB=FsrEasuSampleH(tc-AF2(con1.x, 0)); - AH3 sC=FsrEasuSampleH(tc); - AH3 sD=FsrEasuSampleH(tc+AF2(con1.x, 0)); - AH3 sE=FsrEasuSampleH(tc+AF2(0, con1.y)); - AH1 lA=sA.r*AH1_(0.5)+sA.g; - AH1 lB=sB.r*AH1_(0.5)+sB.g; - AH1 lC=sC.r*AH1_(0.5)+sC.g; - AH1 lD=sD.r*AH1_(0.5)+sD.g; - AH1 lE=sE.r*AH1_(0.5)+sE.g; + AF3 sA=FsrEasuSampleF(tc-AF2(0, con1.y)); + AF3 sB=FsrEasuSampleF(tc-AF2(con1.x, 0)); + AF3 sC=FsrEasuSampleF(tc); + AF3 sD=FsrEasuSampleF(tc+AF2(con1.x, 0)); + AF3 sE=FsrEasuSampleF(tc+AF2(0, con1.y)); + AF1 lA=sA.r*AF1_(0.5)+sA.g; + AF1 lB=sB.r*AF1_(0.5)+sB.g; + AF1 lC=sC.r*AF1_(0.5)+sC.g; + AF1 lD=sD.r*AF1_(0.5)+sD.g; + AF1 lE=sE.r*AF1_(0.5)+sE.g; // Then takes magnitude from abs average of both sides of 'C'. // Length converts gradient reversal to 0, smoothly to non-reversal at 1, shaped, then adding horz and vert terms. - AH1 dc=lD-lC; - AH1 cb=lC-lB; - AH1 lenX=max(abs(dc),abs(cb)); - lenX=ARcpH1(lenX); - AH1 dirX=lD-lB; - lenX=ASatH1(abs(dirX)*lenX); + AF1 dc=lD-lC; + AF1 cb=lC-lB; + AF1 lenX=max(abs(dc),abs(cb)); + lenX=ARcpF1(lenX); + AF1 dirX=lD-lB; + lenX=ASatF1(abs(dirX)*lenX); lenX*=lenX; // Repeat for the y axis. - AH1 ec=lE-lC; - AH1 ca=lC-lA; - AH1 lenY=max(abs(ec),abs(ca)); - lenY=ARcpH1(lenY); - AH1 dirY=lE-lA; - lenY=ASatH1(abs(dirY)*lenY); - AH1 len = lenY * lenY + lenX; - AH2 dir = AH2(dirX, dirY); - //------------------------------------------------------------------------------------------------------------------------------ - AH2 dir2=dir*dir; - AH1 dirR=dir2.x+dir2.y; - if (dirR