FidelityFX-FSR (#288)

* FidelityFX-FSR

* fsr update

* editor fsr sharpness slider
This commit is contained in:
Turánszki János
2021-07-18 17:18:01 +02:00
committed by GitHub
parent 19690fc160
commit 3d55225452
18 changed files with 4187 additions and 1 deletions
+20
View File
@@ -372,6 +372,26 @@ void PostprocessWindow::Create(EditorComponent* editor)
});
AddWidget(&chromaticaberrationSlider);
fsrCheckBox.Create("FSR: ");
fsrCheckBox.SetTooltip("FidelityFX FSR Upscaling. Use this only with Temporal AA or MSAA when the resolution scaling is lowered.");
fsrCheckBox.SetSize(XMFLOAT2(hei, hei));
fsrCheckBox.SetPos(XMFLOAT2(x, y += step));
fsrCheckBox.SetCheck(editor->renderPath->getFSREnabled());
fsrCheckBox.OnClick([=](wiEventArgs args) {
editor->renderPath->setFSREnabled(args.bValue);
});
AddWidget(&fsrCheckBox);
fsrSlider.Create(0, 2, 1.0f, 1000, "Sharpness: ");
fsrSlider.SetTooltip("The sharpening amount to apply for FSR upscaling.");
fsrSlider.SetSize(XMFLOAT2(100, hei));
fsrSlider.SetPos(XMFLOAT2(x + 100, y));
fsrSlider.SetValue(editor->renderPath->getFSRSharpness());
fsrSlider.OnSlide([=](wiEventArgs args) {
editor->renderPath->setFSRSharpness(args.fValue);
});
AddWidget(&fsrSlider);
Translate(XMFLOAT3((float)editor->GetLogicalWidth() - 500, 80, 0));
SetVisible(false);
+2
View File
@@ -39,6 +39,8 @@ public:
wiSlider outlineThicknessSlider;
wiCheckBox chromaticaberrationCheckBox;
wiSlider chromaticaberrationSlider;
wiCheckBox fsrCheckBox;
wiSlider fsrSlider;
};
+33
View File
@@ -505,6 +505,7 @@ void RenderPath3D::ResizeBuffers()
setAO(ao);
setSSREnabled(ssrEnabled);
setRaytracedReflectionsEnabled(raytracedReflectionsEnabled);
setFSREnabled(fsrEnabled);
RenderPath2D::ResizeBuffers();
}
@@ -1459,6 +1460,13 @@ void RenderPath3D::RenderPostprocessChain(CommandList cmd) const
device->EventEnd(cmd);
wiProfiler::EndRange(range);
}
if (rtFSR[0].IsValid() && getFSREnabled())
{
wiRenderer::Postprocess_FSR(*rt_read, rtFSR[1], rtFSR[0], cmd, getFSRSharpness());
device->UnbindResources(TEXSLOT_ONDEMAND0, 1, cmd);
}
}
}
@@ -1559,3 +1567,28 @@ void RenderPath3D::setRaytracedReflectionsEnabled(bool value)
rtreflectionResources = {};
}
}
void RenderPath3D::setFSREnabled(bool value)
{
fsrEnabled = value;
if (resolutionScale < 1.0f && fsrEnabled)
{
GraphicsDevice* device = wiRenderer::GetDevice();
TextureDesc desc;
desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
desc.Format = rtPostprocess_LDR[0].desc.Format;
desc.Width = GetPhysicalWidth();
desc.Height = GetPhysicalHeight();
device->CreateTexture(&desc, nullptr, &rtFSR[0]);
device->SetName(&rtFSR[0], "rtFSR[0]");
device->CreateTexture(&desc, nullptr, &rtFSR[1]);
device->SetName(&rtFSR[1], "rtFSR[1]");
}
else
{
rtFSR[0] = {};
rtFSR[1] = {};
}
}
+11
View File
@@ -37,6 +37,7 @@ private:
float screenSpaceShadowRange = 1;
float eyeadaptionKey = 0.115f;
float eyeadaptionRate = 1;
float fsrSharpness = 1.0f;
AO ao = AO_DISABLED;
bool fxaaEnabled = false;
@@ -58,6 +59,7 @@ private:
bool ditherEnabled = true;
bool occlusionCullingEnabled = true;
bool sceneUpdateEnabled = true;
bool fsrEnabled = true;
uint32_t msaaSampleCount = 1;
@@ -81,6 +83,7 @@ public:
wiGraphics::Texture rtSun_resolved; // sun render target, but the resolved version if MSAA is enabled
wiGraphics::Texture rtGUIBlurredBackground[3]; // downsampled, gaussian blurred scene for GUI
wiGraphics::Texture rtShadingRate; // UINT8 shading rate per tile
wiGraphics::Texture rtFSR[2]; // FSR upscaling result (full resolution LDR)
wiGraphics::Texture rtPostprocess_HDR; // ping-pong with main scene RT in HDR post-process chain
wiGraphics::Texture rtPostprocess_LDR[2]; // ping-pong with itself in LDR post-process chain
@@ -145,6 +148,10 @@ public:
// Post-processes are ping-ponged, this function helps to obtain the last postprocess render target that was written
const wiGraphics::Texture* GetLastPostprocessRT() const
{
if (rtFSR[0].IsValid() && getFSREnabled())
{
return &rtFSR[0];
}
int ldr_postprocess_count = 0;
ldr_postprocess_count += getSharpenFilterEnabled() ? 1 : 0;
ldr_postprocess_count += getFXAAEnabled() ? 1 : 0;
@@ -195,6 +202,7 @@ public:
constexpr float getScreenSpaceShadowRange() const { return screenSpaceShadowRange; }
constexpr float getEyeAdaptionKey() const { return eyeadaptionKey; }
constexpr float getEyeAdaptionRate() const { return eyeadaptionRate; }
constexpr float getFSRSharpness() const { return fsrSharpness; }
constexpr bool getAOEnabled() const { return ao != AO_DISABLED; }
constexpr AO getAO() const { return ao; }
@@ -217,6 +225,7 @@ public:
constexpr bool getDitherEnabled() const { return ditherEnabled; }
constexpr bool getOcclusionCullingEnabled() const { return occlusionCullingEnabled; }
constexpr bool getSceneUpdateEnabled() const { return sceneUpdateEnabled; }
constexpr bool getFSREnabled() const { return fsrEnabled; }
constexpr uint32_t getMSAASampleCount() const { return msaaSampleCount; }
@@ -236,6 +245,7 @@ public:
constexpr void setScreenSpaceShadowRange(float value) { screenSpaceShadowRange = value; }
constexpr void setEyeAdaptionKey(float value) { eyeadaptionKey = value; }
constexpr void setEyeAdaptionRate(float value) { eyeadaptionRate = value; }
constexpr void setFSRSharpness(float value) { fsrSharpness = value; }
void setAO(AO value);
void setSSREnabled(bool value);
@@ -257,6 +267,7 @@ public:
constexpr void setDitherEnabled(bool value) { ditherEnabled = value; }
constexpr void setOcclusionCullingEnabled(bool value) { occlusionCullingEnabled = value; }
constexpr void setSceneUpdateEnabled(bool value) { sceneUpdateEnabled = value; }
void setFSREnabled(bool value);
virtual void setMSAASampleCount(uint32_t value) { msaaSampleCount = value; }
+2
View File
@@ -104,6 +104,8 @@ int main(int argc, char* argv[])
"temporalaaCS.hlsl" ,
"tileFrustumsCS.hlsl" ,
"tonemapCS.hlsl" ,
"fsr_upscalingCS.hlsl" ,
"fsr_sharpenCS.hlsl" ,
"ssr_resolveCS.hlsl" ,
"ssr_temporalCS.hlsl" ,
"ssaoCS.hlsl" ,
+2
View File
@@ -30,6 +30,8 @@ set(SHADERS_CS
"temporalaaCS.hlsl"
"tileFrustumsCS.hlsl"
"tonemapCS.hlsl"
"fsr_upscalingCS.hlsl"
"fsr_sharpenCS.hlsl"
"ssr_resolveCS.hlsl"
"ssr_temporalCS.hlsl"
"ssaoCS.hlsl"
@@ -70,6 +70,14 @@ CBUFFER(ShadingRateClassificationCB, CBSLOT_RENDERER_POSTPROCESS)
uint SHADING_RATE_4X4;
};
CBUFFER(FSRCB, CBSLOT_RENDERER_POSTPROCESS)
{
uint4 xFSR_Const0;
uint4 xFSR_Const1;
uint4 xFSR_Const2;
uint4 xFSR_Const3;
};
static const uint MOTIONBLUR_TILESIZE = 32;
#define motionblur_strength xPPParams0.x
@@ -671,6 +671,14 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Vertex</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Vertex</ShaderType>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)fsr_sharpenCS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)fsr_upscalingCS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)hairparticle_finishUpdateCS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
@@ -986,6 +986,12 @@
<FxCompile Include="$(MSBuildThisFileDirectory)objectVS_simple_tessellation.hlsl">
<Filter>VS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)fsr_upscalingCS.hlsl">
<Filter>CS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)fsr_sharpenCS.hlsl">
<Filter>CS</Filter>
</FxCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(MSBuildThisFileDirectory)ConstantBufferMapping.h">
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
#include "globals.hlsli"
#include "ShaderInterop_Postprocess.h"
#define A_GPU 1
#define A_HLSL 1
#include "ffx-fsr/ffx_a.h"
static const uint4 Sample = 0;
TEXTURE2D(input, float4, TEXSLOT_ONDEMAND0);
RWTEXTURE2D(output, unorm float4, 0);
#define FSR_RCAS_F
AF4 FsrRcasLoadF(ASU2 p) { return input.Load(int3(ASU2(p), 0)); }
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
#include "ffx-fsr/ffx_fsr1.h"
void CurrFilter(int2 pos)
{
AF3 c;
FsrRcasF(c.r, c.g, c.b, pos, xFSR_Const0);
if (Sample.x == 1)
c *= c;
output[pos] = float4(c, 1);
}
[numthreads(64, 1, 1)]
void main(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);
CurrFilter(gxy);
gxy.x += 8u;
CurrFilter(gxy);
gxy.y += 8u;
CurrFilter(gxy);
gxy.x -= 8u;
CurrFilter(gxy);
}
+42
View File
@@ -0,0 +1,42 @@
#include "globals.hlsli"
#include "ShaderInterop_Postprocess.h"
#define A_GPU 1
#define A_HLSL 1
#include "ffx-fsr/ffx_a.h"
static const uint4 Sample = 0;
TEXTURE2D(input, float4, TEXSLOT_ONDEMAND0);
RWTEXTURE2D(output, unorm float4, 0);
AF4 FsrEasuRF(AF2 p) { AF4 res = input.GatherRed(sampler_linear_clamp, p, int2(0, 0)); return res; }
AF4 FsrEasuGF(AF2 p) { AF4 res = input.GatherGreen(sampler_linear_clamp, p, int2(0, 0)); return res; }
AF4 FsrEasuBF(AF2 p) { AF4 res = input.GatherBlue(sampler_linear_clamp, p, int2(0, 0)); return res; }
#define FSR_EASU_F 1
#include "ffx-fsr/ffx_fsr1.h"
void CurrFilter(int2 pos)
{
AF3 c;
FsrEasuF(c, pos, xFSR_Const0, xFSR_Const1, xFSR_Const2, xFSR_Const3);
if (Sample.x == 1)
c *= c;
output[pos] = float4(c, 1);
}
[numthreads(64, 1, 1)]
void main(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);
CurrFilter(gxy);
gxy.x += 8u;
CurrFilter(gxy);
gxy.y += 8u;
CurrFilter(gxy);
gxy.x -= 8u;
CurrFilter(gxy);
}
+3
View File
@@ -102,6 +102,7 @@ enum CBTYPES
CBTYPE_COPYTEXTURE,
CBTYPE_FORWARDENTITYMASK,
CBTYPE_POSTPROCESS,
CBTYPE_POSTPROCESS_FSR,
CBTYPE_POSTPROCESS_MSAO,
CBTYPE_POSTPROCESS_MSAO_UPSAMPLE,
CBTYPE_LENSFLARE,
@@ -369,6 +370,8 @@ enum SHADERTYPE
CSTYPE_POSTPROCESS_LINEARDEPTH,
CSTYPE_POSTPROCESS_SHARPEN,
CSTYPE_POSTPROCESS_TONEMAP,
CSTYPE_POSTPROCESS_FSR_UPSCALING,
CSTYPE_POSTPROCESS_FSR_SHARPEN,
CSTYPE_POSTPROCESS_CHROMATIC_ABERRATION,
CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_FLOAT1,
CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_UNORM1,
+122
View File
@@ -1301,6 +1301,8 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_LINEARDEPTH], "lineardepthCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_SHARPEN], "sharpenCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_TONEMAP], "tonemapCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_FSR_UPSCALING], "fsr_upscalingCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_FSR_SHARPEN], "fsr_sharpenCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_CHROMATIC_ABERRATION], "chromatic_aberrationCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_FLOAT1], "upsample_bilateral_float1CS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_UNORM1], "upsample_bilateral_unorm1CS.cso"); });
@@ -2068,6 +2070,10 @@ void LoadBuffers()
device->CreateBuffer(&bd, nullptr, &constantBuffers[CBTYPE_POSTPROCESS]);
device->SetName(&constantBuffers[CBTYPE_POSTPROCESS], "PostProcessCB");
bd.ByteWidth = sizeof(FSRCB);
device->CreateBuffer(&bd, nullptr, &constantBuffers[CBTYPE_POSTPROCESS_FSR]);
device->SetName(&constantBuffers[CBTYPE_POSTPROCESS_FSR], "FSRCB");
bd.ByteWidth = sizeof(MSAOCB);
device->CreateBuffer(&bd, nullptr, &constantBuffers[CBTYPE_POSTPROCESS_MSAO]);
device->SetName(&constantBuffers[CBTYPE_POSTPROCESS_MSAO], "MSAOCB");
@@ -11859,6 +11865,122 @@ void Postprocess_Tonemap(
device->EventEnd(cmd);
}
#define A_CPU
#include "shaders/ffx-fsr/ffx_a.h"
#include "shaders/ffx-fsr/ffx_fsr1.h"
void Postprocess_FSR(
const Texture& input,
const Texture& temp,
const Texture& output,
CommandList cmd,
float sharpness
)
{
device->EventBegin("Postprocess_FSR", cmd);
auto range = wiProfiler::BeginRangeGPU("Postprocess_FSR", cmd);
const TextureDesc& desc = output.GetDesc();
struct FSRCB
{
AU1 const0[4];
AU1 const1[4];
AU1 const2[4];
AU1 const3[4];
} cb;
// Upscaling:
{
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_FSR_UPSCALING], cmd);
FsrEasuCon(
cb.const0,
cb.const1,
cb.const2,
cb.const3,
// current frame render resolution:
static_cast<AF1>(input.desc.Width),
static_cast<AF1>(input.desc.Height),
// input container resolution:
static_cast<AF1>(input.desc.Width),
static_cast<AF1>(input.desc.Height),
// upscaled-to-resolution:
static_cast<AF1>(temp.desc.Width),
static_cast<AF1>(temp.desc.Height)
);
device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS_FSR], &cb, cmd);
device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS_FSR], CB_GETBINDSLOT(FSRCB), cmd);
device->BindResource(CS, &input, TEXSLOT_ONDEMAND0, cmd);
const GPUResource* uavs[] = {
&temp,
};
device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
{
GPUBarrier barriers[] = {
GPUBarrier::Image(&temp, temp.desc.layout, IMAGE_LAYOUT_UNORDERED_ACCESS),
};
device->Barrier(barriers, arraysize(barriers), cmd);
}
device->Dispatch((desc.Width + 15) / 16, (desc.Height + 15) / 16, 1, cmd);
{
GPUBarrier barriers[] = {
GPUBarrier::Memory(),
GPUBarrier::Image(&temp, IMAGE_LAYOUT_UNORDERED_ACCESS, temp.desc.layout),
};
device->Barrier(barriers, arraysize(barriers), cmd);
}
device->UnbindUAVs(0, arraysize(uavs), cmd);
}
// Sharpen:
{
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_FSR_SHARPEN], cmd);
FsrRcasCon(cb.const0, sharpness);
device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS_FSR], &cb, cmd);
device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS_FSR], CB_GETBINDSLOT(FSRCB), cmd);
device->BindResource(CS, &temp, TEXSLOT_ONDEMAND0, cmd);
const GPUResource* uavs[] = {
&output,
};
device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
{
GPUBarrier barriers[] = {
GPUBarrier::Image(&output, output.desc.layout, IMAGE_LAYOUT_UNORDERED_ACCESS),
};
device->Barrier(barriers, arraysize(barriers), cmd);
}
device->Dispatch((desc.Width + 15) / 16, (desc.Height + 15) / 16, 1, cmd);
{
GPUBarrier barriers[] = {
GPUBarrier::Memory(),
GPUBarrier::Image(&output, IMAGE_LAYOUT_UNORDERED_ACCESS, output.desc.layout),
};
device->Barrier(barriers, arraysize(barriers), cmd);
}
device->UnbindUAVs(0, arraysize(uavs), cmd);
}
wiProfiler::EndRange(range);
device->EventEnd(cmd);
}
void Postprocess_Chromatic_Aberration(
const Texture& input,
const Texture& output,
+7
View File
@@ -596,6 +596,13 @@ namespace wiRenderer
const wiGraphics::Texture* texture_luminance = nullptr,
float eyeadaptionkey = 0.115f
);
void Postprocess_FSR(
const wiGraphics::Texture& input,
const wiGraphics::Texture& temp,
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd,
float sharpness = 1.0f
);
void Postprocess_Chromatic_Aberration(
const wiGraphics::Texture& input,
const wiGraphics::Texture& output,
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates, breaking compatibility changes
const int minor = 56;
// minor bug fixes, alterations, refactors, updates
const int revision = 73;
const int revision = 74;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
+25
View File
@@ -356,6 +356,31 @@ 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.
###############################################################################################################################
AMD FidelityFX
Shadow Denoiser: https://github.com/GPUOpen-Effects/FidelityFX-Denoiser
Super Resolution: https://github.com/GPUOpen-Effects/FidelityFX-FSR
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.