Skip to content

Commit 7f6c66f

Browse files
committed
初步移植FSR
1 parent 463c668 commit 7f6c66f

15 files changed

+4444
-4
lines changed

‎EffectCommon/EffectCommon.vcxproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<ItemGroup Label="ProjectConfigurations">
44
<ProjectConfiguration Include="Debug|Win32">

‎EffectCommon/EffectCommon.vcxproj.filters‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
<Filter>着色器</Filter>
4343
</None>
4444
<None Include="packages.config" />
45+
<None Include="ffx_a.hlsli">
46+
<Filter>着色器</Filter>
47+
</None>
4548
</ItemGroup>
4649
<ItemGroup>
4750
<FxCompile Include="RGB2YUVShader.hlsl">

‎EffectCommon/common.hlsli‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,17 @@ static float2 maxCoord7;
9898
#define SampleInputCur(index) (SampleInput(index, Coord(index).xy))
9999
#define SampleInputOff(index, pos) (SampleInput(index, Coord(index).xy + (pos) * Coord(index).zw))
100100

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

104+
// Gather
105+
#define GatherInputRed(index, pos) (InputTexture##index.GatherRed(InputSampler##index, (pos), 0))
106+
#define GatherInputGreen(index, pos) (InputTexture##index.GatherGreen(InputSampler##index, (pos), 0))
107+
#define GatherInputBlue(index, pos) (InputTexture##index.GatherBlue(InputSampler##index, (pos), 0))
108+
109+
// Load
110+
#define LoadInput(index, pos) (InputTexture##index.Load(pos))
111+
104112
#ifndef MAGPIE_NO_CHECK
105113
#define GetCheckedPos(index, pos) (clamp((pos), 0, maxCoord##index))
106114
#define GetCheckedOffPos(index, pos) (GetCheckedPos(index, Coord(index).xy + (pos) * Coord(index).zw))
@@ -110,6 +118,8 @@ static float2 maxCoord7;
110118
#endif
111119

112120

121+
#define MAGPIE_ENTRY(name) D2D_PS_ENTRY(name)
122+
113123
// 需要 main 函数的开头调用
114124

