Browse Source
Merge pull request #9539 from Wollnashorn/opengl-fsr
Merge pull request #9539 from Wollnashorn/opengl-fsr
video_core/opengl: Added FSR upscaling filter to the OpenGL rendererpull/15/merge
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 547 additions and 172 deletions
-
4src/video_core/CMakeLists.txt
-
148src/video_core/fsr.cpp
-
19src/video_core/fsr.h
-
30src/video_core/host_shaders/CMakeLists.txt
-
108src/video_core/host_shaders/opengl_fidelityfx_fsr.frag
-
9src/video_core/host_shaders/opengl_fidelityfx_fsr_easu.frag
-
9src/video_core/host_shaders/opengl_fidelityfx_fsr_rcas.frag
-
101src/video_core/renderer_opengl/gl_fsr.cpp
-
43src/video_core/renderer_opengl/gl_fsr.h
-
72src/video_core/renderer_opengl/renderer_opengl.cpp
-
3src/video_core/renderer_opengl/renderer_opengl.h
-
144src/video_core/renderer_vulkan/vk_fsr.cpp
-
2src/yuzu/configuration/configure_graphics.ui
-
9src/yuzu/main.cpp
@ -0,0 +1,148 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include <cmath>
|
|||
#include "video_core/fsr.h"
|
|||
|
|||
namespace FSR { |
|||
namespace { |
|||
// Reimplementations of the constant generating functions in ffx_fsr1.h
|
|||
// GCC generated a lot of warnings when using the official header.
|
|||
u32 AU1_AH1_AF1(f32 f) { |
|||
static constexpr u32 base[512]{ |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, |
|||
0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00, 0x2000, |
|||
0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x4400, 0x4800, 0x4c00, |
|||
0x5000, 0x5400, 0x5800, 0x5c00, 0x6000, 0x6400, 0x6800, 0x6c00, 0x7000, 0x7400, 0x7800, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, |
|||
0x8010, 0x8020, 0x8040, 0x8080, 0x8100, 0x8200, 0x8400, 0x8800, 0x8c00, 0x9000, 0x9400, |
|||
0x9800, 0x9c00, 0xa000, 0xa400, 0xa800, 0xac00, 0xb000, 0xb400, 0xb800, 0xbc00, 0xc000, |
|||
0xc400, 0xc800, 0xcc00, 0xd000, 0xd400, 0xd800, 0xdc00, 0xe000, 0xe400, 0xe800, 0xec00, |
|||
0xf000, 0xf400, 0xf800, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
}; |
|||
static constexpr s8 shift[512]{ |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x16, |
|||
0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, |
|||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, |
|||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, |
|||
0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, |
|||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, |
|||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, |
|||
}; |
|||
const u32 u = Common::BitCast<u32>(f); |
|||
const u32 i = u >> 23; |
|||
return base[i] + ((u & 0x7fffff) >> shift[i]); |
|||
} |
|||
|
|||
u32 AU1_AH2_AF2(f32 a[2]) { |
|||
return AU1_AH1_AF1(a[0]) + (AU1_AH1_AF1(a[1]) << 16); |
|||
} |
|||
|
|||
void FsrEasuCon(u32 con0[4], u32 con1[4], u32 con2[4], u32 con3[4], f32 inputViewportInPixelsX, |
|||
f32 inputViewportInPixelsY, f32 inputSizeInPixelsX, f32 inputSizeInPixelsY, |
|||
f32 outputSizeInPixelsX, f32 outputSizeInPixelsY) { |
|||
con0[0] = Common::BitCast<u32>(inputViewportInPixelsX / outputSizeInPixelsX); |
|||
con0[1] = Common::BitCast<u32>(inputViewportInPixelsY / outputSizeInPixelsY); |
|||
con0[2] = Common::BitCast<u32>(0.5f * inputViewportInPixelsX / outputSizeInPixelsX - 0.5f); |
|||
con0[3] = Common::BitCast<u32>(0.5f * inputViewportInPixelsY / outputSizeInPixelsY - 0.5f); |
|||
con1[0] = Common::BitCast<u32>(1.0f / inputSizeInPixelsX); |
|||
con1[1] = Common::BitCast<u32>(1.0f / inputSizeInPixelsY); |
|||
con1[2] = Common::BitCast<u32>(1.0f / inputSizeInPixelsX); |
|||
con1[3] = Common::BitCast<u32>(-1.0f / inputSizeInPixelsY); |
|||
con2[0] = Common::BitCast<u32>(-1.0f / inputSizeInPixelsX); |
|||
con2[1] = Common::BitCast<u32>(2.0f / inputSizeInPixelsY); |
|||
con2[2] = Common::BitCast<u32>(1.0f / inputSizeInPixelsX); |
|||
con2[3] = Common::BitCast<u32>(2.0f / inputSizeInPixelsY); |
|||
con3[0] = Common::BitCast<u32>(0.0f / inputSizeInPixelsX); |
|||
con3[1] = Common::BitCast<u32>(4.0f / inputSizeInPixelsY); |
|||
con3[2] = con3[3] = 0; |
|||
} |
|||
} // Anonymous namespace
|
|||
|
|||
void FsrEasuConOffset(u32 con0[4], u32 con1[4], u32 con2[4], u32 con3[4], |
|||
f32 inputViewportInPixelsX, f32 inputViewportInPixelsY, |
|||
f32 inputSizeInPixelsX, f32 inputSizeInPixelsY, f32 outputSizeInPixelsX, |
|||
f32 outputSizeInPixelsY, f32 inputOffsetInPixelsX, f32 inputOffsetInPixelsY) { |
|||
FsrEasuCon(con0, con1, con2, con3, inputViewportInPixelsX, inputViewportInPixelsY, |
|||
inputSizeInPixelsX, inputSizeInPixelsY, outputSizeInPixelsX, outputSizeInPixelsY); |
|||
con0[2] = Common::BitCast<u32>(0.5f * inputViewportInPixelsX / outputSizeInPixelsX - 0.5f + |
|||
inputOffsetInPixelsX); |
|||
con0[3] = Common::BitCast<u32>(0.5f * inputViewportInPixelsY / outputSizeInPixelsY - 0.5f + |
|||
inputOffsetInPixelsY); |
|||
} |
|||
|
|||
void FsrRcasCon(u32* con, f32 sharpness) { |
|||
sharpness = std::exp2f(-sharpness); |
|||
f32 hSharp[2]{sharpness, sharpness}; |
|||
con[0] = Common::BitCast<u32>(sharpness); |
|||
con[1] = AU1_AH2_AF2(hSharp); |
|||
con[2] = 0; |
|||
con[3] = 0; |
|||
} |
|||
} // namespace FSR
|
|||
@ -0,0 +1,19 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/bit_cast.h" |
|||
#include "common/common_types.h" |
|||
|
|||
namespace FSR { |
|||
// Reimplementations of the constant generating functions in ffx_fsr1.h |
|||
// GCC generated a lot of warnings when using the official header. |
|||
void FsrEasuConOffset(u32 con0[4], u32 con1[4], u32 con2[4], u32 con3[4], |
|||
f32 inputViewportInPixelsX, f32 inputViewportInPixelsY, |
|||
f32 inputSizeInPixelsX, f32 inputSizeInPixelsY, f32 outputSizeInPixelsX, |
|||
f32 outputSizeInPixelsY, f32 inputOffsetInPixelsX, f32 inputOffsetInPixelsY); |
|||
|
|||
void FsrRcasCon(u32* con, f32 sharpness); |
|||
|
|||
} // namespace FSR |
|||
@ -0,0 +1,108 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
//!#version 460 core |
|||
#extension GL_ARB_separate_shader_objects : enable |
|||
#extension GL_ARB_shading_language_420pack : enable |
|||
|
|||
#extension GL_AMD_gpu_shader_half_float : enable |
|||
#extension GL_NV_gpu_shader5 : enable |
|||
|
|||
// FidelityFX Super Resolution Sample |
|||
// |
|||
// 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. |
|||
|
|||
layout (location = 0) uniform uvec4 constants[4]; |
|||
|
|||
#define A_GPU 1 |
|||
#define A_GLSL 1 |
|||
|
|||
#ifdef YUZU_USE_FP16 |
|||
#define A_HALF |
|||
#endif |
|||
#include "ffx_a.h" |
|||
|
|||
#ifndef YUZU_USE_FP16 |
|||
layout (binding=0) uniform sampler2D InputTexture; |
|||
#if USE_EASU |
|||
#define FSR_EASU_F 1 |
|||
AF4 FsrEasuRF(AF2 p) { AF4 res = textureGather(InputTexture, p, 0); return res; } |
|||
AF4 FsrEasuGF(AF2 p) { AF4 res = textureGather(InputTexture, p, 1); return res; } |
|||
AF4 FsrEasuBF(AF2 p) { AF4 res = textureGather(InputTexture, p, 2); return res; } |
|||
#endif |
|||
#if USE_RCAS |
|||
#define FSR_RCAS_F |
|||
AF4 FsrRcasLoadF(ASU2 p) { return texelFetch(InputTexture, ASU2(p), 0); } |
|||
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {} |
|||
#endif |
|||
#else |
|||
layout (binding=0) uniform sampler2D InputTexture; |
|||
#if USE_EASU |
|||
#define FSR_EASU_H 1 |
|||
AH4 FsrEasuRH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 0)); return res; } |
|||
AH4 FsrEasuGH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 1)); return res; } |
|||
AH4 FsrEasuBH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 2)); return res; } |
|||
#endif |
|||
#if USE_RCAS |
|||
#define FSR_RCAS_H |
|||
AH4 FsrRcasLoadH(ASW2 p) { return AH4(texelFetch(InputTexture, ASU2(p), 0)); } |
|||
void FsrRcasInputH(inout AH1 r,inout AH1 g,inout AH1 b){} |
|||
#endif |
|||
#endif |
|||
|
|||
#include "ffx_fsr1.h" |
|||
|
|||
#if USE_RCAS |
|||
layout(location = 0) in vec2 frag_texcoord; |
|||
#endif |
|||
layout (location = 0) out vec4 frag_color; |
|||
|
|||
void CurrFilter(AU2 pos) |
|||
{ |
|||
#if USE_EASU |
|||
#ifndef YUZU_USE_FP16 |
|||
AF3 c; |
|||
FsrEasuF(c, pos, constants[0], constants[1], constants[2], constants[3]); |
|||
frag_color = AF4(c, 1.0); |
|||
#else |
|||
AH3 c; |
|||
FsrEasuH(c, pos, constants[0], constants[1], constants[2], constants[3]); |
|||
frag_color = AH4(c, 1.0); |
|||
#endif |
|||
#endif |
|||
#if USE_RCAS |
|||
#ifndef YUZU_USE_FP16 |
|||
AF3 c; |
|||
FsrRcasF(c.r, c.g, c.b, pos, constants[0]); |
|||
frag_color = AF4(c, 1.0); |
|||
#else |
|||
AH3 c; |
|||
FsrRcasH(c.r, c.g, c.b, pos, constants[0]); |
|||
frag_color = AH4(c, 1.0); |
|||
#endif |
|||
#endif |
|||
} |
|||
|
|||
void main() |
|||
{ |
|||
#if USE_RCAS |
|||
CurrFilter(AU2(frag_texcoord * vec2(textureSize(InputTexture, 0)))); |
|||
#else |
|||
CurrFilter(AU2(gl_FragCoord.xy)); |
|||
#endif |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#version 460 core |
|||
#extension GL_GOOGLE_include_directive : enable |
|||
|
|||
#define USE_EASU 1 |
|||
|
|||
#include "opengl_fidelityfx_fsr.frag" |
|||
@ -0,0 +1,9 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#version 460 core |
|||
#extension GL_GOOGLE_include_directive : enable |
|||
|
|||
#define USE_RCAS 1 |
|||
|
|||
#include "opengl_fidelityfx_fsr.frag" |
|||
@ -0,0 +1,101 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "common/settings.h"
|
|||
#include "video_core/fsr.h"
|
|||
#include "video_core/renderer_opengl/gl_fsr.h"
|
|||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
|||
#include "video_core/renderer_opengl/gl_shader_util.h"
|
|||
|
|||
namespace OpenGL { |
|||
using namespace FSR; |
|||
|
|||
using FsrConstants = std::array<u32, 4 * 4>; |
|||
|
|||
FSR::FSR(std::string_view fsr_vertex_source, std::string_view fsr_easu_source, |
|||
std::string_view fsr_rcas_source) |
|||
: fsr_vertex{CreateProgram(fsr_vertex_source, GL_VERTEX_SHADER)}, |
|||
fsr_easu_frag{CreateProgram(fsr_easu_source, GL_FRAGMENT_SHADER)}, |
|||
fsr_rcas_frag{CreateProgram(fsr_rcas_source, GL_FRAGMENT_SHADER)} { |
|||
glProgramUniform2f(fsr_vertex.handle, 0, 1.0f, 1.0f); |
|||
glProgramUniform2f(fsr_vertex.handle, 1, 0.0f, 0.0f); |
|||
} |
|||
|
|||
FSR::~FSR() = default; |
|||
|
|||
void FSR::Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen, |
|||
u32 input_image_width, u32 input_image_height, |
|||
const Common::Rectangle<int>& crop_rect) { |
|||
|
|||
const auto output_image_width = screen.GetWidth(); |
|||
const auto output_image_height = screen.GetHeight(); |
|||
|
|||
if (fsr_intermediate_tex.handle) { |
|||
GLint fsr_tex_width, fsr_tex_height; |
|||
glGetTextureLevelParameteriv(fsr_intermediate_tex.handle, 0, GL_TEXTURE_WIDTH, |
|||
&fsr_tex_width); |
|||
glGetTextureLevelParameteriv(fsr_intermediate_tex.handle, 0, GL_TEXTURE_HEIGHT, |
|||
&fsr_tex_height); |
|||
if (static_cast<u32>(fsr_tex_width) != output_image_width || |
|||
static_cast<u32>(fsr_tex_height) != output_image_height) { |
|||
fsr_intermediate_tex.Release(); |
|||
} |
|||
} |
|||
if (!fsr_intermediate_tex.handle) { |
|||
fsr_intermediate_tex.Create(GL_TEXTURE_2D); |
|||
glTextureStorage2D(fsr_intermediate_tex.handle, 1, GL_RGB16F, output_image_width, |
|||
output_image_height); |
|||
glNamedFramebufferTexture(fsr_framebuffer.handle, GL_COLOR_ATTACHMENT0, |
|||
fsr_intermediate_tex.handle, 0); |
|||
} |
|||
|
|||
GLint old_draw_fb; |
|||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb); |
|||
|
|||
glFrontFace(GL_CW); |
|||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fsr_framebuffer.handle); |
|||
glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(output_image_width), |
|||
static_cast<GLfloat>(output_image_height)); |
|||
|
|||
FsrConstants constants; |
|||
FsrEasuConOffset( |
|||
constants.data() + 0, constants.data() + 4, constants.data() + 8, constants.data() + 12, |
|||
|
|||
static_cast<f32>(crop_rect.GetWidth()), static_cast<f32>(crop_rect.GetHeight()), |
|||
static_cast<f32>(input_image_width), static_cast<f32>(input_image_height), |
|||
static_cast<f32>(output_image_width), static_cast<f32>(output_image_height), |
|||
static_cast<f32>(crop_rect.left), static_cast<f32>(crop_rect.top)); |
|||
|
|||
glProgramUniform4uiv(fsr_easu_frag.handle, 0, sizeof(constants), std::data(constants)); |
|||
|
|||
program_manager.BindPresentPrograms(fsr_vertex.handle, fsr_easu_frag.handle); |
|||
glDrawArrays(GL_TRIANGLES, 0, 3); |
|||
|
|||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb); |
|||
glBindTextureUnit(0, fsr_intermediate_tex.handle); |
|||
|
|||
const float sharpening = |
|||
static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f; |
|||
|
|||
FsrRcasCon(constants.data(), sharpening); |
|||
glProgramUniform4uiv(fsr_rcas_frag.handle, 0, sizeof(constants), std::data(constants)); |
|||
} |
|||
|
|||
void FSR::InitBuffers() { |
|||
fsr_framebuffer.Create(); |
|||
} |
|||
|
|||
void FSR::ReleaseBuffers() { |
|||
fsr_framebuffer.Release(); |
|||
fsr_intermediate_tex.Release(); |
|||
} |
|||
|
|||
const OGLProgram& FSR::GetPresentFragmentProgram() const noexcept { |
|||
return fsr_rcas_frag; |
|||
} |
|||
|
|||
bool FSR::AreBuffersInitialized() const noexcept { |
|||
return fsr_framebuffer.handle; |
|||
} |
|||
|
|||
} // namespace OpenGL
|
|||
@ -0,0 +1,43 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <string_view> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "common/math_util.h" |
|||
#include "video_core/fsr.h" |
|||
#include "video_core/renderer_opengl/gl_resource_manager.h" |
|||
|
|||
namespace OpenGL { |
|||
|
|||
class ProgramManager; |
|||
|
|||
class FSR { |
|||
public: |
|||
explicit FSR(std::string_view fsr_vertex_source, std::string_view fsr_easu_source, |
|||
std::string_view fsr_rcas_source); |
|||
~FSR(); |
|||
|
|||
void Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen, |
|||
u32 input_image_width, u32 input_image_height, |
|||
const Common::Rectangle<int>& crop_rect); |
|||
|
|||
void InitBuffers(); |
|||
|
|||
void ReleaseBuffers(); |
|||
|
|||
[[nodiscard]] const OGLProgram& GetPresentFragmentProgram() const noexcept; |
|||
|
|||
[[nodiscard]] bool AreBuffersInitialized() const noexcept; |
|||
|
|||
private: |
|||
OGLFramebuffer fsr_framebuffer; |
|||
OGLProgram fsr_vertex; |
|||
OGLProgram fsr_easu_frag; |
|||
OGLProgram fsr_rcas_frag; |
|||
OGLTexture fsr_intermediate_tex; |
|||
}; |
|||
|
|||
} // namespace OpenGL |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue