mirror of
https://github.com/ublue-os/bazzite.git
synced 2025-01-29 00:32:52 +00:00
1013 lines
37 KiB
Diff
1013 lines
37 KiB
Diff
From 564a689c2b293d2e894bf1edb14eb0f78bde8725 Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Sat, 5 Oct 2024 14:40:23 -0300
|
||
Subject: [PATCH 1/9] Partial bicubic code adaptation
|
||
|
||
---
|
||
src/Backends/SDLBackend.cpp | 4 +
|
||
src/Backends/WaylandBackend.cpp | 1 +
|
||
src/main.cpp | 29 ++++++
|
||
src/main.hpp | 15 +++
|
||
src/meson.build | 1 +
|
||
src/rendervulkan.cpp | 64 +++++++++++-
|
||
src/rendervulkan.hpp | 2 +
|
||
src/shaders/bicubic.h | 44 ++++++++
|
||
src/shaders/cs_bicubic.comp | 176 ++++++++++++++++++++++++++++++++
|
||
src/steamcompmgr.cpp | 6 ++
|
||
10 files changed, 341 insertions(+), 1 deletion(-)
|
||
create mode 100644 src/shaders/bicubic.h
|
||
create mode 100644 src/shaders/cs_bicubic.comp
|
||
|
||
diff --git a/src/Backends/SDLBackend.cpp b/src/Backends/SDLBackend.cpp
|
||
index 6d50f8d34..c24b864c6 100644
|
||
--- a/src/Backends/SDLBackend.cpp
|
||
+++ b/src/Backends/SDLBackend.cpp
|
||
@@ -719,6 +719,10 @@ namespace gamescope
|
||
case KEY_B:
|
||
g_wantedUpscaleFilter = GamescopeUpscaleFilter::LINEAR;
|
||
break;
|
||
+ case KEY_K:
|
||
+ g_wantedDownscaleFilter = (g_wantedDownscaleFilter == GamescopeDownscaleFilter::BICUBIC) ?
|
||
+ GamescopeDownscaleFilter::LINEAR : GamescopeDownscaleFilter::BICUBIC;
|
||
+ break;
|
||
case KEY_U:
|
||
g_wantedUpscaleFilter = (g_wantedUpscaleFilter == GamescopeUpscaleFilter::FSR) ?
|
||
GamescopeUpscaleFilter::LINEAR : GamescopeUpscaleFilter::FSR;
|
||
diff --git a/src/Backends/WaylandBackend.cpp b/src/Backends/WaylandBackend.cpp
|
||
index c53bf14df..d0abb2fa2 100644
|
||
--- a/src/Backends/WaylandBackend.cpp
|
||
+++ b/src/Backends/WaylandBackend.cpp
|
||
@@ -1598,6 +1598,7 @@ namespace gamescope
|
||
bNeedsFullComposite |= cv_composite_force;
|
||
bNeedsFullComposite |= pFrameInfo->useFSRLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->useNISLayer0;
|
||
+ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->blurLayer0;
|
||
bNeedsFullComposite |= bNeedsCompositeFromFilter;
|
||
bNeedsFullComposite |= g_bColorSliderInUse;
|
||
diff --git a/src/main.cpp b/src/main.cpp
|
||
index a9cdaa2e2..ed7fd4fa7 100644
|
||
--- a/src/main.cpp
|
||
+++ b/src/main.cpp
|
||
@@ -5,6 +5,7 @@
|
||
#include <mutex>
|
||
#include <vector>
|
||
#include <cstring>
|
||
+#include <sstream>
|
||
#include <string>
|
||
#if defined(__linux__)
|
||
#include <sys/capability.h>
|
||
@@ -63,6 +64,7 @@ const struct option *gamescope_options = (struct option[]){
|
||
{ "output-height", required_argument, nullptr, 'H' },
|
||
{ "sharpness", required_argument, nullptr, 0 },
|
||
{ "fsr-sharpness", required_argument, nullptr, 0 },
|
||
+ { "bicubic", optional_argument, nullptr, 'D' },
|
||
{ "rt", no_argument, nullptr, 0 },
|
||
{ "prefer-vk-device", required_argument, 0 },
|
||
{ "expose-wayland", no_argument, 0 },
|
||
@@ -288,11 +290,14 @@ bool g_bGrabbed = false;
|
||
float g_mouseSensitivity = 1.0;
|
||
|
||
GamescopeUpscaleFilter g_upscaleFilter = GamescopeUpscaleFilter::LINEAR;
|
||
+GamescopeDownscaleFilter g_downscaleFilter = GamescopeDownscaleFilter::LINEAR;
|
||
GamescopeUpscaleScaler g_upscaleScaler = GamescopeUpscaleScaler::AUTO;
|
||
|
||
GamescopeUpscaleFilter g_wantedUpscaleFilter = GamescopeUpscaleFilter::LINEAR;
|
||
+GamescopeDownscaleFilter g_wantedDownscaleFilter = GamescopeDownscaleFilter::LINEAR;
|
||
GamescopeUpscaleScaler g_wantedUpscaleScaler = GamescopeUpscaleScaler::AUTO;
|
||
int g_upscaleFilterSharpness = 2;
|
||
+GamescopeBicubicParams g_bicubicParams;
|
||
|
||
gamescope::GamescopeModeGeneration g_eGamescopeModeGeneration = gamescope::GAMESCOPE_MODE_GENERATE_CVT;
|
||
|
||
@@ -397,6 +402,27 @@ static enum GamescopeUpscaleFilter parse_upscaler_filter(const char *str)
|
||
}
|
||
}
|
||
|
||
+static enum GamescopeDownscaleFilter parse_downscaling_filter(const char *str)
|
||
+{
|
||
+ std::stringstream ss{optarg};
|
||
+
|
||
+ double b, c;
|
||
+ char comma;
|
||
+ if ((ss >> b >> comma >> c) && (comma == ',')) {
|
||
+ // clamp values
|
||
+ b = std::clamp(b, 0.0, 1.0);
|
||
+ c = std::clamp(c, 0.0, 1.0);
|
||
+ // Ovewrite default global parameters
|
||
+ g_bicubicParams.b = b;
|
||
+ g_bicubicParams.c = c;
|
||
+ // Set downscaling filters
|
||
+ return GamescopeDownscaleFilter::BICUBIC;
|
||
+ }
|
||
+
|
||
+ fprintf( stderr, "gamescope: invalid value for --bicubic\n" );
|
||
+ exit(1);
|
||
+}
|
||
+
|
||
static enum gamescope::GamescopeBackend parse_backend_name(const char *str)
|
||
{
|
||
if (strcmp(str, "auto") == 0) {
|
||
@@ -704,6 +730,9 @@ int main(int argc, char **argv)
|
||
case 'F':
|
||
g_wantedUpscaleFilter = parse_upscaler_filter(optarg);
|
||
break;
|
||
+ case 'D':
|
||
+ g_wantedDownscaleFilter = parse_downscaling_filter(optarg);
|
||
+ break;
|
||
case 'b':
|
||
g_bBorderlessOutputWindow = true;
|
||
break;
|
||
diff --git a/src/main.hpp b/src/main.hpp
|
||
index 2e6fb833a..f8cc03053 100644
|
||
--- a/src/main.hpp
|
||
+++ b/src/main.hpp
|
||
@@ -40,6 +40,18 @@ enum class GamescopeUpscaleFilter : uint32_t
|
||
FROM_VIEW = 0xF, // internal
|
||
};
|
||
|
||
+enum class GamescopeDownscaleFilter : uint32_t
|
||
+{
|
||
+ LINEAR = 0,
|
||
+ BICUBIC,
|
||
+};
|
||
+
|
||
+struct GamescopeBicubicParams
|
||
+{
|
||
+ float b = 0.3f;
|
||
+ float c = 0.3f;
|
||
+};
|
||
+
|
||
static constexpr bool DoesHardwareSupportUpscaleFilter( GamescopeUpscaleFilter eFilter )
|
||
{
|
||
// Could do nearest someday... AMDGPU DC supports custom tap placement to an extent.
|
||
@@ -57,10 +69,13 @@ enum class GamescopeUpscaleScaler : uint32_t
|
||
};
|
||
|
||
extern GamescopeUpscaleFilter g_upscaleFilter;
|
||
+extern GamescopeDownscaleFilter g_downscaleFilter;
|
||
extern GamescopeUpscaleScaler g_upscaleScaler;
|
||
extern GamescopeUpscaleFilter g_wantedUpscaleFilter;
|
||
+extern GamescopeDownscaleFilter g_wantedDownscaleFilter;
|
||
extern GamescopeUpscaleScaler g_wantedUpscaleScaler;
|
||
extern int g_upscaleFilterSharpness;
|
||
+extern GamescopeBicubicParams g_bicubicParams;
|
||
|
||
extern bool g_bBorderlessOutputWindow;
|
||
|
||
diff --git a/src/meson.build b/src/meson.build
|
||
index 5174de670..907277a23 100644
|
||
--- a/src/meson.build
|
||
+++ b/src/meson.build
|
||
@@ -66,6 +66,7 @@ shader_src = [
|
||
'shaders/cs_composite_rcas.comp',
|
||
'shaders/cs_easu.comp',
|
||
'shaders/cs_easu_fp16.comp',
|
||
+ 'shaders/cs_bicubic.comp',
|
||
'shaders/cs_gaussian_blur_horizontal.comp',
|
||
'shaders/cs_nis.comp',
|
||
'shaders/cs_nis_fp16.comp',
|
||
diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp
|
||
index d61fd73ea..45f45deba 100644
|
||
--- a/src/rendervulkan.cpp
|
||
+++ b/src/rendervulkan.cpp
|
||
@@ -44,6 +44,7 @@
|
||
#include "cs_composite_rcas.h"
|
||
#include "cs_easu.h"
|
||
#include "cs_easu_fp16.h"
|
||
+#include "cs_bicubic.h"
|
||
#include "cs_gaussian_blur_horizontal.h"
|
||
#include "cs_nis.h"
|
||
#include "cs_nis_fp16.h"
|
||
@@ -52,6 +53,7 @@
|
||
#define A_CPU
|
||
#include "shaders/ffx_a.h"
|
||
#include "shaders/ffx_fsr1.h"
|
||
+#include "shaders/bicubic.h"
|
||
|
||
#include "reshade_effect_manager.hpp"
|
||
|
||
@@ -890,11 +892,13 @@ bool CVulkanDevice::createShaders()
|
||
if (m_bSupportsFp16)
|
||
{
|
||
SHADER(EASU, cs_easu_fp16);
|
||
+ SHADER(BICUBIC, cs_bicubic);
|
||
SHADER(NIS, cs_nis_fp16);
|
||
}
|
||
else
|
||
{
|
||
SHADER(EASU, cs_easu);
|
||
+ SHADER(BICUBIC, cs_bicubic);
|
||
SHADER(NIS, cs_nis);
|
||
}
|
||
SHADER(RGB_TO_NV12, cs_rgb_to_nv12);
|
||
@@ -1126,6 +1130,7 @@ void CVulkanDevice::compileAllPipelines()
|
||
SHADER(BLUR_FIRST_PASS, 1, 2, 1);
|
||
SHADER(RCAS, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, 1);
|
||
SHADER(EASU, 1, 1, 1);
|
||
+ SHADER(BICUBIC, 1, 1, 1);
|
||
SHADER(NIS, 1, 1, 1);
|
||
SHADER(RGB_TO_NV12, 1, 1, 1);
|
||
#undef SHADER
|
||
@@ -3691,6 +3696,17 @@ struct EasuPushData_t
|
||
}
|
||
};
|
||
|
||
+struct BicubicPushData_t
|
||
+{
|
||
+ uvec4_t Const0;
|
||
+ uvec4_t Const1;
|
||
+
|
||
+ BicubicPushData_t(float B, float C, uint32_t inputX, uint32_t inputY, uint32_t tempX, uint32_t tempY, uint32_t winX, uint32_t winY)
|
||
+ {
|
||
+ BicubicCon(&Const0.x, &Const1.x, B*10, C*10, inputX, inputY, tempX, tempY, winX, winY);
|
||
+ }
|
||
+};
|
||
+
|
||
struct RcasPushData_t
|
||
{
|
||
uvec2_t u_layer0Offset;
|
||
@@ -3900,7 +3916,53 @@ std::optional<uint64_t> vulkan_composite( struct FrameInfo_t *frameInfo, gamesco
|
||
for (uint32_t i = 0; i < EOTF_Count; i++)
|
||
cmdBuffer->bindColorMgmtLuts(i, frameInfo->shaperLut[i], frameInfo->lut3D[i]);
|
||
|
||
- if ( frameInfo->useFSRLayer0 )
|
||
+ if ( frameInfo->useBICUBICLayer0 )
|
||
+ {
|
||
+ // fprintf(stderr, "-- Use bicubic\n");
|
||
+ uint32_t inputX = frameInfo->layers[0].tex->width();
|
||
+ uint32_t inputY = frameInfo->layers[0].tex->height();
|
||
+
|
||
+ uint32_t tempX = frameInfo->layers[0].integerWidth();
|
||
+ uint32_t tempY = frameInfo->layers[0].integerHeight();
|
||
+
|
||
+ update_tmp_images(tempX, tempY);
|
||
+
|
||
+ cmdBuffer->bindPipeline( g_device.pipeline(SHADER_TYPE_BICUBIC, frameInfo->layerCount, frameInfo->ycbcrMask()));
|
||
+ // cmdBuffer->bindTarget(compositeImage);
|
||
+ cmdBuffer->bindTarget(g_output.tmpOutput);
|
||
+ cmdBuffer->bindTexture(0, frameInfo->layers[0].tex);
|
||
+ cmdBuffer->setTextureSrgb(0, true);
|
||
+ cmdBuffer->setSamplerUnnormalized(0, false);
|
||
+ cmdBuffer->setSamplerNearest(0, false);
|
||
+ cmdBuffer->uploadConstants<BicubicPushData_t>(g_bicubicParams.b
|
||
+ , g_bicubicParams.c
|
||
+ , inputX
|
||
+ , inputY
|
||
+ , tempX
|
||
+ , tempY
|
||
+ , currentOutputWidth
|
||
+ , currentOutputHeight
|
||
+ );
|
||
+
|
||
+ int pixelsPerGroup = 16;
|
||
+
|
||
+ cmdBuffer->dispatch(div_roundup(tempX, pixelsPerGroup), div_roundup(tempY, pixelsPerGroup));
|
||
+
|
||
+ struct FrameInfo_t bicFrameInfo = *frameInfo;
|
||
+ bicFrameInfo.layers[0].tex = g_output.tmpOutput;
|
||
+ bicFrameInfo.layers[0].scale.x = 1.0f;
|
||
+ bicFrameInfo.layers[0].scale.y = 1.0f;
|
||
+
|
||
+ cmdBuffer->bindPipeline( g_device.pipeline(SHADER_TYPE_BLIT, bicFrameInfo.layerCount, bicFrameInfo.ycbcrMask()));
|
||
+ bind_all_layers(cmdBuffer.get(), &bicFrameInfo);
|
||
+ cmdBuffer->bindTarget(compositeImage);
|
||
+ cmdBuffer->uploadConstants<BlitPushData_t>(&bicFrameInfo);
|
||
+
|
||
+ pixelsPerGroup = 8;
|
||
+
|
||
+ cmdBuffer->dispatch(div_roundup(currentOutputWidth, pixelsPerGroup), div_roundup(currentOutputHeight, pixelsPerGroup));
|
||
+ }
|
||
+ else if ( frameInfo->useFSRLayer0 )
|
||
{
|
||
uint32_t inputX = frameInfo->layers[0].tex->width();
|
||
uint32_t inputY = frameInfo->layers[0].tex->height();
|
||
diff --git a/src/rendervulkan.hpp b/src/rendervulkan.hpp
|
||
index b967e849f..f6b80c5a1 100644
|
||
--- a/src/rendervulkan.hpp
|
||
+++ b/src/rendervulkan.hpp
|
||
@@ -269,6 +269,7 @@ struct FrameInfo_t
|
||
{
|
||
bool useFSRLayer0;
|
||
bool useNISLayer0;
|
||
+ bool useBICUBICLayer0;
|
||
bool bFadingOut;
|
||
BlurMode blurLayer0;
|
||
int blurRadius;
|
||
@@ -530,6 +531,7 @@ enum ShaderType {
|
||
SHADER_TYPE_EASU,
|
||
SHADER_TYPE_RCAS,
|
||
SHADER_TYPE_NIS,
|
||
+ SHADER_TYPE_BICUBIC,
|
||
SHADER_TYPE_RGB_TO_NV12,
|
||
|
||
SHADER_TYPE_COUNT
|
||
diff --git a/src/shaders/bicubic.h b/src/shaders/bicubic.h
|
||
new file mode 100644
|
||
index 000000000..8117e8783
|
||
--- /dev/null
|
||
+++ b/src/shaders/bicubic.h
|
||
@@ -0,0 +1,44 @@
|
||
+//_____________________________________________________________/\_______________________________________________________________
|
||
+//==============================================================================================================================
|
||
+//
|
||
+//
|
||
+// BICUBIC IMAGE SCALING
|
||
+//
|
||
+//
|
||
+//------------------------------------------------------------------------------------------------------------------------------
|
||
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
+//_____________________________________________________________/\_______________________________________________________________
|
||
+//==============================================================================================================================
|
||
+// CONSTANT SETUP
|
||
+//==============================================================================================================================
|
||
+// Call to setup required constant values (works on CPU or GPU).
|
||
+A_STATIC void BicubicCon(
|
||
+outAU4 con0,
|
||
+outAU4 con1,
|
||
+// Configurable parameters
|
||
+AU1 B,
|
||
+AU1 C,
|
||
+// This the rendered image resolution
|
||
+AF1 inputRenderedSizeX,
|
||
+AF1 inputRenderedSizeY,
|
||
+// This is the resolution of the resource containing the input image (useful for dynamic resolution)
|
||
+AF1 inputCurrentSizeX,
|
||
+AF1 inputCurrentSizeY,
|
||
+// This is the window width / height
|
||
+AF1 outputTargetSizeX,
|
||
+AF1 outputTargetSizeY)
|
||
+{
|
||
+ // Input/Output size information
|
||
+ con0[0]=AU1_AF1(inputRenderedSizeX);
|
||
+ con0[1]=AU1_AF1(inputRenderedSizeY);
|
||
+ con0[2]=AU1_AF1(inputCurrentSizeX);
|
||
+ con0[3]=AU1_AF1(inputCurrentSizeY);
|
||
+
|
||
+ // Viewport pixel position to normalized image space.
|
||
+ con1[0]=AU1_AF1(outputTargetSizeX);
|
||
+ con1[1]=AU1_AF1(outputTargetSizeY);
|
||
+ con1[2]=B;
|
||
+ con1[3]=C;
|
||
+}
|
||
diff --git a/src/shaders/cs_bicubic.comp b/src/shaders/cs_bicubic.comp
|
||
new file mode 100644
|
||
index 000000000..4904433b5
|
||
--- /dev/null
|
||
+++ b/src/shaders/cs_bicubic.comp
|
||
@@ -0,0 +1,176 @@
|
||
+// References
|
||
+// https://www.codeproject.com/Articles/236394/Bi-Cubic-and-Bi-Linear-Interpolation-with-GLSL
|
||
+// https://stackoverflow.com/questions/13501081/efficient-bicubic-filtering-code-in-glsl
|
||
+// https://web.archive.org/web/20180927181721/http://www.java-gaming.org/index.php?topic=35123.0
|
||
+// https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1
|
||
+
|
||
+#version 460
|
||
+
|
||
+#extension GL_GOOGLE_include_directive : require
|
||
+#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
|
||
+
|
||
+#include "descriptor_set.h"
|
||
+
|
||
+layout(
|
||
+ local_size_x = 64,
|
||
+ local_size_y = 1,
|
||
+ local_size_z = 1) in;
|
||
+
|
||
+// Push constant is a mechanism in modern OpenGL that allows passing small amounts of frequently
|
||
+// updated data to the shader without needing to bind a buffer
|
||
+layout(push_constant)
|
||
+uniform layers_t {
|
||
+ uvec4 c0, c1;
|
||
+};
|
||
+
|
||
+#define A_GPU 1
|
||
+#define A_GLSL 1
|
||
+#define A_HALF 1
|
||
+#include "ffx_a.h"
|
||
+#include "bicubic.h"
|
||
+
|
||
+// The Mitchell–Netravali filters or BC-splines
|
||
+// https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters
|
||
+// Conditionals are slow in GPU code, so to represent 0 <= f < 1 and 1 <= f < 2
|
||
+// the P(d) form shown in the wikipedia page is used
|
||
+vec4 mitchellNetravaliWeights(float f, float B, float C)
|
||
+{
|
||
+ float w0 = ((12.0 - 9.0 * B - 6.0 * C) * pow(f, 3.0)) +
|
||
+ ((-18.0 + 12.0 * B + 6.0 * C) * pow(f, 2.0)) +
|
||
+ (6.0 - 2.0 * B);
|
||
+
|
||
+ float w1 = ((-B - 6.0 * C) * pow(f - 1.0, 3.0)) +
|
||
+ ((6.0 * B + 30.0 * C) * pow(f - 1.0, 2.0)) +
|
||
+ ((-12.0 * B - 48.0 * C) * (f - 1.0)) +
|
||
+ (8.0 * B + 24.0 * C);
|
||
+
|
||
+ float w2 = ((12.0 - 9.0 * B - 6.0 * C) * pow(1.0 - f, 3.0)) +
|
||
+ ((-18.0 + 12.0 * B + 6.0 * C) * pow(1.0 - f, 2.0)) +
|
||
+ (6.0 - 2.0 * B);
|
||
+
|
||
+ float w3 = ((-B - 6.0 * C) * pow(2.0 - f, 3.0)) +
|
||
+ ((6.0 * B + 30.0 * C) * pow(2.0 - f, 2.0)) +
|
||
+ ((-12.0 * B - 48.0 * C) * (2.0 - f)) +
|
||
+ (8.0 * B + 24.0 * C);
|
||
+
|
||
+ return vec4(w0, w1, w2, w3);
|
||
+}
|
||
+
|
||
+// https://stackoverflow.com/questions/13501081/efficient-bicubic-filtering-code-in-glsl
|
||
+// https://web.archive.org/web/20180927181721/http://www.java-gaming.org/index.php?topic=35123.0
|
||
+// This is an efficient method to implement bicubic filtering, it takes
|
||
+// advantage of the fact that the bilinear approach gives the weighted average
|
||
+// of a 2x2 area.
|
||
+vec4 textureBicubic(sampler2D splr, vec2 texCoords)
|
||
+{
|
||
+ vec2 texSize = textureSize(splr, 0);
|
||
+ vec2 invTexSize = 1.0 / texSize;
|
||
+
|
||
+ // Converts normalized coordinates into pixel-space coordinate
|
||
+ // Example: If texCoords is (0.5, 0.5), and the texture size is (1920, 1080), the result will be
|
||
+ // (960, 540)—the center of the texture in pixel space.
|
||
+ // Subtracting 0.5 ensures that you're sampling from the center of the texel rather than its corner
|
||
+ // Example: Assume we have a 3x3 texture and texCoords = (0.5, 0.5):
|
||
+ // [0,0][1,0][2,0]
|
||
+ // [0,1][1,1][2,1]
|
||
+ // [0,2][1,2][2,2]
|
||
+ // texCoords * texSize - 0.5 maps to (1.5, 1.5), which is between (1,1) and (2,2), then
|
||
+ // subtracts 0.5 to move it to (1.0, 1.0)—the center of the texel
|
||
+ texCoords = texCoords * texSize - 0.5;
|
||
+
|
||
+ // Get B and C that were pushed from the user input (or default values)
|
||
+ float B = c1[2] / 10.0f;
|
||
+ float C = c1[3] / 10.0f;
|
||
+
|
||
+ // Get the fractional part of the coordinates
|
||
+ // They are used in Mitchell Netravali's strategy to calculate the interpolation weights,
|
||
+ // i.e., how much influence the neighboring vertices have on the final pixel value
|
||
+ vec2 fxy = fract(texCoords);
|
||
+ texCoords -= fxy;
|
||
+
|
||
+ // Calculate bicubic weights
|
||
+ // These weights represent how much influence each neighboring texel in the 4x4 grid will have
|
||
+ // on the final interpolated pixel value
|
||
+ vec4 xweights = mitchellNetravaliWeights(fxy.x, B, C);
|
||
+ vec4 yweights = mitchellNetravaliWeights(fxy.y, B, C);
|
||
+
|
||
+ // Modify the current texture coordinates to have an offset in texels for each coordinate
|
||
+ // E.g. texCoords + vec(-1.0, 0.0) is a texel to the left
|
||
+ // texCoords + vec(1.0, 0.0) is a texel to the right
|
||
+ // texCoords + vec(0.0, 1.0) is a texel downwards
|
||
+ // texCoords + vec(0.0, -1.0) is a texel upwards
|
||
+ vec4 offsetTexels = texCoords.xxyy;
|
||
+ offsetTexels += vec2 (-1.0, +1.0).xyxy;
|
||
+ // Normalize weights to range between (0,1)
|
||
+ // vec4 sumWeights = vec4(xweights.xz + xweights.yw, yweights.xz + yweights.yw);
|
||
+ // vec4 normalizedWeights = vec4 (xweights.yw, yweights.yw) / sumWeights;
|
||
+ vec4 sumWeights = vec4(xweights.x + xweights.y, xweights.z + xweights.w, yweights.x + yweights.y, yweights.z + yweights.w);
|
||
+ vec4 normalizedWeights = vec4 (xweights.y, xweights.w, yweights.y, yweights.w) / sumWeights;
|
||
+ // Use the weights to influence the sampling position inside each texel
|
||
+ // Each texel has a size from (0,1)
|
||
+ vec4 offsetSampler = offsetTexels + normalizedWeights;
|
||
+ // Go back to normalized space
|
||
+ offsetSampler *= invTexSize.xxyy;
|
||
+ // Perform the sampling
|
||
+ vec4 sample0 = texture(splr, offsetSampler.xz);
|
||
+ vec4 sample1 = texture(splr, offsetSampler.yz);
|
||
+ vec4 sample2 = texture(splr, offsetSampler.xw);
|
||
+ vec4 sample3 = texture(splr, offsetSampler.yw);
|
||
+
|
||
+ // Now we perform linear interpolation in the selected points
|
||
+ // The mix(a, b, t) function in GLSL performs linear interpolation between a and b based on the
|
||
+ // parameter t, t is between 0 and 1
|
||
+ // https://registry.khronos.org/OpenGL-Refpages/gl4/html/mix.xhtml
|
||
+
|
||
+ // Here we want to normalize sx and sy to between 0 and 1 (t value)
|
||
+ float sx = sumWeights.x / (sumWeights.x + sumWeights.y);
|
||
+ float sy = sumWeights.z / (sumWeights.z + sumWeights.w);
|
||
+
|
||
+ return mix(
|
||
+ mix(sample3, sample2, sx), mix(sample1, sample0, sx)
|
||
+ , sy);
|
||
+}
|
||
+
|
||
+void bicPass(uvec2 pos)
|
||
+{
|
||
+ // Retrieve pushed values
|
||
+ AF2 inputRenderedSize = AF2_AU2(c0.xy);
|
||
+ AF2 inputCurrentSize = AF2_AU2(c0.zw);
|
||
+ AF2 outputTargetSize = AF2_AU2(c1.xy);
|
||
+
|
||
+ // ARcpF1(x) == 1.0 / x
|
||
+ // scaleFactor is the division between the rendered image and the size it should have at the end
|
||
+ // E.g.: Rendered 1920x1080, window size is 960x540, then scaleFactor is 2x2
|
||
+ AF2 scaleFactor = inputRenderedSize * vec2(ARcpF1(inputCurrentSize.x), ARcpF1(inputCurrentSize.y));
|
||
+
|
||
+ // The parameter pos of this function is used to iterate over the output image (e.g. 960x540)
|
||
+ // The position of the processed pixel should be taken from the rendered image (e.g. 1920x1080)
|
||
+ // 10x10 in the output, corresponds to 20x20 in the original image
|
||
+ AF2 positionPixel=AF2(pos)*scaleFactor;
|
||
+
|
||
+ // Normalize the image space to be between [0,1]
|
||
+ positionPixel=positionPixel*vec2(ARcpF1(inputRenderedSize.x),ARcpF1(inputRenderedSize.y));
|
||
+
|
||
+ // Apply the bicubic algorithm in the normalized pixel position
|
||
+ vec4 bicPass = textureBicubic(s_samplers[0], positionPixel);
|
||
+
|
||
+ imageStore(dst, ivec2(pos), bicPass);
|
||
+}
|
||
+
|
||
+
|
||
+void main()
|
||
+{
|
||
+ // AMD recommends to use this swizzle and to process 4 pixel per invocation
|
||
+ // for better cache utilisation
|
||
+ uvec2 pos = ARmp8x8(gl_LocalInvocationID.x) + uvec2(gl_WorkGroupID.x << 4u, gl_WorkGroupID.y << 4u);
|
||
+
|
||
+ bicPass(pos);
|
||
+ pos.x += 8u;
|
||
+ bicPass(pos);
|
||
+ pos.y += 8u;
|
||
+ bicPass(pos);
|
||
+ pos.x -= 8u;
|
||
+ bicPass(pos);
|
||
+}
|
||
+
|
||
+/* vim: set expandtab ft=cpp fdm=marker ts=4 sw=4 tw=100 et :*/
|
||
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
||
index 02148f423..b33608707 100644
|
||
--- a/src/steamcompmgr.cpp
|
||
+++ b/src/steamcompmgr.cpp
|
||
@@ -2356,6 +2356,10 @@ paint_all(bool async)
|
||
paint_window(w, w, &frameInfo, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::DrawBorders, 1.0f, override);
|
||
|
||
bool needsScaling = frameInfo.layers[0].scale.x < 0.999f && frameInfo.layers[0].scale.y < 0.999f;
|
||
+ // Temporarily allow upscaling as well
|
||
+ // bool needsDownScaling = frameInfo.layers[0].scale.x > 1.001f && frameInfo.layers[0].scale.y > 1.001f;
|
||
+ bool needsDownScaling = true;
|
||
+ frameInfo.useBICUBICLayer0 = g_downscaleFilter == GamescopeDownscaleFilter::BICUBIC && needsDownScaling;
|
||
frameInfo.useFSRLayer0 = g_upscaleFilter == GamescopeUpscaleFilter::FSR && needsScaling;
|
||
frameInfo.useNISLayer0 = g_upscaleFilter == GamescopeUpscaleFilter::NIS && needsScaling;
|
||
}
|
||
@@ -2488,6 +2492,7 @@ paint_all(bool async)
|
||
}
|
||
|
||
frameInfo.useFSRLayer0 = false;
|
||
+ frameInfo.useBICUBICLayer0 = false;
|
||
frameInfo.useNISLayer0 = false;
|
||
}
|
||
|
||
@@ -7846,6 +7851,7 @@ steamcompmgr_main(int argc, char **argv)
|
||
g_bSteamIsActiveWindow = false;
|
||
g_upscaleScaler = g_wantedUpscaleScaler;
|
||
g_upscaleFilter = g_wantedUpscaleFilter;
|
||
+ g_downscaleFilter = g_wantedDownscaleFilter;
|
||
}
|
||
|
||
// If we're in the middle of a fade, then keep us
|
||
|
||
From 6acfb50f09cc9fd8a16dd502d260b920a8ba02cb Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Sat, 5 Oct 2024 15:19:23 -0300
|
||
Subject: [PATCH 2/9] Partial bicubic code adaptation [2]
|
||
|
||
---
|
||
src/Backends/DRMBackend.cpp | 1 +
|
||
src/Backends/OpenVRBackend.cpp | 1 +
|
||
src/main.cpp | 6 +++---
|
||
src/rendervulkan.cpp | 3 +--
|
||
src/shaders/descriptor_set.h | 1 +
|
||
src/steamcompmgr.cpp | 17 +++++++++++++++++
|
||
src/steamcompmgr.hpp | 1 +
|
||
src/xwayland_ctx.hpp | 1 +
|
||
8 files changed, 26 insertions(+), 5 deletions(-)
|
||
|
||
diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
|
||
index c62635f19..76c9f0514 100644
|
||
--- a/src/Backends/DRMBackend.cpp
|
||
+++ b/src/Backends/DRMBackend.cpp
|
||
@@ -3211,6 +3211,7 @@ namespace gamescope
|
||
bNeedsFullComposite |= bWasFirstFrame;
|
||
bNeedsFullComposite |= pFrameInfo->useFSRLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->useNISLayer0;
|
||
+ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->blurLayer0;
|
||
bNeedsFullComposite |= bNeedsCompositeFromFilter;
|
||
bNeedsFullComposite |= !k_bUseCursorPlane && bDrewCursor;
|
||
diff --git a/src/Backends/OpenVRBackend.cpp b/src/Backends/OpenVRBackend.cpp
|
||
index c39caa54b..08640f853 100644
|
||
--- a/src/Backends/OpenVRBackend.cpp
|
||
+++ b/src/Backends/OpenVRBackend.cpp
|
||
@@ -554,6 +554,7 @@ namespace gamescope
|
||
bNeedsFullComposite |= cv_composite_force;
|
||
bNeedsFullComposite |= pFrameInfo->useFSRLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->useNISLayer0;
|
||
+ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->blurLayer0;
|
||
bNeedsFullComposite |= bNeedsCompositeFromFilter;
|
||
bNeedsFullComposite |= g_bColorSliderInUse;
|
||
diff --git a/src/main.cpp b/src/main.cpp
|
||
index ed7fd4fa7..de25ddeab 100644
|
||
--- a/src/main.cpp
|
||
+++ b/src/main.cpp
|
||
@@ -402,7 +402,7 @@ static enum GamescopeUpscaleFilter parse_upscaler_filter(const char *str)
|
||
}
|
||
}
|
||
|
||
-static enum GamescopeDownscaleFilter parse_downscaling_filter(const char *str)
|
||
+static enum GamescopeDownscaleFilter parse_downscaler_filter(const char *str)
|
||
{
|
||
std::stringstream ss{optarg};
|
||
|
||
@@ -415,7 +415,7 @@ static enum GamescopeDownscaleFilter parse_downscaling_filter(const char *str)
|
||
// Ovewrite default global parameters
|
||
g_bicubicParams.b = b;
|
||
g_bicubicParams.c = c;
|
||
- // Set downscaling filters
|
||
+ // Set downscaler filters
|
||
return GamescopeDownscaleFilter::BICUBIC;
|
||
}
|
||
|
||
@@ -731,7 +731,7 @@ int main(int argc, char **argv)
|
||
g_wantedUpscaleFilter = parse_upscaler_filter(optarg);
|
||
break;
|
||
case 'D':
|
||
- g_wantedDownscaleFilter = parse_downscaling_filter(optarg);
|
||
+ g_wantedDownscaleFilter = parse_downscaler_filter(optarg);
|
||
break;
|
||
case 'b':
|
||
g_bBorderlessOutputWindow = true;
|
||
diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp
|
||
index 45f45deba..e80afb68a 100644
|
||
--- a/src/rendervulkan.cpp
|
||
+++ b/src/rendervulkan.cpp
|
||
@@ -889,16 +889,15 @@ bool CVulkanDevice::createShaders()
|
||
SHADER(BLUR_COND, cs_composite_blur_cond);
|
||
SHADER(BLUR_FIRST_PASS, cs_gaussian_blur_horizontal);
|
||
SHADER(RCAS, cs_composite_rcas);
|
||
+ SHADER(BICUBIC, cs_bicubic);
|
||
if (m_bSupportsFp16)
|
||
{
|
||
SHADER(EASU, cs_easu_fp16);
|
||
- SHADER(BICUBIC, cs_bicubic);
|
||
SHADER(NIS, cs_nis_fp16);
|
||
}
|
||
else
|
||
{
|
||
SHADER(EASU, cs_easu);
|
||
- SHADER(BICUBIC, cs_bicubic);
|
||
SHADER(NIS, cs_nis);
|
||
}
|
||
SHADER(RGB_TO_NV12, cs_rgb_to_nv12);
|
||
diff --git a/src/shaders/descriptor_set.h b/src/shaders/descriptor_set.h
|
||
index f2b8527c8..64cc1c9c3 100644
|
||
--- a/src/shaders/descriptor_set.h
|
||
+++ b/src/shaders/descriptor_set.h
|
||
@@ -21,6 +21,7 @@ const int filter_nearest = 1;
|
||
const int filter_fsr = 2;
|
||
const int filter_nis = 3;
|
||
const int filter_pixel = 4;
|
||
+const int filter_bicubic = 5;
|
||
const int filter_from_view = 255;
|
||
|
||
const int EOTF_Gamma22 = 0;
|
||
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
||
index b33608707..86a815f06 100644
|
||
--- a/src/steamcompmgr.cpp
|
||
+++ b/src/steamcompmgr.cpp
|
||
@@ -874,6 +874,7 @@ gamescope::ConCommand cc_debug_set_fps_limit( "debug_set_fps_limit", "Set refres
|
||
static int g_nRuntimeInfoFd = -1;
|
||
|
||
bool g_bFSRActive = false;
|
||
+bool g_bBicubicActive = false;
|
||
|
||
BlurMode g_BlurMode = BLUR_MODE_OFF;
|
||
BlurMode g_BlurModeOld = BLUR_MODE_OFF;
|
||
@@ -2497,6 +2498,7 @@ paint_all(bool async)
|
||
}
|
||
|
||
g_bFSRActive = frameInfo.useFSRLayer0;
|
||
+ g_bBicubicActive = frameInfo.useBICUBICLayer0;
|
||
|
||
g_bFirstFrame = false;
|
||
|
||
@@ -5417,6 +5419,9 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
||
g_wantedUpscaleScaler = GamescopeUpscaleScaler::AUTO;
|
||
g_wantedUpscaleFilter = GamescopeUpscaleFilter::NIS;
|
||
break;
|
||
+ case 5:
|
||
+ g_wantedDownscaleFilter = GamescopeDownscaleFilter::BICUBIC;
|
||
+ break;
|
||
}
|
||
hasRepaint = true;
|
||
}
|
||
@@ -6969,6 +6974,7 @@ void init_xwayland_ctx(uint32_t serverId, gamescope_xwayland_server_t *xwayland_
|
||
ctx->atoms.gamescopeLowLatency = XInternAtom( ctx->dpy, "GAMESCOPE_LOW_LATENCY", false );
|
||
|
||
ctx->atoms.gamescopeFSRFeedback = XInternAtom( ctx->dpy, "GAMESCOPE_FSR_FEEDBACK", false );
|
||
+ ctx->atoms.gamescopeBicubicFeedback = XInternAtom( ctx->dpy, "GAMESCOPE_BICUBIC_FEEDBACK", false );
|
||
|
||
ctx->atoms.gamescopeBlurMode = XInternAtom( ctx->dpy, "GAMESCOPE_BLUR_MODE", false );
|
||
ctx->atoms.gamescopeBlurRadius = XInternAtom( ctx->dpy, "GAMESCOPE_BLUR_RADIUS", false );
|
||
@@ -7224,6 +7230,7 @@ extern int g_nPreferredOutputWidth;
|
||
extern int g_nPreferredOutputHeight;
|
||
|
||
static bool g_bWasFSRActive = false;
|
||
+static bool g_bWasBicubicActive = false;
|
||
|
||
bool g_bAppWantsHDRCached = false;
|
||
|
||
@@ -7615,6 +7622,16 @@ steamcompmgr_main(int argc, char **argv)
|
||
flush_root = true;
|
||
}
|
||
|
||
+ if ( g_bBicubicActive != g_bWasBicubicActive )
|
||
+ {
|
||
+ uint32_t active = g_bBicubicActive ? 1 : 0;
|
||
+ XChangeProperty( root_ctx->dpy, root_ctx->root, root_ctx->atoms.gamescopeBicubicFeedback, XA_CARDINAL, 32, PropModeReplace,
|
||
+ (unsigned char *)&active, 1 );
|
||
+
|
||
+ g_bWasBicubicActive = g_bBicubicActive;
|
||
+ flush_root = true;
|
||
+ }
|
||
+
|
||
if (global_focus.IsDirty())
|
||
determine_and_apply_focus();
|
||
|
||
diff --git a/src/steamcompmgr.hpp b/src/steamcompmgr.hpp
|
||
index 9f384c461..ea0746860 100644
|
||
--- a/src/steamcompmgr.hpp
|
||
+++ b/src/steamcompmgr.hpp
|
||
@@ -128,6 +128,7 @@ extern float focusedWindowOffsetX;
|
||
extern float focusedWindowOffsetY;
|
||
|
||
extern bool g_bFSRActive;
|
||
+extern bool g_bBicubicActive;
|
||
|
||
extern uint32_t inputCounter;
|
||
extern uint64_t g_lastWinSeq;
|
||
diff --git a/src/xwayland_ctx.hpp b/src/xwayland_ctx.hpp
|
||
index df2af70d1..e212a119e 100644
|
||
--- a/src/xwayland_ctx.hpp
|
||
+++ b/src/xwayland_ctx.hpp
|
||
@@ -164,6 +164,7 @@ struct xwayland_ctx_t final : public gamescope::IWaitable
|
||
Atom gamescopeLowLatency;
|
||
|
||
Atom gamescopeFSRFeedback;
|
||
+ Atom gamescopeBicubicFeedback;
|
||
|
||
Atom gamescopeBlurMode;
|
||
Atom gamescopeBlurRadius;
|
||
|
||
From fceb9b90021e0abf2da6e8cff71034dc204afb24 Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Mon, 7 Oct 2024 00:37:49 -0300
|
||
Subject: [PATCH 3/9] Fix indentation
|
||
|
||
---
|
||
src/Backends/OpenVRBackend.cpp | 2 +-
|
||
src/Backends/WaylandBackend.cpp | 2 +-
|
||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||
|
||
diff --git a/src/Backends/OpenVRBackend.cpp b/src/Backends/OpenVRBackend.cpp
|
||
index 08640f853..96a3d0166 100644
|
||
--- a/src/Backends/OpenVRBackend.cpp
|
||
+++ b/src/Backends/OpenVRBackend.cpp
|
||
@@ -554,7 +554,7 @@ namespace gamescope
|
||
bNeedsFullComposite |= cv_composite_force;
|
||
bNeedsFullComposite |= pFrameInfo->useFSRLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->useNISLayer0;
|
||
- bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0;
|
||
+ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->blurLayer0;
|
||
bNeedsFullComposite |= bNeedsCompositeFromFilter;
|
||
bNeedsFullComposite |= g_bColorSliderInUse;
|
||
diff --git a/src/Backends/WaylandBackend.cpp b/src/Backends/WaylandBackend.cpp
|
||
index d0abb2fa2..d9d213e85 100644
|
||
--- a/src/Backends/WaylandBackend.cpp
|
||
+++ b/src/Backends/WaylandBackend.cpp
|
||
@@ -1598,7 +1598,7 @@ namespace gamescope
|
||
bNeedsFullComposite |= cv_composite_force;
|
||
bNeedsFullComposite |= pFrameInfo->useFSRLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->useNISLayer0;
|
||
- bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0;
|
||
+ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0;
|
||
bNeedsFullComposite |= pFrameInfo->blurLayer0;
|
||
bNeedsFullComposite |= bNeedsCompositeFromFilter;
|
||
bNeedsFullComposite |= g_bColorSliderInUse;
|
||
|
||
From 514c7c243730e6f4cae719cd5a662bc5ee68dc6c Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Mon, 7 Oct 2024 00:43:10 -0300
|
||
Subject: [PATCH 4/9] Fix black screen on bicubic filter
|
||
|
||
---
|
||
src/shaders/cs_bicubic.comp | 3 ++-
|
||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||
|
||
diff --git a/src/shaders/cs_bicubic.comp b/src/shaders/cs_bicubic.comp
|
||
index 4904433b5..2b6dfb824 100644
|
||
--- a/src/shaders/cs_bicubic.comp
|
||
+++ b/src/shaders/cs_bicubic.comp
|
||
@@ -8,6 +8,7 @@
|
||
|
||
#extension GL_GOOGLE_include_directive : require
|
||
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
|
||
+#extension GL_EXT_scalar_block_layout : require
|
||
|
||
#include "descriptor_set.h"
|
||
|
||
@@ -18,7 +19,7 @@ layout(
|
||
|
||
// Push constant is a mechanism in modern OpenGL that allows passing small amounts of frequently
|
||
// updated data to the shader without needing to bind a buffer
|
||
-layout(push_constant)
|
||
+layout(binding = 0, scalar)
|
||
uniform layers_t {
|
||
uvec4 c0, c1;
|
||
};
|
||
|
||
From 8fa17e48fa07210f03d2643f3fe8811e2e6aa9a4 Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Mon, 7 Oct 2024 01:27:35 -0300
|
||
Subject: [PATCH 5/9] Use bicubic as an option of --filter
|
||
|
||
---
|
||
src/main.cpp | 39 ++++++++++++++++++++++++++++++++-------
|
||
1 file changed, 32 insertions(+), 7 deletions(-)
|
||
|
||
diff --git a/src/main.cpp b/src/main.cpp
|
||
index de25ddeab..b7f5985b9 100644
|
||
--- a/src/main.cpp
|
||
+++ b/src/main.cpp
|
||
@@ -64,7 +64,6 @@ const struct option *gamescope_options = (struct option[]){
|
||
{ "output-height", required_argument, nullptr, 'H' },
|
||
{ "sharpness", required_argument, nullptr, 0 },
|
||
{ "fsr-sharpness", required_argument, nullptr, 0 },
|
||
- { "bicubic", optional_argument, nullptr, 'D' },
|
||
{ "rt", no_argument, nullptr, 0 },
|
||
{ "prefer-vk-device", required_argument, 0 },
|
||
{ "expose-wayland", no_argument, 0 },
|
||
@@ -404,8 +403,26 @@ static enum GamescopeUpscaleFilter parse_upscaler_filter(const char *str)
|
||
|
||
static enum GamescopeDownscaleFilter parse_downscaler_filter(const char *str)
|
||
{
|
||
- std::stringstream ss{optarg};
|
||
+ std::string_view arg{str};
|
||
|
||
+ // If the string is just 'bicubic' use default values
|
||
+ if ( arg == "bicubic" ) {
|
||
+ return GamescopeDownscaleFilter::BICUBIC;
|
||
+ }
|
||
+
|
||
+ // Arguments start after ':'
|
||
+ if ( auto search = arg.find(':'); search == std::string::npos ) {
|
||
+ fprintf( stderr, "gamescope: invalid argument for --filter=bicubic:float,float\n" );
|
||
+ exit(1);
|
||
+ } else {
|
||
+ arg = std::string_view(arg.data() + search + 1);
|
||
+ }
|
||
+
|
||
+ // Push arguments to stream
|
||
+ std::stringstream ss;
|
||
+ ss << arg;
|
||
+
|
||
+ // Validate arguments from stream
|
||
double b, c;
|
||
char comma;
|
||
if ((ss >> b >> comma >> c) && (comma == ',')) {
|
||
@@ -419,10 +436,21 @@ static enum GamescopeDownscaleFilter parse_downscaler_filter(const char *str)
|
||
return GamescopeDownscaleFilter::BICUBIC;
|
||
}
|
||
|
||
- fprintf( stderr, "gamescope: invalid value for --bicubic\n" );
|
||
+ fprintf( stderr, "gamescope: invalid value for --filter\n" );
|
||
exit(1);
|
||
}
|
||
|
||
+static void parse_filter(const char *str)
|
||
+{
|
||
+ fprintf(stderr, "str: %s\n", str);
|
||
+ if (std::string_view{str}.starts_with("bicubic")) {
|
||
+ fprintf(stderr, "Startswith\n");
|
||
+ g_wantedDownscaleFilter = parse_downscaler_filter(str);
|
||
+ } else {
|
||
+ g_wantedUpscaleFilter = parse_upscaler_filter(str);
|
||
+ }
|
||
+}
|
||
+
|
||
static enum gamescope::GamescopeBackend parse_backend_name(const char *str)
|
||
{
|
||
if (strcmp(str, "auto") == 0) {
|
||
@@ -728,10 +756,7 @@ int main(int argc, char **argv)
|
||
g_wantedUpscaleScaler = parse_upscaler_scaler(optarg);
|
||
break;
|
||
case 'F':
|
||
- g_wantedUpscaleFilter = parse_upscaler_filter(optarg);
|
||
- break;
|
||
- case 'D':
|
||
- g_wantedDownscaleFilter = parse_downscaler_filter(optarg);
|
||
+ parse_filter(optarg);
|
||
break;
|
||
case 'b':
|
||
g_bBorderlessOutputWindow = true;
|
||
|
||
From 5e50b2f931abe251e656138ba7bd0e5694dcc671 Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Mon, 7 Oct 2024 01:44:06 -0300
|
||
Subject: [PATCH 6/9] Updated README with bicubic info
|
||
|
||
---
|
||
README.md | 1 +
|
||
1 file changed, 1 insertion(+)
|
||
|
||
diff --git a/README.md b/README.md
|
||
index 8aa0227bf..cfae48017 100644
|
||
--- a/README.md
|
||
+++ b/README.md
|
||
@@ -66,6 +66,7 @@ See `gamescope --help` for a full list of options.
|
||
* `-o`: set a frame-rate limit for the game when unfocused. Specified in frames per second. Defaults to unlimited.
|
||
* `-F fsr`: use AMD FidelityFX™ Super Resolution 1.0 for upscaling
|
||
* `-F nis`: use NVIDIA Image Scaling v1.0.3 for upscaling
|
||
+* `-F bicubic`: use a bicubic filter for downscaling
|
||
* `-S integer`: use integer scaling.
|
||
* `-S stretch`: use stretch scaling, the game will fill the window. (e.g. 4:3 to 16:9)
|
||
* `-b`: create a border-less window.
|
||
|
||
From c1832fc5a44df8fc4c30c47b45638694e51bfa53 Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Mon, 7 Oct 2024 01:45:55 -0300
|
||
Subject: [PATCH 7/9] Fix indentation in meson.build
|
||
|
||
---
|
||
src/meson.build | 2 +-
|
||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
||
diff --git a/src/meson.build b/src/meson.build
|
||
index 907277a23..90096979a 100644
|
||
--- a/src/meson.build
|
||
+++ b/src/meson.build
|
||
@@ -66,7 +66,7 @@ shader_src = [
|
||
'shaders/cs_composite_rcas.comp',
|
||
'shaders/cs_easu.comp',
|
||
'shaders/cs_easu_fp16.comp',
|
||
- 'shaders/cs_bicubic.comp',
|
||
+ 'shaders/cs_bicubic.comp',
|
||
'shaders/cs_gaussian_blur_horizontal.comp',
|
||
'shaders/cs_nis.comp',
|
||
'shaders/cs_nis_fp16.comp',
|
||
|
||
From 7ad3fc2a5e0ce35758fec6a8fb51fb4306cbc6e1 Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Mon, 7 Oct 2024 05:31:33 -0300
|
||
Subject: [PATCH 8/9] Remove debug print
|
||
|
||
---
|
||
src/main.cpp | 2 --
|
||
1 file changed, 2 deletions(-)
|
||
|
||
diff --git a/src/main.cpp b/src/main.cpp
|
||
index b7f5985b9..32a20cbd5 100644
|
||
--- a/src/main.cpp
|
||
+++ b/src/main.cpp
|
||
@@ -442,9 +442,7 @@ static enum GamescopeDownscaleFilter parse_downscaler_filter(const char *str)
|
||
|
||
static void parse_filter(const char *str)
|
||
{
|
||
- fprintf(stderr, "str: %s\n", str);
|
||
if (std::string_view{str}.starts_with("bicubic")) {
|
||
- fprintf(stderr, "Startswith\n");
|
||
g_wantedDownscaleFilter = parse_downscaler_filter(str);
|
||
} else {
|
||
g_wantedUpscaleFilter = parse_upscaler_filter(str);
|
||
|
||
From 6649fd8f0e7d2bce465855221f30eafc06f9a4ce Mon Sep 17 00:00:00 2001
|
||
From: "Ruan E. Formigoni" <ruanformigoni@gmail.com>
|
||
Date: Mon, 7 Oct 2024 05:34:15 -0300
|
||
Subject: [PATCH 9/9] Remove outdated comments
|
||
|
||
---
|
||
src/rendervulkan.cpp | 2 --
|
||
1 file changed, 2 deletions(-)
|
||
|
||
diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp
|
||
index e80afb68a..33f999101 100644
|
||
--- a/src/rendervulkan.cpp
|
||
+++ b/src/rendervulkan.cpp
|
||
@@ -3917,7 +3917,6 @@ std::optional<uint64_t> vulkan_composite( struct FrameInfo_t *frameInfo, gamesco
|
||
|
||
if ( frameInfo->useBICUBICLayer0 )
|
||
{
|
||
- // fprintf(stderr, "-- Use bicubic\n");
|
||
uint32_t inputX = frameInfo->layers[0].tex->width();
|
||
uint32_t inputY = frameInfo->layers[0].tex->height();
|
||
|
||
@@ -3927,7 +3926,6 @@ std::optional<uint64_t> vulkan_composite( struct FrameInfo_t *frameInfo, gamesco
|
||
update_tmp_images(tempX, tempY);
|
||
|
||
cmdBuffer->bindPipeline( g_device.pipeline(SHADER_TYPE_BICUBIC, frameInfo->layerCount, frameInfo->ycbcrMask()));
|
||
- // cmdBuffer->bindTarget(compositeImage);
|
||
cmdBuffer->bindTarget(g_output.tmpOutput);
|
||
cmdBuffer->bindTexture(0, frameInfo->layers[0].tex);
|
||
cmdBuffer->setTextureSrgb(0, true);
|