diff options
| author | 2021-10-21 01:27:54 +0200 | |
|---|---|---|
| committer | 2021-11-16 22:11:32 +0100 | |
| commit | 9e065b9c7d3b25ddfe20afa4a945cca6e9767fa9 (patch) | |
| tree | f9d3d14332d7a0f83c5a60541e2d3fb1e2522669 /src | |
| parent | TextureCache: Improve Reaper. (diff) | |
| download | yuzu-9e065b9c7d3b25ddfe20afa4a945cca6e9767fa9.tar.gz yuzu-9e065b9c7d3b25ddfe20afa4a945cca6e9767fa9.tar.xz yuzu-9e065b9c7d3b25ddfe20afa4a945cca6e9767fa9.zip | |
VideoCore: Add gaussian filtering.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/settings.h | 5 | ||||
| -rw-r--r-- | src/video_core/host_shaders/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/video_core/host_shaders/present_gaussian.frag | 74 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.cpp | 49 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.h | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics.ui | 5 |
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 | ||
| 74 | struct ResolutionScalingInfo { | 75 | struct 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 | |||
| 17 | layout (location = 0) in vec2 frag_tex_coord; | ||
| 18 | |||
| 19 | layout (location = 0) out vec4 color; | ||
| 20 | |||
| 21 | layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D color_texture; | ||
| 22 | |||
| 23 | const float offset[3] = float[](0.0, 1.3846153846, 3.2307692308); | ||
| 24 | const float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703); | ||
| 25 | |||
| 26 | vec4 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 | |||
| 39 | vec4 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 | |||
| 52 | vec4 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 | |||
| 65 | void 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> |