summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ameerj2021-09-09 23:01:39 -0400
committerGravatar Fernando Sahmkow2021-11-16 22:11:29 +0100
commitae8d19d17eb5448207ece99ae07507c542c6ddae (patch)
tree2238f455b633142718ea0601687fa01811b5d218 /src
parentgl_texture_cache: fix scaling on upload (diff)
downloadyuzu-ae8d19d17eb5448207ece99ae07507c542c6ddae.tar.gz
yuzu-ae8d19d17eb5448207ece99ae07507c542c6ddae.tar.xz
yuzu-ae8d19d17eb5448207ece99ae07507c542c6ddae.zip
Renderers: Unify post processing filter shaders
Diffstat (limited to 'src')
-rw-r--r--src/video_core/host_shaders/CMakeLists.txt6
-rw-r--r--src/video_core/host_shaders/opengl_present_scaleforce.frag135
-rw-r--r--src/video_core/host_shaders/present_bicubic.frag (renamed from src/video_core/host_shaders/opengl_present_bicubic.frag)13
-rw-r--r--src/video_core/host_shaders/present_scaleforce.frag (renamed from src/video_core/host_shaders/vulkan_present_scaleforce.frag)20
-rw-r--r--src/video_core/host_shaders/vulkan_present_bicubic.frag56
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp9
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp8
7 files changed, 36 insertions, 211 deletions
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt
index 835b37944..664d6ce5d 100644
--- a/src/video_core/host_shaders/CMakeLists.txt
+++ b/src/video_core/host_shaders/CMakeLists.txt
@@ -6,15 +6,13 @@ set(SHADER_FILES
6 convert_float_to_depth.frag 6 convert_float_to_depth.frag
7 full_screen_triangle.vert 7 full_screen_triangle.vert
8 opengl_copy_bc4.comp 8 opengl_copy_bc4.comp
9 opengl_present_scaleforce.frag
10 opengl_present_bicubic.frag
11 opengl_present.frag 9 opengl_present.frag
12 opengl_present.vert 10 opengl_present.vert
13 pitch_unswizzle.comp 11 pitch_unswizzle.comp
12 present_scaleforce.frag
13 present_bicubic.frag
14 vulkan_blit_color_float.frag 14 vulkan_blit_color_float.frag
15 vulkan_blit_depth_stencil.frag 15 vulkan_blit_depth_stencil.frag
16 vulkan_present_bicubic.frag
17 vulkan_present_scaleforce.frag
18 vulkan_present.frag 16 vulkan_present.frag
19 vulkan_present.vert 17 vulkan_present.vert
20 vulkan_quad_indexed.comp 18 vulkan_quad_indexed.comp
diff --git a/src/video_core/host_shaders/opengl_present_scaleforce.frag b/src/video_core/host_shaders/opengl_present_scaleforce.frag
deleted file mode 100644
index 0153f62c0..000000000
--- a/src/video_core/host_shaders/opengl_present_scaleforce.frag
+++ /dev/null
@@ -1,135 +0,0 @@
1// from https://github.com/BreadFish64/ScaleFish/tree/master/scale_force
2
3// MIT License
4//
5// Copyright (c) 2020 BreadFish64
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in all
15// copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25precision mediump float;
26
27layout (location = 0) in vec2 tex_coord;
28
29layout (location = 0) out vec4 frag_color;
30
31layout (binding = 1) uniform sampler2D input_texture;
32
33vec2 tex_size;
34vec2 inv_tex_size;
35
36vec4 cubic(float v) {
37 vec3 n = vec3(1.0, 2.0, 3.0) - v;
38 vec3 s = n * n * n;
39 float x = s.x;
40 float y = s.y - 4.0 * s.x;
41 float z = s.z - 4.0 * s.y + 6.0 * s.x;
42 float w = 6.0 - x - y - z;
43 return vec4(x, y, z, w) / 6.0;
44}
45
46// Bicubic interpolation
47vec4 textureBicubic(vec2 tex_coords) {
48 tex_coords = tex_coords * tex_size - 0.5;
49
50 vec2 fxy = modf(tex_coords, tex_coords);
51
52 vec4 xcubic = cubic(fxy.x);
53 vec4 ycubic = cubic(fxy.y);
54
55 vec4 c = tex_coords.xxyy + vec2(-0.5, +1.5).xyxy;
56
57 vec4 s = vec4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw);
58 vec4 offset = c + vec4(xcubic.yw, ycubic.yw) / s;
59
60 offset *= inv_tex_size.xxyy;
61
62 vec4 sample0 = textureLod(input_texture, offset.xz, 0.0);
63 vec4 sample1 = textureLod(input_texture, offset.yz, 0.0);
64 vec4 sample2 = textureLod(input_texture, offset.xw, 0.0);
65 vec4 sample3 = textureLod(input_texture, offset.yw, 0.0);
66
67 float sx = s.x / (s.x + s.y);
68 float sy = s.z / (s.z + s.w);
69
70 return mix(mix(sample3, sample2, sx), mix(sample1, sample0, sx), sy);
71}
72
73mat4x3 center_matrix;
74vec4 center_alpha;
75
76// Finds the distance between four colors and cc in YCbCr space
77vec4 ColorDist(vec4 A, vec4 B, vec4 C, vec4 D) {
78 // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion
79 const vec3 K = vec3(0.2627, 0.6780, 0.0593);
80 const float LUMINANCE_WEIGHT = .6;
81 const mat3 YCBCR_MATRIX =
82 mat3(K * LUMINANCE_WEIGHT, -.5 * K.r / (1.0 - K.b), -.5 * K.g / (1.0 - K.b), .5, .5,
83 -.5 * K.g / (1.0 - K.r), -.5 * K.b / (1.0 - K.r));
84
85 mat4x3 colors = mat4x3(A.rgb, B.rgb, C.rgb, D.rgb) - center_matrix;
86 mat4x3 YCbCr = YCBCR_MATRIX * colors;
87 vec4 color_dist = vec3(1.0) * YCbCr;
88 color_dist *= color_dist;
89 vec4 alpha = vec4(A.a, B.a, C.a, D.a);
90
91 return sqrt((color_dist + abs(center_alpha - alpha)) * alpha * center_alpha);
92}
93
94void main() {
95 vec4 bl = textureLodOffset(input_texture, tex_coord, 0.0, ivec2(-1, -1));
96 vec4 bc = textureLodOffset(input_texture, tex_coord, 0.0, ivec2(0, -1));
97 vec4 br = textureLodOffset(input_texture, tex_coord, 0.0, ivec2(1, -1));
98 vec4 cl = textureLodOffset(input_texture, tex_coord, 0.0, ivec2(-1, 0));
99 vec4 cc = textureLod(input_texture, tex_coord, 0.0);
100 vec4 cr = textureLodOffset(input_texture, tex_coord, 0.0, ivec2(1, 0));
101 vec4 tl = textureLodOffset(input_texture, tex_coord, 0.0, ivec2(-1, 1));
102 vec4 tc = textureLodOffset(input_texture, tex_coord, 0.0, ivec2(0, 1));
103 vec4 tr = textureLodOffset(input_texture, tex_coord, 0.0, ivec2(1, 1));
104
105
106 tex_size = vec2(textureSize(input_texture, 0));
107 inv_tex_size = 1.0 / tex_size;
108 center_matrix = mat4x3(cc.rgb, cc.rgb, cc.rgb, cc.rgb);
109 center_alpha = cc.aaaa;
110
111 vec4 offset_tl = ColorDist(tl, tc, tr, cr);
112 vec4 offset_br = ColorDist(br, bc, bl, cl);
113
114 // Calculate how different cc is from the texels around it
115 float total_dist = dot(offset_tl + offset_br, vec4(1.0));
116
117 // Add together all the distances with direction taken into account
118 vec4 tmp = offset_tl - offset_br;
119 vec2 total_offset = tmp.wy + tmp.zz + vec2(-tmp.x, tmp.x);
120
121 if (total_dist == 0.0) {
122 // Doing bicubic filtering just past the edges where the offset is 0 causes black floaters
123 // and it doesn't really matter which filter is used when the colors aren't changing.
124 frag_color = vec4(cc.rgb, 1.0f);
125 } else {
126 // When the image has thin points, they tend to split apart.
127 // This is because the texels all around are different
128 // and total_offset reaches into clear areas.
129 // This works pretty well to keep the offset in bounds for these cases.
130 float clamp_val = length(total_offset) / total_dist;
131 vec2 final_offset = clamp(total_offset, -clamp_val, clamp_val) * inv_tex_size;
132
133 frag_color = vec4(textureBicubic(tex_coord - final_offset).rgb, 1.0f);
134 }
135}
diff --git a/src/video_core/host_shaders/opengl_present_bicubic.frag b/src/video_core/host_shaders/present_bicubic.frag
index 17772095a..f3e5410e7 100644
--- a/src/video_core/host_shaders/opengl_present_bicubic.frag
+++ b/src/video_core/host_shaders/present_bicubic.frag
@@ -4,11 +4,22 @@
4 4
5#version 460 core 5#version 460 core
6 6
7#ifdef VULKAN
8
9#define BINDING_COLOR_TEXTURE 1
10
11#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
12
13#define BINDING_COLOR_TEXTURE 0
14
15#endif
16
17
7layout (location = 0) in vec2 frag_tex_coord; 18layout (location = 0) in vec2 frag_tex_coord;
8 19
9layout (location = 0) out vec4 color; 20layout (location = 0) out vec4 color;
10 21
11layout (binding = 1) uniform sampler2D color_texture; 22layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D color_texture;
12 23
13vec4 cubic(float v) { 24vec4 cubic(float v) {
14 vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v; 25 vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v;
diff --git a/src/video_core/host_shaders/vulkan_present_scaleforce.frag b/src/video_core/host_shaders/present_scaleforce.frag
index 801c8eae9..1829a9be8 100644
--- a/src/video_core/host_shaders/vulkan_present_scaleforce.frag
+++ b/src/video_core/host_shaders/present_scaleforce.frag
@@ -1,7 +1,3 @@
1#version 320 es
2
3// from https://github.com/BreadFish64/ScaleFish/tree/master/scale_force
4
5// MIT License 1// MIT License
6// 2//
7// Copyright (c) 2020 BreadFish64 3// Copyright (c) 2020 BreadFish64
@@ -24,13 +20,25 @@
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25// SOFTWARE. 21// SOFTWARE.
26 22
27precision mediump float; 23// Adapted from https://github.com/BreadFish64/ScaleFish/tree/master/scaleforce
24
25#version 460
26
27#ifdef VULKAN
28
29#define BINDING_COLOR_TEXTURE 1
30
31#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
32
33#define BINDING_COLOR_TEXTURE 0
34
35#endif
28 36
29layout (location = 0) in vec2 tex_coord; 37layout (location = 0) in vec2 tex_coord;
30 38
31layout (location = 0) out vec4 frag_color; 39layout (location = 0) out vec4 frag_color;
32 40
33layout (binding = 1) uniform sampler2D input_texture; 41layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D input_texture;
34 42
35vec2 tex_size; 43vec2 tex_size;
36vec2 inv_tex_size; 44vec2 inv_tex_size;
diff --git a/src/video_core/host_shaders/vulkan_present_bicubic.frag b/src/video_core/host_shaders/vulkan_present_bicubic.frag
deleted file mode 100644
index 17772095a..000000000
--- a/src/video_core/host_shaders/vulkan_present_bicubic.frag
+++ /dev/null
@@ -1,56 +0,0 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#version 460 core
6
7layout (location = 0) in vec2 frag_tex_coord;
8
9layout (location = 0) out vec4 color;
10
11layout (binding = 1) uniform sampler2D color_texture;
12
13vec4 cubic(float v) {
14 vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v;
15 vec4 s = n * n * n;
16 float x = s.x;
17 float y = s.y - 4.0 * s.x;
18 float z = s.z - 4.0 * s.y + 6.0 * s.x;
19 float w = 6.0 - x - y - z;
20 return vec4(x, y, z, w) * (1.0 / 6.0);
21}
22
23vec4 textureBicubic( sampler2D textureSampler, vec2 texCoords ) {
24
25 vec2 texSize = textureSize(textureSampler, 0);
26 vec2 invTexSize = 1.0 / texSize;
27
28 texCoords = texCoords * texSize - 0.5;
29
30 vec2 fxy = fract(texCoords);
31 texCoords -= fxy;
32
33 vec4 xcubic = cubic(fxy.x);
34 vec4 ycubic = cubic(fxy.y);
35
36 vec4 c = texCoords.xxyy + vec2(-0.5, +1.5).xyxy;
37
38 vec4 s = vec4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw);
39 vec4 offset = c + vec4(xcubic.yw, ycubic.yw) / s;
40
41 offset *= invTexSize.xxyy;
42
43 vec4 sample0 = texture(textureSampler, offset.xz);
44 vec4 sample1 = texture(textureSampler, offset.yz);
45 vec4 sample2 = texture(textureSampler, offset.xw);
46 vec4 sample3 = texture(textureSampler, offset.yw);
47
48 float sx = s.x / (s.x + s.y);
49 float sy = s.z / (s.z + s.w);
50
51 return mix(mix(sample3, sample2, sx), mix(sample1, sample0, sx), sy);
52}
53
54void main() {
55 color = vec4(textureBicubic(color_texture, frag_tex_coord).rgb, 1.0f);
56}
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 71a5e3adf..955dbc744 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -21,10 +21,10 @@
21#include "core/memory.h" 21#include "core/memory.h"
22#include "core/perf_stats.h" 22#include "core/perf_stats.h"
23#include "core/telemetry_session.h" 23#include "core/telemetry_session.h"
24#include "video_core/host_shaders/opengl_present_bicubic_frag.h"
25#include "video_core/host_shaders/opengl_present_frag.h" 24#include "video_core/host_shaders/opengl_present_frag.h"
26#include "video_core/host_shaders/opengl_present_scaleforce_frag.h"
27#include "video_core/host_shaders/opengl_present_vert.h" 25#include "video_core/host_shaders/opengl_present_vert.h"
26#include "video_core/host_shaders/present_bicubic_frag.h"
27#include "video_core/host_shaders/present_scaleforce_frag.h"
28#include "video_core/renderer_opengl/gl_rasterizer.h" 28#include "video_core/renderer_opengl/gl_rasterizer.h"
29#include "video_core/renderer_opengl/gl_shader_manager.h" 29#include "video_core/renderer_opengl/gl_shader_manager.h"
30#include "video_core/renderer_opengl/gl_shader_util.h" 30#include "video_core/renderer_opengl/gl_shader_util.h"
@@ -255,10 +255,9 @@ void RendererOpenGL::InitOpenGLObjects() {
255 // Create shader programs 255 // Create shader programs
256 present_vertex = CreateProgram(HostShaders::OPENGL_PRESENT_VERT, GL_VERTEX_SHADER); 256 present_vertex = CreateProgram(HostShaders::OPENGL_PRESENT_VERT, GL_VERTEX_SHADER);
257 present_bilinear_fragment = CreateProgram(HostShaders::OPENGL_PRESENT_FRAG, GL_FRAGMENT_SHADER); 257 present_bilinear_fragment = CreateProgram(HostShaders::OPENGL_PRESENT_FRAG, GL_FRAGMENT_SHADER);
258 present_bicubic_fragment = 258 present_bicubic_fragment = CreateProgram(HostShaders::PRESENT_BICUBIC_FRAG, GL_FRAGMENT_SHADER);
259 CreateProgram(HostShaders::OPENGL_PRESENT_BICUBIC_FRAG, GL_FRAGMENT_SHADER);
260 present_scaleforce_fragment = 259 present_scaleforce_fragment =
261 CreateProgram(HostShaders::OPENGL_PRESENT_SCALEFORCE_FRAG, GL_FRAGMENT_SHADER); 260 CreateProgram(HostShaders::PRESENT_SCALEFORCE_FRAG, GL_FRAGMENT_SHADER);
262 261
263 // Generate presentation sampler 262 // Generate presentation sampler
264 present_sampler.Create(); 263 present_sampler.Create();
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 19d91ecfc..c91b24e3a 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -17,9 +17,9 @@
17#include "core/frontend/emu_window.h" 17#include "core/frontend/emu_window.h"
18#include "core/memory.h" 18#include "core/memory.h"
19#include "video_core/gpu.h" 19#include "video_core/gpu.h"
20#include "video_core/host_shaders/vulkan_present_bicubic_frag_spv.h" 20#include "video_core/host_shaders/present_bicubic_frag_spv.h"
21#include "video_core/host_shaders/present_scaleforce_frag_spv.h"
21#include "video_core/host_shaders/vulkan_present_frag_spv.h" 22#include "video_core/host_shaders/vulkan_present_frag_spv.h"
22#include "video_core/host_shaders/vulkan_present_scaleforce_frag_spv.h"
23#include "video_core/host_shaders/vulkan_present_vert_spv.h" 23#include "video_core/host_shaders/vulkan_present_vert_spv.h"
24#include "video_core/renderer_vulkan/renderer_vulkan.h" 24#include "video_core/renderer_vulkan/renderer_vulkan.h"
25#include "video_core/renderer_vulkan/vk_blit_screen.h" 25#include "video_core/renderer_vulkan/vk_blit_screen.h"
@@ -342,8 +342,8 @@ void VKBlitScreen::RefreshResources(const Tegra::FramebufferConfig& framebuffer)
342void VKBlitScreen::CreateShaders() { 342void VKBlitScreen::CreateShaders() {
343 vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV); 343 vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV);
344 bilinear_fragment_shader = BuildShader(device, VULKAN_PRESENT_FRAG_SPV); 344 bilinear_fragment_shader = BuildShader(device, VULKAN_PRESENT_FRAG_SPV);
345 bicubic_fragment_shader = BuildShader(device, VULKAN_PRESENT_BICUBIC_FRAG_SPV); 345 bicubic_fragment_shader = BuildShader(device, PRESENT_BICUBIC_FRAG_SPV);
346 scaleforce_fragment_shader = BuildShader(device, VULKAN_PRESENT_SCALEFORCE_FRAG_SPV); 346 scaleforce_fragment_shader = BuildShader(device, PRESENT_SCALEFORCE_FRAG_SPV);
347} 347}
348 348
349void VKBlitScreen::CreateSemaphores() { 349void VKBlitScreen::CreateSemaphores() {