summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar FernandoS272021-10-21 01:27:54 +0200
committerGravatar Fernando Sahmkow2021-11-16 22:11:32 +0100
commit9e065b9c7d3b25ddfe20afa4a945cca6e9767fa9 (patch)
treef9d3d14332d7a0f83c5a60541e2d3fb1e2522669 /src
parentTextureCache: Improve Reaper. (diff)
downloadyuzu-9e065b9c7d3b25ddfe20afa4a945cca6e9767fa9.tar.gz
yuzu-9e065b9c7d3b25ddfe20afa4a945cca6e9767fa9.tar.xz
yuzu-9e065b9c7d3b25ddfe20afa4a945cca6e9767fa9.zip
VideoCore: Add gaussian filtering.
Diffstat (limited to 'src')
-rw-r--r--src/common/settings.h5
-rw-r--r--src/video_core/host_shaders/CMakeLists.txt1
-rw-r--r--src/video_core/host_shaders/present_gaussian.frag74
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp5
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp49
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.h2
-rw-r--r--src/yuzu/configuration/configure_graphics.ui5
8 files changed, 140 insertions, 2 deletions
diff --git a/src/common/settings.h b/src/common/settings.h
index f6acf5bdf..830030efd 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -67,8 +67,9 @@ enum class ScalingFilter : u32 {
67 NearestNeighbor = 0, 67 NearestNeighbor = 0,
68 Bilinear = 1, 68 Bilinear = 1,
69 Bicubic = 2, 69 Bicubic = 2,
70 ScaleForce = 3, 70 Gaussian = 3,
71 Fsr = 4, 71 ScaleForce = 4,
72 Fsr = 5,
72}; 73};
73 74
74struct ResolutionScalingInfo { 75struct ResolutionScalingInfo {
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt
index 32e2ab500..b0e15773c 100644
--- a/src/video_core/host_shaders/CMakeLists.txt
+++ b/src/video_core/host_shaders/CMakeLists.txt
@@ -19,6 +19,7 @@ set(SHADER_FILES
19 pitch_unswizzle.comp 19 pitch_unswizzle.comp
20 present_scaleforce.frag 20 present_scaleforce.frag
21 present_bicubic.frag 21 present_bicubic.frag
22 present_gaussian.frag
22 vulkan_blit_color_float.frag 23 vulkan_blit_color_float.frag
23 vulkan_blit_depth_stencil.frag 24 vulkan_blit_depth_stencil.frag
24 vulkan_fidelityfx_fsr_easu.comp 25 vulkan_fidelityfx_fsr_easu.comp
diff --git a/src/video_core/host_shaders/present_gaussian.frag b/src/video_core/host_shaders/present_gaussian.frag
new file mode 100644
index 000000000..d5e2b1781
--- /dev/null
+++ b/src/video_core/host_shaders/present_gaussian.frag
@@ -0,0 +1,74 @@
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
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
17layout (location = 0) in vec2 frag_tex_coord;
18
19layout (location = 0) out vec4 color;
20
21layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D color_texture;
22
23const float offset[3] = float[](0.0, 1.3846153846, 3.2307692308);
24const float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703);
25
26vec4 blurVertical(sampler2D textureSampler, vec2 coord, vec2 norm) {
27 vec4 result = vec4(0.0f);
28 for (int i=1; i<3; i++) {
29 result +=
30 texture(textureSampler, vec2(coord) + (vec2(0.0, offset[i]) * norm))
31 * weight[i];
32 result +=
33 texture(textureSampler, vec2(coord) - (vec2(0.0, offset[i]) * norm))
34 * weight[i];
35 }
36 return result;
37}
38
39vec4 blurHorizontal(sampler2D textureSampler, vec2 coord, vec2 norm) {
40 vec4 result = vec4(0.0f);
41 for (int i=1; i<3; i++) {
42 result +=
43 texture(textureSampler, vec2(coord) + (vec2(offset[i], 0.0) * norm))
44 * weight[i];
45 result +=
46 texture(textureSampler, vec2(coord) - (vec2(offset[i], 0.0) * norm))
47 * weight[i];
48 }
49 return result;
50}
51
52vec4 blurDiagonal(sampler2D textureSampler, vec2 coord, vec2 norm) {
53 vec4 result = vec4(0.0f);
54 for (int i=1; i<3; i++) {
55 result +=
56 texture(textureSampler, vec2(coord) + (vec2(offset[i], offset[i]) * norm))
57 * weight[i];
58 result +=
59 texture(textureSampler, vec2(coord) - (vec2(offset[i], offset[i]) * norm))
60 * weight[i];
61 }
62 return result;
63}
64
65void main() {
66 vec3 base = texture(color_texture, vec2(frag_tex_coord)).rgb * weight[0];
67 vec2 tex_offset = 1.0f / textureSize(color_texture, 0);
68 vec3 horizontal = blurHorizontal(color_texture, frag_tex_coord, tex_offset).rgb;
69 vec3 vertical = blurVertical(color_texture, frag_tex_coord, tex_offset).rgb;
70 vec3 diagonalA = blurVertical(color_texture, frag_tex_coord, tex_offset).rgb;
71 vec3 diagonalB = blurVertical(color_texture, frag_tex_coord, -tex_offset).rgb;
72 vec3 combination = mix(mix(horizontal, vertical, 0.5f), mix(diagonalA, diagonalB, 0.5f), 0.5f);
73 color = vec4(combination + base, 1.0f);
74}
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 68423601c..6132b3c49 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -256,6 +256,8 @@ void RendererOpenGL::InitOpenGLObjects() {
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 = CreateProgram(HostShaders::PRESENT_BICUBIC_FRAG, GL_FRAGMENT_SHADER); 258 present_bicubic_fragment = CreateProgram(HostShaders::PRESENT_BICUBIC_FRAG, GL_FRAGMENT_SHADER);
259 present_gaussian_fragment =
260 CreateProgram(HostShaders::PRESENT_GAUSSIAN_FRAG, GL_FRAGMENT_SHADER);
259 present_scaleforce_fragment = 261 present_scaleforce_fragment =
260 CreateProgram(HostShaders::PRESENT_SCALEFORCE_FRAG, GL_FRAGMENT_SHADER); 262 CreateProgram(HostShaders::PRESENT_SCALEFORCE_FRAG, GL_FRAGMENT_SHADER);
261 263
@@ -359,6 +361,9 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
359 case Settings::ScalingFilter::Bicubic: 361 case Settings::ScalingFilter::Bicubic:
360 fragment_handle = present_bicubic_fragment.handle; 362 fragment_handle = present_bicubic_fragment.handle;
361 break; 363 break;
364 case Settings::ScalingFilter::Gaussian:
365 fragment_handle = present_gaussian_fragment.handle;
366 break;
362 case Settings::ScalingFilter::ScaleForce: 367 case Settings::ScalingFilter::ScaleForce:
363 fragment_handle = present_scaleforce_fragment.handle; 368 fragment_handle = present_scaleforce_fragment.handle;
364 break; 369 break;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 504ddbe7b..62a746e41 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -114,6 +114,7 @@ private:
114 OGLProgram present_vertex; 114 OGLProgram present_vertex;
115 OGLProgram present_bilinear_fragment; 115 OGLProgram present_bilinear_fragment;
116 OGLProgram present_bicubic_fragment; 116 OGLProgram present_bicubic_fragment;
117 OGLProgram present_gaussian_fragment;
117 OGLProgram present_scaleforce_fragment; 118 OGLProgram present_scaleforce_fragment;
118 OGLFramebuffer screenshot_framebuffer; 119 OGLFramebuffer screenshot_framebuffer;
119 120
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index ccf721008..0d6bce214 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -18,6 +18,7 @@
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/present_bicubic_frag_spv.h" 20#include "video_core/host_shaders/present_bicubic_frag_spv.h"
21#include "video_core/host_shaders/present_gaussian_frag_spv.h"
21#include "video_core/host_shaders/present_scaleforce_frag_spv.h" 22#include "video_core/host_shaders/present_scaleforce_frag_spv.h"
22#include "video_core/host_shaders/vulkan_present_frag_spv.h" 23#include "video_core/host_shaders/vulkan_present_frag_spv.h"
23#include "video_core/host_shaders/vulkan_present_vert_spv.h" 24#include "video_core/host_shaders/vulkan_present_vert_spv.h"
@@ -297,6 +298,9 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
297 case Settings::ScalingFilter::Bicubic: 298 case Settings::ScalingFilter::Bicubic:
298 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bicubic_pipeline); 299 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bicubic_pipeline);
299 break; 300 break;
301 case Settings::ScalingFilter::Gaussian:
302 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *gaussian_pipeline);
303 break;
300 case Settings::ScalingFilter::ScaleForce: 304 case Settings::ScalingFilter::ScaleForce:
301 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *scaleforce_pipeline); 305 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *scaleforce_pipeline);
302 break; 306 break;
@@ -388,6 +392,7 @@ void VKBlitScreen::CreateShaders() {
388 vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV); 392 vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV);
389 bilinear_fragment_shader = BuildShader(device, VULKAN_PRESENT_FRAG_SPV); 393 bilinear_fragment_shader = BuildShader(device, VULKAN_PRESENT_FRAG_SPV);
390 bicubic_fragment_shader = BuildShader(device, PRESENT_BICUBIC_FRAG_SPV); 394 bicubic_fragment_shader = BuildShader(device, PRESENT_BICUBIC_FRAG_SPV);
395 gaussian_fragment_shader = BuildShader(device, PRESENT_GAUSSIAN_FRAG_SPV);
391 scaleforce_fragment_shader = BuildShader(device, PRESENT_SCALEFORCE_FRAG_SPV); 396 scaleforce_fragment_shader = BuildShader(device, PRESENT_SCALEFORCE_FRAG_SPV);
392} 397}
393 398
@@ -574,6 +579,27 @@ void VKBlitScreen::CreateGraphicsPipeline() {
574 }, 579 },
575 }}; 580 }};
576 581
582 const std::array<VkPipelineShaderStageCreateInfo, 2> gaussian_shader_stages{{
583 {
584 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
585 .pNext = nullptr,
586 .flags = 0,
587 .stage = VK_SHADER_STAGE_VERTEX_BIT,
588 .module = *vertex_shader,
589 .pName = "main",
590 .pSpecializationInfo = nullptr,
591 },
592 {
593 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
594 .pNext = nullptr,
595 .flags = 0,
596 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
597 .module = *gaussian_fragment_shader,
598 .pName = "main",
599 .pSpecializationInfo = nullptr,
600 },
601 }};
602
577 const std::array<VkPipelineShaderStageCreateInfo, 2> scaleforce_shader_stages{{ 603 const std::array<VkPipelineShaderStageCreateInfo, 2> scaleforce_shader_stages{{
578 { 604 {
579 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 605 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
@@ -733,6 +759,28 @@ void VKBlitScreen::CreateGraphicsPipeline() {
733 .basePipelineIndex = 0, 759 .basePipelineIndex = 0,
734 }; 760 };
735 761
762 const VkGraphicsPipelineCreateInfo gaussian_pipeline_ci{
763 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
764 .pNext = nullptr,
765 .flags = 0,
766 .stageCount = static_cast<u32>(gaussian_shader_stages.size()),
767 .pStages = gaussian_shader_stages.data(),
768 .pVertexInputState = &vertex_input_ci,
769 .pInputAssemblyState = &input_assembly_ci,
770 .pTessellationState = nullptr,
771 .pViewportState = &viewport_state_ci,
772 .pRasterizationState = &rasterization_ci,
773 .pMultisampleState = &multisampling_ci,
774 .pDepthStencilState = nullptr,
775 .pColorBlendState = &color_blend_ci,
776 .pDynamicState = &dynamic_state_ci,
777 .layout = *pipeline_layout,
778 .renderPass = *renderpass,
779 .subpass = 0,
780 .basePipelineHandle = 0,
781 .basePipelineIndex = 0,
782 };
783
736 const VkGraphicsPipelineCreateInfo scaleforce_pipeline_ci{ 784 const VkGraphicsPipelineCreateInfo scaleforce_pipeline_ci{
737 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 785 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
738 .pNext = nullptr, 786 .pNext = nullptr,
@@ -757,6 +805,7 @@ void VKBlitScreen::CreateGraphicsPipeline() {
757 805
758 bilinear_pipeline = device.GetLogical().CreateGraphicsPipeline(bilinear_pipeline_ci); 806 bilinear_pipeline = device.GetLogical().CreateGraphicsPipeline(bilinear_pipeline_ci);
759 bicubic_pipeline = device.GetLogical().CreateGraphicsPipeline(bicubic_pipeline_ci); 807 bicubic_pipeline = device.GetLogical().CreateGraphicsPipeline(bicubic_pipeline_ci);
808 gaussian_pipeline = device.GetLogical().CreateGraphicsPipeline(gaussian_pipeline_ci);
760 scaleforce_pipeline = device.GetLogical().CreateGraphicsPipeline(scaleforce_pipeline_ci); 809 scaleforce_pipeline = device.GetLogical().CreateGraphicsPipeline(scaleforce_pipeline_ci);
761} 810}
762 811
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h
index 448a2fbe6..96a5598ad 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.h
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.h
@@ -111,6 +111,7 @@ private:
111 vk::ShaderModule vertex_shader; 111 vk::ShaderModule vertex_shader;
112 vk::ShaderModule bilinear_fragment_shader; 112 vk::ShaderModule bilinear_fragment_shader;
113 vk::ShaderModule bicubic_fragment_shader; 113 vk::ShaderModule bicubic_fragment_shader;
114 vk::ShaderModule gaussian_fragment_shader;
114 vk::ShaderModule scaleforce_fragment_shader; 115 vk::ShaderModule scaleforce_fragment_shader;
115 vk::DescriptorPool descriptor_pool; 116 vk::DescriptorPool descriptor_pool;
116 vk::DescriptorSetLayout descriptor_set_layout; 117 vk::DescriptorSetLayout descriptor_set_layout;
@@ -118,6 +119,7 @@ private:
118 vk::Pipeline nearest_neightbor_pipeline; 119 vk::Pipeline nearest_neightbor_pipeline;
119 vk::Pipeline bilinear_pipeline; 120 vk::Pipeline bilinear_pipeline;
120 vk::Pipeline bicubic_pipeline; 121 vk::Pipeline bicubic_pipeline;
122 vk::Pipeline gaussian_pipeline;
121 vk::Pipeline scaleforce_pipeline; 123 vk::Pipeline scaleforce_pipeline;
122 vk::RenderPass renderpass; 124 vk::RenderPass renderpass;
123 std::vector<vk::Framebuffer> framebuffers; 125 std::vector<vk::Framebuffer> framebuffers;
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index c1d7e8349..848ee2d08 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -419,6 +419,11 @@
419 </item> 419 </item>
420 <item> 420 <item>
421 <property name="text"> 421 <property name="text">
422 <string>Gaussian</string>
423 </property>
424 </item>
425 <item>
426 <property name="text">
422 <string>ScaleForce</string> 427 <string>ScaleForce</string>
423 </property> 428 </property>
424 </item> 429 </item>