Skip to content

Commit

Permalink
初步移植FSR
Browse files Browse the repository at this point in the history
  • Loading branch information
Blinue committed Jul 16, 2021
1 parent 463c668 commit 7f6c66f
Show file tree
Hide file tree
Showing 15 changed files with 4,444 additions and 4 deletions.
2 changes: 1 addition & 1 deletion EffectCommon/EffectCommon.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
Expand Down
3 changes: 3 additions & 0 deletions EffectCommon/EffectCommon.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
<Filter>着色器</Filter>
</None>
<None Include="packages.config" />
<None Include="ffx_a.hlsli">
<Filter>着色器</Filter>
</None>
</ItemGroup>
<ItemGroup>
<FxCompile Include="RGB2YUVShader.hlsl">
Expand Down
12 changes: 11 additions & 1 deletion EffectCommon/common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,17 @@ static float2 maxCoord7;
#define SampleInputCur(index) (SampleInput(index, Coord(index).xy))
#define SampleInputOff(index, pos) (SampleInput(index, Coord(index).xy + (pos) * Coord(index).zw))

// 在循环中使用
// LOD
#define SampleInputLod(index, pos) (InputTexture##index.SampleLevel(InputSampler##index, (pos), 0))

// Gather
#define GatherInputRed(index, pos) (InputTexture##index.GatherRed(InputSampler##index, (pos), 0))
#define GatherInputGreen(index, pos) (InputTexture##index.GatherGreen(InputSampler##index, (pos), 0))
#define GatherInputBlue(index, pos) (InputTexture##index.GatherBlue(InputSampler##index, (pos), 0))

// Load
#define LoadInput(index, pos) (InputTexture##index.Load(pos))

#ifndef MAGPIE_NO_CHECK
#define GetCheckedPos(index, pos) (clamp((pos), 0, maxCoord##index))
#define GetCheckedOffPos(index, pos) (GetCheckedPos(index, Coord(index).xy + (pos) * Coord(index).zw))
Expand All @@ -110,6 +118,8 @@ static float2 maxCoord7;
#endif


#define MAGPIE_ENTRY(name) D2D_PS_ENTRY(name)

// 需要 main 函数的开头调用

void InitMagpieSampleInput() {
Expand Down
55 changes: 54 additions & 1 deletion MODULE_Common/DllMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "MitchellNetravaliScaleEffect.h"
#include "PixelScaleEffect.h"
#include "ContrastAdaptiveSharpenEffect.h"
#include "FSREffect.h"

#pragma comment(lib, "dxguid.lib")

Expand Down Expand Up @@ -357,6 +358,56 @@ API_DECLSPEC HRESULT CreateContrastAdaptiveSharpenEffect(
return S_OK;
}

API_DECLSPEC HRESULT CreateFSREffect(
ID2D1Factory1* d2dFactory,
ID2D1DeviceContext* d2dDC,
const nlohmann::json& props,
float fillScale,
std::pair<float, float>& scale,
ComPtr<ID2D1Effect>& effect
) {
bool isRegistered;
HRESULT hr = EffectUtils::IsEffectRegistered(d2dFactory, CLSID_MAGPIE_FSR_EFFECT, isRegistered);
if (FAILED(hr)) {
return hr;
}

if (!isRegistered) {
hr = FSREffect::Register(d2dFactory);
if (FAILED(hr)) {
return hr;
}
}

ComPtr<ID2D1Effect> result;
hr = d2dDC->CreateEffect(CLSID_MAGPIE_FSR_EFFECT, &result);
if (FAILED(hr)) {
return hr;
}

std::pair<float, float> scaleResult(1.0f, 1.0f);
// scale 属性
auto it = props.find("scale");
if (it != props.end()) {
hr = EffectUtils::ReadScaleProp(*it, fillScale, scale, scaleResult);
if (FAILED(hr)) {
return hr;
}

hr = result->SetValue(
FSREffect::PROP_SCALE,
D2D1_VECTOR_2F{ scaleResult.first, scaleResult.second }
);
if (FAILED(hr)) {
return hr;
}
}

effect = std::move(result);
scale.first *= scaleResult.first;
scale.second *= scaleResult.second;
return S_OK;
}

API_DECLSPEC HRESULT CreateEffect(
ID2D1Factory1* d2dFactory,
Expand All @@ -380,7 +431,9 @@ API_DECLSPEC HRESULT CreateEffect(
return CreateMitchellEffect(d2dFactory, d2dDC, props, fillScale, scale, effect);
} else if (e == "pixelScale") {
return CreatePixelScaleEffect(d2dFactory, d2dDC, props, effect, scale);
} else {
} else if (e == "FSR") {
return CreateFSREffect(d2dFactory, d2dDC, props, fillScale, scale, effect);
} else {
return E_INVALIDARG;
}
}
13 changes: 13 additions & 0 deletions MODULE_Common/EffectDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ DEFINE_GUID(GUID_MAGPIE_PIXEL_SCALE_SHADER,
DEFINE_GUID(GUID_MAGPIE_CONTRAST_ADAPTIVE_SHARPEN_SHADER,
0x3e7f23c3, 0x185f, 0x4ac6, 0xb6, 0xb8, 0xd5, 0x18, 0x7e, 0x69, 0xca, 0x4f);

// {6B5C18BA-B415-4EDC-9A1C-7D4876E94633}
DEFINE_GUID(GUID_MAGPIE_FFX_EASU_SHADER,
0x6b5c18ba, 0xb415, 0x4edc, 0x9a, 0x1c, 0x7d, 0x48, 0x76, 0xe9, 0x46, 0x33);
// {16C7F163-CBCC-4764-8AF8-07FC113747FA}
DEFINE_GUID(GUID_MAGPIE_FFX_RCAS_SHADER,
0x16c7f163, 0xcbcc, 0x4764, 0x8a, 0xf8, 0x7, 0xfc, 0x11, 0x37, 0x47, 0xfa);



// {FF65D2D6-4359-429D-B30A-F3F65B5AF20D}
Expand Down Expand Up @@ -58,6 +65,9 @@ DEFINE_GUID(CLSID_MAGPIE_LANCZOS_SCALE_EFFECT,
DEFINE_GUID(CLSID_MAGPIE_PIXEL_SCALE_EFFECT,
0xed9318d, 0xd624, 0x4582, 0x9c, 0xe2, 0x39, 0x9b, 0x79, 0x42, 0x8a, 0xb4);

// {0C748324-87A8-4A9E-AF73-38309CF9CF2C}
DEFINE_GUID(CLSID_MAGPIE_FSR_EFFECT,
0xc748324, 0x87a8, 0x4a9e, 0xaf, 0x73, 0x38, 0x30, 0x9c, 0xf9, 0xcf, 0x2c);


constexpr auto MAGPIE_ADAPTIVE_SHARPEN_PASS1_SHADER = L"shaders/AdaptiveSharpenPass1Shader.cso";
Expand All @@ -68,3 +78,6 @@ constexpr auto MAGPIE_LANCZOS6_SCALE_SHADER = L"shaders/Lanczos6ScaleShader.cso"
constexpr auto MAGPIE_JINC2_SCALE_SHADER = L"shaders/Jinc2ScaleShader.cso";
constexpr auto MAGPIE_MITCHELL_NETRAVALI_SCALE_SHADER = L"shaders/MitchellNetravaliScaleShader.cso";
constexpr auto MAGPIE_PIXEL_SCALE_SHADER = L"shaders/PixelScaleShader.cso";

constexpr auto MAGPIE_FFX_EASU_SHADER = L"shaders/FfxEasuShader.cso";
constexpr auto MAGPIE_FFX_RCAS_SHADER = L"shaders/FfxRcasShader.cso";
109 changes: 109 additions & 0 deletions MODULE_Common/FSREffect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#pragma once
#include "pch.h"
#include <EffectBase.h>
#include "EffectDefines.h"
#include "FfxEasuTransform.h"
#include "FfxRcasTransform.h"


class FSREffect : public EffectBase {
public:
IFACEMETHODIMP Initialize(
_In_ ID2D1EffectContext* pEffectContext,
_In_ ID2D1TransformGraph* pTransformGraph
) {
HRESULT hr = FfxEasuTransform::Create(pEffectContext, &_easuTransform);
if (FAILED(hr)) {
return hr;
}
hr = FfxRcasTransform::Create(pEffectContext, &_rcasTransform);
if (FAILED(hr)) {
return hr;
}

hr = pTransformGraph->AddNode(_easuTransform.Get());
if (FAILED(hr)) {
return hr;
}
hr = pTransformGraph->AddNode(_rcasTransform.Get());
if (FAILED(hr)) {
return hr;
}

hr = pTransformGraph->ConnectToEffectInput(0, _easuTransform.Get(), 0);
if (FAILED(hr)) {
return hr;
}
hr = pTransformGraph->ConnectNode(_easuTransform.Get(), _rcasTransform.Get(), 0);
if (FAILED(hr)) {
return hr;
}
hr = pTransformGraph->SetOutputNode(_rcasTransform.Get());
if (FAILED(hr)) {
return hr;
}

return S_OK;
}

HRESULT SetScale(D2D_VECTOR_2F value) {
if (value.x <= 0 || value.y <= 0) {
return E_INVALIDARG;
}

_easuTransform->SetScale(value);
return S_OK;
}

D2D_VECTOR_2F GetScale() const {
return _easuTransform->GetScale();
}

enum PROPS {
PROP_SCALE = 0,
};

static HRESULT Register(_In_ ID2D1Factory1* pFactory) {
const D2D1_PROPERTY_BINDING bindings[] =
{
D2D1_VALUE_TYPE_BINDING(L"Scale", &SetScale, &GetScale)
};

HRESULT hr = pFactory->RegisterEffectFromString(CLSID_MAGPIE_FSR_EFFECT, XML(
<?xml version='1.0'?>
<Effect>
<!--System Properties-->
<Property name='DisplayName' type='string' value='FSR'/>
<Property name='Author' type='string' value='Blinue'/>
<Property name='Category' type='string' value='FFX'/>
<Property name='Description' type='string' value='FSR'/>
<Inputs>
<Input name='Source'/>
</Inputs>
<Property name='Scale' type='vector2'>
<Property name='DisplayName' type='string' value='Scale'/>
<Property name='Default' type='vector2' value='(1,1)'/>
</Property>

</Effect>
), bindings, ARRAYSIZE(bindings), CreateEffect);

return hr;
}

static HRESULT CALLBACK CreateEffect(_Outptr_ IUnknown** ppEffectImpl) {
*ppEffectImpl = static_cast<ID2D1EffectImpl*>(new FSREffect());

if (*ppEffectImpl == nullptr) {
return E_OUTOFMEMORY;
}

return S_OK;
}

private:
FSREffect() {}

ComPtr<FfxEasuTransform> _easuTransform = nullptr;
ComPtr<FfxRcasTransform> _rcasTransform = nullptr;
};
45 changes: 45 additions & 0 deletions MODULE_Common/FfxEasuShader.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
cbuffer constants : register(b0) {
int2 srcSize : packoffset(c0.x);
int2 destSize : packoffset(c0.z);
};

#define MAGPIE_INPUT_COUNT 1
#include "common.hlsli"


#define A_GPU 1
#define A_HLSL 1
#include "ffx_a.hlsli"
#define FSR_EASU_F 1

AF4 FsrEasuRF(AF2 p) {
return GatherInputRed(0, p * srcSize * Coord(0).zw);
}
AF4 FsrEasuGF(AF2 p) {
return GatherInputGreen(0, p * srcSize * Coord(0).zw);
}
AF4 FsrEasuBF(AF2 p) {
return GatherInputBlue(0, p * srcSize * Coord(0).zw);
}


#include "ffx_fsr1.hlsli"


MAGPIE_ENTRY(main) {
float2 rcpSrc = rcp(srcSize);
float2 rcpDest = rcp(destSize);
float2 scale = srcSize * rcpDest;

float3 c;
FsrEasuF(
c,
Coord(0).xy / Coord(0).zw,
asuint(float4(scale, 0.5 * scale - 0.5)),
asuint(float4(rcpSrc.xy, rcpSrc.x, -rcpSrc.y)),
asuint(float4(-rcpSrc.x, 2 * rcpSrc.y, rcpSrc.x, 2 * rcpSrc.y)),
asuint(float4(0, 4 * rcpSrc.y, 0, 0))
);

return float4(c, 1.0f);
}
41 changes: 41 additions & 0 deletions MODULE_Common/FfxEasuTransform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once
#include "pch.h"
#include <SimpleScaleTransform.h>
#include "EffectDefines.h"


class FfxEasuTransform : public SimpleScaleTransform {
private:
FfxEasuTransform() : SimpleScaleTransform(GUID_MAGPIE_FFX_EASU_SHADER) {}
public:
static HRESULT Create(_In_ ID2D1EffectContext* d2dEC, _Outptr_ FfxEasuTransform** ppOutput) {
if (!ppOutput) {
return E_INVALIDARG;
}

HRESULT hr = LoadShader(d2dEC, MAGPIE_FFX_EASU_SHADER, GUID_MAGPIE_FFX_EASU_SHADER);
if (FAILED(hr)) {
return hr;
}

*ppOutput = new FfxEasuTransform();
return hr;
}

protected:
void _SetShaderContantBuffer(const SIZE& srcSize, const SIZE& destSize) override {
struct {
INT32 srcWidth;
INT32 srcHeight;
INT32 destWidth;
INT32 destHeight;
} shaderConstants{
srcSize.cx,
srcSize.cy,
destSize.cx,
destSize.cy
};

_drawInfo->SetPixelShaderConstantBuffer((BYTE*)&shaderConstants, sizeof(shaderConstants));
}
};
31 changes: 31 additions & 0 deletions MODULE_Common/FfxRcasShader.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
cbuffer constants : register(b0) {
uint2 srcSize : packoffset(c0.x);
float sharpness : packoffset(c0.z);
};

#define MAGPIE_INPUT_COUNT 1
#define MAGPIE_NO_CHECK
#include "common.hlsli"


#define A_GPU
#define A_HLSL
#include "ffx_a.hlsli"
#define FSR_RCAS_F

AF4 FsrRcasLoadF(ASU2 p) { return LoadInput(0, int3(ASU2(p), 0)); }
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}


#include "ffx_fsr1.hlsli"


MAGPIE_ENTRY(main) {
float s = AExp2F1(-sharpness);
varAF2(hSharp) = initAF2(s, s);

float3 c;
FsrRcasF(c.r, c.g, c.b, Coord(0).xy / Coord(0).zw, float4(AU1_AF1(s), AU1_AH2_AF2(hSharp), 0, 0));

return float4(c, 1.0f);
}
Loading

0 comments on commit 7f6c66f

Please sign in to comment.