|
|
|
@ -2,8 +2,11 @@ |
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
#include "common/bit_cast.h"
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "common/div_ceil.h"
|
|
|
|
|
|
|
|
#include "video_core/host_shaders/vulkan_fidelityfx_fsr_easu_fp16_comp_spv.h"
|
|
|
|
#include "video_core/host_shaders/vulkan_fidelityfx_fsr_easu_fp32_comp_spv.h"
|
|
|
|
#include "video_core/host_shaders/vulkan_fidelityfx_fsr_rcas_fp16_comp_spv.h"
|
|
|
|
@ -13,9 +16,11 @@ |
|
|
|
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
|
|
|
#include "video_core/vulkan_common/vulkan_device.h"
|
|
|
|
|
|
|
|
namespace Vulkan { |
|
|
|
namespace { |
|
|
|
// Reimplementations of the constant generating functions in ffx_fsr1.h
|
|
|
|
// GCC generated a lot of warnings when using the official header.
|
|
|
|
static u32 AU1_AH1_AF1(f32 f) { |
|
|
|
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, |
|
|
|
@ -102,59 +107,56 @@ static u32 AU1_AH1_AF1(f32 f) { |
|
|
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|
|
|
0x18, 0x18, |
|
|
|
}; |
|
|
|
auto u = std::bit_cast<u32>(f); |
|
|
|
u32 i = u >> 23; |
|
|
|
const u32 u = Common::BitCast<u32>(f); |
|
|
|
const u32 i = u >> 23; |
|
|
|
return base[i] + ((u & 0x7fffff) >> shift[i]); |
|
|
|
} |
|
|
|
|
|
|
|
static u32 AU1_AH2_AF2(f32 a[2]) { |
|
|
|
u32 AU1_AH2_AF2(f32 a[2]) { |
|
|
|
return AU1_AH1_AF1(a[0]) + (AU1_AH1_AF1(a[1]) << 16); |
|
|
|
} |
|
|
|
|
|
|
|
static 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] = std::bit_cast<u32>(inputViewportInPixelsX / outputSizeInPixelsX); |
|
|
|
con0[1] = std::bit_cast<u32>(inputViewportInPixelsY / outputSizeInPixelsY); |
|
|
|
con0[2] = std::bit_cast<u32>(0.5f * inputViewportInPixelsX / outputSizeInPixelsX - 0.5f); |
|
|
|
con0[3] = std::bit_cast<u32>(0.5f * inputViewportInPixelsY / outputSizeInPixelsY - 0.5f); |
|
|
|
con1[0] = std::bit_cast<u32>(1.0f / inputSizeInPixelsX); |
|
|
|
con1[1] = std::bit_cast<u32>(1.0f / inputSizeInPixelsY); |
|
|
|
con1[2] = std::bit_cast<u32>(1.0f / inputSizeInPixelsX); |
|
|
|
con1[3] = std::bit_cast<u32>(-1.0f / inputSizeInPixelsY); |
|
|
|
con2[0] = std::bit_cast<u32>(-1.0f / inputSizeInPixelsX); |
|
|
|
con2[1] = std::bit_cast<u32>(2.0f / inputSizeInPixelsY); |
|
|
|
con2[2] = std::bit_cast<u32>(1.0f / inputSizeInPixelsX); |
|
|
|
con2[3] = std::bit_cast<u32>(2.0f / inputSizeInPixelsY); |
|
|
|
con3[0] = std::bit_cast<u32>(0.0f / inputSizeInPixelsX); |
|
|
|
con3[1] = std::bit_cast<u32>(4.0f / inputSizeInPixelsY); |
|
|
|
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; |
|
|
|
} |
|
|
|
|
|
|
|
static 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 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] = std::bit_cast<u32>(0.5f * inputViewportInPixelsX / outputSizeInPixelsX - 0.5f + |
|
|
|
inputOffsetInPixelsX); |
|
|
|
con0[3] = std::bit_cast<u32>(0.5f * inputViewportInPixelsY / outputSizeInPixelsY - 0.5f + |
|
|
|
inputOffsetInPixelsY); |
|
|
|
con0[2] = Common::BitCast<u32>(0.5f * inputViewportInPixelsX / outputSizeInPixelsX - 0.5f + |
|
|
|
inputOffsetInPixelsX); |
|
|
|
con0[3] = Common::BitCast<u32>(0.5f * inputViewportInPixelsY / outputSizeInPixelsY - 0.5f + |
|
|
|
inputOffsetInPixelsY); |
|
|
|
} |
|
|
|
|
|
|
|
static void FsrRcasCon(u32* con, f32 sharpness) { |
|
|
|
void FsrRcasCon(u32* con, f32 sharpness) { |
|
|
|
sharpness = std::exp2f(-sharpness); |
|
|
|
f32 hSharp[2]{sharpness, sharpness}; |
|
|
|
con[0] = std::bit_cast<u32>(sharpness); |
|
|
|
con[0] = Common::BitCast<u32>(sharpness); |
|
|
|
con[1] = AU1_AH2_AF2(hSharp); |
|
|
|
con[2] = 0; |
|
|
|
con[3] = 0; |
|
|
|
} |
|
|
|
|
|
|
|
namespace Vulkan { |
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
FSR::FSR(const Device& device_, MemoryAllocator& memory_allocator_, size_t image_count_, |
|
|
|
VkExtent2D output_size_) |
|
|
|
|