115125
void InitMagpieSampleInput() {

‎MODULE_Common/DllMain.cpp‎

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "MitchellNetravaliScaleEffect.h"
88
#include "PixelScaleEffect.h"
99
#include "ContrastAdaptiveSharpenEffect.h"
10+
#include "FSREffect.h"
1011

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

@@ -357,6 +358,56 @@ API_DECLSPEC HRESULT CreateContrastAdaptiveSharpenEffect(
357358
return S_OK;
358359
}
359360

361+
API_DECLSPEC HRESULT CreateFSREffect(
362+
ID2D1Factory1* d2dFactory,
363+
ID2D1DeviceContext* d2dDC,
364+
const nlohmann::json& props,
365+
float fillScale,
366+
std::pair<float, float>& scale,
367+
ComPtr<ID2D1Effect>& effect
368+
) {
369+
bool isRegistered;
370+
HRESULT hr = EffectUtils::IsEffectRegistered(d2dFactory, CLSID_MAGPIE_FSR_EFFECT, isRegistered);
371+
if (FAILED(hr)) {
372+
return hr;
373+
}
374+
375+
if (!isRegistered) {
376+
hr = FSREffect::Register(d2dFactory);
377+
if (FAILED(hr)) {
378+
return hr;
379+
}
380+
}
381+
382+
ComPtr<ID2D1Effect> result;
383+
hr = d2dDC->CreateEffect(CLSID_MAGPIE_FSR_EFFECT, &result);
384+
if (FAILED(hr)) {
385+
return hr;
386+
}
387+
388+
std::pair<float, float> scaleResult(1.0f, 1.0f);
389+
// scale 属性
390+
auto it = props.find("scale");
391+
if (it != props.end()) {
392+
hr = EffectUtils::ReadScaleProp(*it, fillScale, scale, scaleResult);
393+
if (FAILED(hr)) {
394+
return hr;
395+
}
396+
397+
hr = result->SetValue(
398+
FSREffect::PROP_SCALE,
399+
D2D1_VECTOR_2F{ scaleResult.first, scaleResult.second }
400+
);
401+
if (FAILED(hr)) {
402+
return hr;
403+
}
404+
}
405+
406+
effect = std::move(result);
407+
scale.first *= scaleResult.first;
408+
scale.second *= scaleResult.second;
409+
return S_OK;
410+
}
360411

361412
API_DECLSPEC HRESULT CreateEffect(
362413
ID2D1Factory1* d2dFactory,
@@ -380,7 +431,9 @@ API_DECLSPEC HRESULT CreateEffect(
380431
return CreateMitchellEffect(d2dFactory, d2dDC, props, fillScale, scale, effect);
381432
} else if (e == "pixelScale") {
382433
return CreatePixelScaleEffect(d2dFactory, d2dDC, props, effect, scale);
383-
} else {
434+
} else if (e == "FSR") {
435+
return CreateFSREffect(d2dFactory, d2dDC, props, fillScale, scale, effect);
436+
} else {
384437
return E_INVALIDARG;
385438
}
386439
}

‎MODULE_Common/EffectDefines.h‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ DEFINE_GUID(GUID_MAGPIE_PIXEL_SCALE_SHADER,
3131
DEFINE_GUID(GUID_MAGPIE_CONTRAST_ADAPTIVE_SHARPEN_SHADER,
3232
0x3e7f23c3, 0x185f, 0x4ac6, 0xb6, 0xb8, 0xd5, 0x18, 0x7e, 0x69, 0xca, 0x4f);
3333

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

3542

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

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

6272

6373
constexpr auto MAGPIE_ADAPTIVE_SHARPEN_PASS1_SHADER = L"shaders/AdaptiveSharpenPass1Shader.cso";
@@ -68,3 +78,6 @@ constexpr auto MAGPIE_LANCZOS6_SCALE_SHADER = L"shaders/Lanczos6ScaleShader.cso"
6878
constexpr auto MAGPIE_JINC2_SCALE_SHADER = L"shaders/Jinc2ScaleShader.cso";
6979
constexpr auto MAGPIE_MITCHELL_NETRAVALI_SCALE_SHADER = L"shaders/MitchellNetravaliScaleShader.cso";
7080
constexpr auto MAGPIE_PIXEL_SCALE_SHADER = L"shaders/PixelScaleShader.cso";
81+
82+
constexpr auto MAGPIE_FFX_EASU_SHADER = L"shaders/FfxEasuShader.cso";
83+
constexpr auto MAGPIE_FFX_RCAS_SHADER = L"shaders/FfxRcasShader.cso";

‎MODULE_Common/FSREffect.h‎

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#pragma once
2+
#include "pch.h"
3+
#include <EffectBase.h>
4+
#include "EffectDefines.h"
5+
#include "FfxEasuTransform.h"
6+
#include "FfxRcasTransform.h"
7+
8+
9+
class FSREffect : public EffectBase {
10+
public:
11+
IFACEMETHODIMP Initialize(
12+
_In_ ID2D1EffectContext* pEffectContext,
13+
_In_ ID2D1TransformGraph* pTransformGraph
14+
) {
15+
HRESULT hr = FfxEasuTransform::Create(pEffectContext, &_easuTransform);
16+
if (FAILED(hr)) {
17+
return hr;
18+
}
19+
hr = FfxRcasTransform::Create(pEffectContext, &_rcasTransform);
20+
if (FAILED(hr)) {
21+
return hr;
22+
}
23+
24+
hr = pTransformGraph->AddNode(_easuTransform.Get());
25+
if (FAILED(hr)) {
26+
return hr;
27+
}
28+
hr = pTransformGraph->AddNode(_rcasTransform.Get());
29+
if (FAILED(hr)) {
30+
return hr;
31+
}
32+
33+
hr = pTransformGraph->ConnectToEffectInput(0, _easuTransform.Get(), 0);
34+
if (FAILED(hr)) {
35+
return hr;
36+
}
37+
hr = pTransformGraph->ConnectNode(_easuTransform.Get(), _rcasTransform.Get(), 0);
38+
if (FAILED(hr)) {
39+
return hr;
40+
}
41+
hr = pTransformGraph->SetOutputNode(_rcasTransform.Get());
42+
if (FAILED(hr)) {
43+
return hr;
44+
}
45+
46+
return S_OK;
47+
}
48+
49+
HRESULT SetScale(D2D_VECTOR_2F value) {
50+
if (value.x <= 0 || value.y <= 0) {
51+
return E_INVALIDARG;
52+
}
53+
54+
_easuTransform->SetScale(value);
55+
return S_OK;
56+
}
57+
58+
D2D_VECTOR_2F GetScale() const {
59+
return _easuTransform->GetScale();
60+
}
61+
62+
enum PROPS {
63+
PROP_SCALE = 0,
64+
};
65+
66+
static HRESULT Register(_In_ ID2D1Factory1* pFactory) {
67+
const D2D1_PROPERTY_BINDING bindings[] =
68+
{
69+
D2D1_VALUE_TYPE_BINDING(L"Scale", &SetScale, &GetScale)
70+
};
71+
72+
HRESULT hr = pFactory->RegisterEffectFromString(CLSID_MAGPIE_FSR_EFFECT, XML(
73+
<?xml version='1.0'?>
74+
<Effect>
75+
<!--System Properties-->
76+
<Property name='DisplayName' type='string' value='FSR'/>
77+
<Property name='Author' type='string' value='Blinue'/>
78+
<Property name='Category' type='string' value='FFX'/>
79+
<Property name='Description' type='string' value='FSR'/>
80+
<Inputs>
81+
<Input name='Source'/>
82+
</Inputs>
83+
<Property name='Scale' type='vector2'>
84+
<Property name='DisplayName' type='string' value='Scale'/>
85+
<Property name='Default' type='vector2' value='(1,1)'/>
86+
</Property>
87+
88+
</Effect>
89+
), bindings, ARRAYSIZE(bindings), CreateEffect);
90+
91+
return hr;
92+
}
93+
94+
static HRESULT CALLBACK CreateEffect(_Outptr_ IUnknown** ppEffectImpl) {
95+
*ppEffectImpl = static_cast<ID2D1EffectImpl*>(new FSREffect());
96+
97+
if (*ppEffectImpl == nullptr) {
98+
return E_OUTOFMEMORY;
99+
}
100+
101+
return S_OK;
102+
}
103+
104+
private:
105+
FSREffect() {}
106+
107+
ComPtr<FfxEasuTransform> _easuTransform = nullptr;
108+
ComPtr<FfxRcasTransform> _rcasTransform = nullptr;
109+
};

‎MODULE_Common/FfxEasuShader.hlsl‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
cbuffer constants : register(b0) {
2+
int2 srcSize : packoffset(c0.x);
3+
int2 destSize : packoffset(c0.z);
4+
};
5+
6+
#define MAGPIE_INPUT_COUNT 1
7+
#include "common.hlsli"
8+
9+
10+
#define A_GPU 1
11+
#define A_HLSL 1
12+
#include "ffx_a.hlsli"
13+
#define FSR_EASU_F 1
14+
15+
AF4 FsrEasuRF(AF2 p) {
16+
return GatherInputRed(0, p * srcSize * Coord(0).zw);
17+
}
18+
AF4 FsrEasuGF(AF2 p) {
19+
return GatherInputGreen(0, p * srcSize * Coord(0).zw);
20+
}
21+
AF4 FsrEasuBF(AF2 p) {
22+
return GatherInputBlue(0, p * srcSize * Coord(0).zw);
23+
}
24+
25+
26+
#include "ffx_fsr1.hlsli"
27+
28+
29+
MAGPIE_ENTRY(main) {
30+
float2 rcpSrc = rcp(srcSize);
31+
float2 rcpDest = rcp(destSize);
32+
float2 scale = srcSize * rcpDest;
33+
34+
float3 c;
35+
FsrEasuF(
36+
c,
37+
Coord(0).xy / Coord(0).zw,
38+
asuint(float4(scale, 0.5 * scale - 0.5)),
39+
asuint(float4(rcpSrc.xy, rcpSrc.x, -rcpSrc.y)),
40+
asuint(float4(-rcpSrc.x, 2 * rcpSrc.y, rcpSrc.x, 2 * rcpSrc.y)),
41+
asuint(float4(0, 4 * rcpSrc.y, 0, 0))
42+
);
43+
44+
return float4(c, 1.0f);
45+
}

‎MODULE_Common/FfxEasuTransform.h‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#pragma once
2+
#include "pch.h"
3+
#include <SimpleScaleTransform.h>
4+
#include "EffectDefines.h"
5+
6+
7+
class FfxEasuTransform : public SimpleScaleTransform {
8+
private:
9+
FfxEasuTransform() : SimpleScaleTransform(GUID_MAGPIE_FFX_EASU_SHADER) {}
10+
public:
11+
static HRESULT Create(_In_ ID2D1EffectContext* d2dEC, _Outptr_ FfxEasuTransform** ppOutput) {
12+
if (!ppOutput) {
13+
return E_INVALIDARG;
14+
}
15+
16+
HRESULT hr = LoadShader(d2dEC, MAGPIE_FFX_EASU_SHADER, GUID_MAGPIE_FFX_EASU_SHADER);
17+
if (FAILED(hr)) {
18+
return hr;
19+
}
20+
21+
*ppOutput = new FfxEasuTransform();
22+
return hr;
23+
}
24+
25+
protected:
26+
void _SetShaderContantBuffer(const SIZE& srcSize, const SIZE& destSize) override {
27+
struct {
28+
INT32 srcWidth;
29+
INT32 srcHeight;
30+
INT32 destWidth;
31+
INT32 destHeight;
32+
} shaderConstants{
33+
srcSize.cx,
34+
srcSize.cy,
35+
destSize.cx,
36+
destSize.cy
37+
};
38+
39+
_drawInfo->SetPixelShaderConstantBuffer((BYTE*)&shaderConstants, sizeof(shaderConstants));
40+
}
41+
};

‎MODULE_Common/FfxRcasShader.hlsl‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
cbuffer constants : register(b0) {
2+
uint2 srcSize : packoffset(c0.x);
3+
float sharpness : packoffset(c0.z);
4+
};
5+
6+
#define MAGPIE_INPUT_COUNT 1
7+
#define MAGPIE_NO_CHECK
8+
#include "common.hlsli"
9+
10+
11+
#define A_GPU
12+
#define A_HLSL
13+
#include "ffx_a.hlsli"
14+
#define FSR_RCAS_F
15+
16+
AF4 FsrRcasLoadF(ASU2 p) { return LoadInput(0, int3(ASU2(p), 0)); }
17+
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
18+
19+
20+
#include "ffx_fsr1.hlsli"
21+
22+
23+
MAGPIE_ENTRY(main) {
24+
float s = AExp2F1(-sharpness);
25+
varAF2(hSharp) = initAF2(s, s);
26+
27+
float3 c;
28+
FsrRcasF(c.r, c.g, c.b, Coord(0).xy / Coord(0).zw, float4(AU1_AF1(s), AU1_AH2_AF2(hSharp), 0, 0));
29+
30+
return float4(c, 1.0f);
31+
}

0 commit comments

Comments
 (0)