diff options
| author | 2021-10-17 17:22:16 +0200 | |
|---|---|---|
| committer | 2021-11-16 22:11:31 +0100 | |
| commit | b60966041c5b1dccd9c5c5ca00fb02353c2151bb (patch) | |
| tree | a4c8e34aadb27e64989a69b3b3b32584e193fab1 /src | |
| parent | externals: Add only included ffx-fsr headers (diff) | |
| download | yuzu-b60966041c5b1dccd9c5c5ca00fb02353c2151bb.tar.gz yuzu-b60966041c5b1dccd9c5c5ca00fb02353c2151bb.tar.xz yuzu-b60966041c5b1dccd9c5c5ca00fb02353c2151bb.zip | |
Presentation: add Nearest Neighbor filter.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/settings.h | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.cpp | 41 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.h | 4 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics.ui | 7 |
6 files changed, 67 insertions, 14 deletions
diff --git a/src/common/settings.h b/src/common/settings.h index 9da447ce0..84dab5217 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -61,10 +61,11 @@ enum class ResolutionSetup : u32 { | |||
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | enum class ScalingFilter : u32 { | 63 | enum class ScalingFilter : u32 { |
| 64 | Bilinear = 0, | 64 | NearestNeighbor = 0, |
| 65 | Bicubic = 1, | 65 | Bilinear = 1, |
| 66 | ScaleForce = 2, | 66 | Bicubic = 2, |
| 67 | Fsr = 3, | 67 | ScaleForce = 3, |
| 68 | Fsr = 4, | ||
| 68 | }; | 69 | }; |
| 69 | 70 | ||
| 70 | struct ResolutionScalingInfo { | 71 | struct ResolutionScalingInfo { |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 955dbc744..68423601c 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -264,6 +264,10 @@ void RendererOpenGL::InitOpenGLObjects() { | |||
| 264 | glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 264 | glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 265 | glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 265 | glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 266 | 266 | ||
| 267 | present_sampler_nn.Create(); | ||
| 268 | glSamplerParameteri(present_sampler_nn.handle, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 269 | glSamplerParameteri(present_sampler_nn.handle, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 270 | |||
| 267 | // Generate VBO handle for drawing | 271 | // Generate VBO handle for drawing |
| 268 | vertex_buffer.Create(); | 272 | vertex_buffer.Create(); |
| 269 | 273 | ||
| @@ -346,6 +350,9 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 346 | GLuint fragment_handle; | 350 | GLuint fragment_handle; |
| 347 | const auto filter = Settings::values.scaling_filter.GetValue(); | 351 | const auto filter = Settings::values.scaling_filter.GetValue(); |
| 348 | switch (filter) { | 352 | switch (filter) { |
| 353 | case Settings::ScalingFilter::NearestNeighbor: | ||
| 354 | fragment_handle = present_bilinear_fragment.handle; | ||
| 355 | break; | ||
| 349 | case Settings::ScalingFilter::Bilinear: | 356 | case Settings::ScalingFilter::Bilinear: |
| 350 | fragment_handle = present_bilinear_fragment.handle; | 357 | fragment_handle = present_bilinear_fragment.handle; |
| 351 | break; | 358 | break; |
| @@ -355,6 +362,12 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 355 | case Settings::ScalingFilter::ScaleForce: | 362 | case Settings::ScalingFilter::ScaleForce: |
| 356 | fragment_handle = present_scaleforce_fragment.handle; | 363 | fragment_handle = present_scaleforce_fragment.handle; |
| 357 | break; | 364 | break; |
| 365 | case Settings::ScalingFilter::Fsr: | ||
| 366 | LOG_WARNING( | ||
| 367 | Render_OpenGL, | ||
| 368 | "FidelityFX FSR Super Sampling is not supported in OpenGL, changing to ScaleForce"); | ||
| 369 | fragment_handle = present_scaleforce_fragment.handle; | ||
| 370 | break; | ||
| 358 | default: | 371 | default: |
| 359 | fragment_handle = present_bilinear_fragment.handle; | 372 | fragment_handle = present_bilinear_fragment.handle; |
| 360 | break; | 373 | break; |
| @@ -464,7 +477,11 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 464 | } | 477 | } |
| 465 | 478 | ||
| 466 | glBindTextureUnit(0, screen_info.display_texture); | 479 | glBindTextureUnit(0, screen_info.display_texture); |
| 467 | glBindSampler(0, present_sampler.handle); | 480 | if (Settings::values.scaling_filter.GetValue() != Settings::ScalingFilter::NearestNeighbor) { |
| 481 | glBindSampler(0, present_sampler.handle); | ||
| 482 | } else { | ||
| 483 | glBindSampler(0, present_sampler_nn.handle); | ||
| 484 | } | ||
| 468 | 485 | ||
| 469 | glClear(GL_COLOR_BUFFER_BIT); | 486 | glClear(GL_COLOR_BUFFER_BIT); |
| 470 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 487 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index bf3d3502c..504ddbe7b 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -109,6 +109,7 @@ private: | |||
| 109 | 109 | ||
| 110 | // OpenGL object IDs | 110 | // OpenGL object IDs |
| 111 | OGLSampler present_sampler; | 111 | OGLSampler present_sampler; |
| 112 | OGLSampler present_sampler_nn; | ||
| 112 | OGLBuffer vertex_buffer; | 113 | OGLBuffer vertex_buffer; |
| 113 | OGLProgram present_vertex; | 114 | OGLProgram present_vertex; |
| 114 | OGLProgram present_bilinear_fragment; | 115 | OGLProgram present_bilinear_fragment; |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 8ce60e874..334eeb92e 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -152,7 +152,9 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, | |||
| 152 | use_accelerated ? screen_info.image_view : *raw_image_views[image_index]; | 152 | use_accelerated ? screen_info.image_view : *raw_image_views[image_index]; |
| 153 | 153 | ||
| 154 | if (!fsr) { | 154 | if (!fsr) { |
| 155 | UpdateDescriptorSet(image_index, source_image_view); | 155 | const bool is_nn = |
| 156 | Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::NearestNeighbor; | ||
| 157 | UpdateDescriptorSet(image_index, source_image_view, is_nn); | ||
| 156 | } | 158 | } |
| 157 | 159 | ||
| 158 | BufferData data; | 160 | BufferData data; |
| @@ -247,7 +249,7 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, | |||
| 247 | crop_rect = crop_rect.Scale(Settings::values.resolution_info.up_factor); | 249 | crop_rect = crop_rect.Scale(Settings::values.resolution_info.up_factor); |
| 248 | VkImageView fsr_image_view = | 250 | VkImageView fsr_image_view = |
| 249 | fsr->Draw(scheduler, image_index, source_image_view, crop_rect); | 251 | fsr->Draw(scheduler, image_index, source_image_view, crop_rect); |
| 250 | UpdateDescriptorSet(image_index, fsr_image_view); | 252 | UpdateDescriptorSet(image_index, fsr_image_view, true); |
| 251 | } | 253 | } |
| 252 | 254 | ||
| 253 | scheduler.Record( | 255 | scheduler.Record( |
| @@ -286,6 +288,9 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, | |||
| 286 | const auto filter = Settings::values.scaling_filter.GetValue(); | 288 | const auto filter = Settings::values.scaling_filter.GetValue(); |
| 287 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); | 289 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); |
| 288 | switch (filter) { | 290 | switch (filter) { |
| 291 | case Settings::ScalingFilter::NearestNeighbor: | ||
| 292 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); | ||
| 293 | break; | ||
| 289 | case Settings::ScalingFilter::Bilinear: | 294 | case Settings::ScalingFilter::Bilinear: |
| 290 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); | 295 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); |
| 291 | break; | 296 | break; |
| @@ -745,13 +750,33 @@ void VKBlitScreen::CreateGraphicsPipeline() { | |||
| 745 | } | 750 | } |
| 746 | 751 | ||
| 747 | void VKBlitScreen::CreateSampler() { | 752 | void VKBlitScreen::CreateSampler() { |
| 748 | bool linear = Settings::values.scaling_filter.GetValue() != Settings::ScalingFilter::Fsr; | ||
| 749 | const VkSamplerCreateInfo ci{ | 753 | const VkSamplerCreateInfo ci{ |
| 750 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, | 754 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, |
| 751 | .pNext = nullptr, | 755 | .pNext = nullptr, |
| 752 | .flags = 0, | 756 | .flags = 0, |
| 753 | .magFilter = linear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST, | 757 | .magFilter = VK_FILTER_LINEAR, |
| 754 | .minFilter = linear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST, | 758 | .minFilter = VK_FILTER_LINEAR, |
| 759 | .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, | ||
| 760 | .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, | ||
| 761 | .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, | ||
| 762 | .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, | ||
| 763 | .mipLodBias = 0.0f, | ||
| 764 | .anisotropyEnable = VK_FALSE, | ||
| 765 | .maxAnisotropy = 0.0f, | ||
| 766 | .compareEnable = VK_FALSE, | ||
| 767 | .compareOp = VK_COMPARE_OP_NEVER, | ||
| 768 | .minLod = 0.0f, | ||
| 769 | .maxLod = 0.0f, | ||
| 770 | .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, | ||
| 771 | .unnormalizedCoordinates = VK_FALSE, | ||
| 772 | }; | ||
| 773 | |||
| 774 | const VkSamplerCreateInfo ci_nn{ | ||
| 775 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, | ||
| 776 | .pNext = nullptr, | ||
| 777 | .flags = 0, | ||
| 778 | .magFilter = VK_FILTER_NEAREST, | ||
| 779 | .minFilter = VK_FILTER_NEAREST, | ||
| 755 | .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, | 780 | .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, |
| 756 | .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, | 781 | .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, |
| 757 | .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, | 782 | .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, |
| @@ -768,6 +793,7 @@ void VKBlitScreen::CreateSampler() { | |||
| 768 | }; | 793 | }; |
| 769 | 794 | ||
| 770 | sampler = device.GetLogical().CreateSampler(ci); | 795 | sampler = device.GetLogical().CreateSampler(ci); |
| 796 | nn_sampler = device.GetLogical().CreateSampler(ci_nn); | ||
| 771 | } | 797 | } |
| 772 | 798 | ||
| 773 | void VKBlitScreen::CreateFramebuffers() { | 799 | void VKBlitScreen::CreateFramebuffers() { |
| @@ -862,7 +888,8 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) | |||
| 862 | } | 888 | } |
| 863 | } | 889 | } |
| 864 | 890 | ||
| 865 | void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const { | 891 | void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view, |
| 892 | bool nn) const { | ||
| 866 | const VkDescriptorBufferInfo buffer_info{ | 893 | const VkDescriptorBufferInfo buffer_info{ |
| 867 | .buffer = *buffer, | 894 | .buffer = *buffer, |
| 868 | .offset = offsetof(BufferData, uniform), | 895 | .offset = offsetof(BufferData, uniform), |
| @@ -883,7 +910,7 @@ void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView imag | |||
| 883 | }; | 910 | }; |
| 884 | 911 | ||
| 885 | const VkDescriptorImageInfo image_info{ | 912 | const VkDescriptorImageInfo image_info{ |
| 886 | .sampler = *sampler, | 913 | .sampler = nn ? *nn_sampler : *sampler, |
| 887 | .imageView = image_view, | 914 | .imageView = image_view, |
| 888 | .imageLayout = VK_IMAGE_LAYOUT_GENERAL, | 915 | .imageLayout = VK_IMAGE_LAYOUT_GENERAL, |
| 889 | }; | 916 | }; |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h index 337931468..448a2fbe6 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.h +++ b/src/video_core/renderer_vulkan/vk_blit_screen.h | |||
| @@ -90,7 +90,7 @@ private: | |||
| 90 | void CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer); | 90 | void CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer); |
| 91 | void CreateRawImages(const Tegra::FramebufferConfig& framebuffer); | 91 | void CreateRawImages(const Tegra::FramebufferConfig& framebuffer); |
| 92 | 92 | ||
| 93 | void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const; | 93 | void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view, bool nn) const; |
| 94 | void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const; | 94 | void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const; |
| 95 | void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, | 95 | void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, |
| 96 | const Layout::FramebufferLayout layout) const; | 96 | const Layout::FramebufferLayout layout) const; |
| @@ -115,12 +115,14 @@ private: | |||
| 115 | vk::DescriptorPool descriptor_pool; | 115 | vk::DescriptorPool descriptor_pool; |
| 116 | vk::DescriptorSetLayout descriptor_set_layout; | 116 | vk::DescriptorSetLayout descriptor_set_layout; |
| 117 | vk::PipelineLayout pipeline_layout; | 117 | vk::PipelineLayout pipeline_layout; |
| 118 | vk::Pipeline nearest_neightbor_pipeline; | ||
| 118 | vk::Pipeline bilinear_pipeline; | 119 | vk::Pipeline bilinear_pipeline; |
| 119 | vk::Pipeline bicubic_pipeline; | 120 | vk::Pipeline bicubic_pipeline; |
| 120 | vk::Pipeline scaleforce_pipeline; | 121 | vk::Pipeline scaleforce_pipeline; |
| 121 | vk::RenderPass renderpass; | 122 | vk::RenderPass renderpass; |
| 122 | std::vector<vk::Framebuffer> framebuffers; | 123 | std::vector<vk::Framebuffer> framebuffers; |
| 123 | vk::DescriptorSets descriptor_sets; | 124 | vk::DescriptorSets descriptor_sets; |
| 125 | vk::Sampler nn_sampler; | ||
| 124 | vk::Sampler sampler; | 126 | vk::Sampler sampler; |
| 125 | 127 | ||
| 126 | vk::Buffer buffer; | 128 | vk::Buffer buffer; |
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index 014ca6683..fe2f6bb7f 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui | |||
| @@ -389,6 +389,11 @@ | |||
| 389 | <widget class="QComboBox" name="scaling_filter_combobox"> | 389 | <widget class="QComboBox" name="scaling_filter_combobox"> |
| 390 | <item> | 390 | <item> |
| 391 | <property name="text"> | 391 | <property name="text"> |
| 392 | <string>Nearest Neighbor</string> | ||
| 393 | </property> | ||
| 394 | </item> | ||
| 395 | <item> | ||
| 396 | <property name="text"> | ||
| 392 | <string>Bilinear</string> | 397 | <string>Bilinear</string> |
| 393 | </property> | 398 | </property> |
| 394 | </item> | 399 | </item> |
| @@ -404,7 +409,7 @@ | |||
| 404 | </item> | 409 | </item> |
| 405 | <item> | 410 | <item> |
| 406 | <property name="text"> | 411 | <property name="text"> |
| 407 | <string>FidelityFX Super Resolution</string> | 412 | <string>FidelityFX Super Resolution [Vulkan Only]</string> |
| 408 | </property> | 413 | </property> |
| 409 | </item> | 414 | </item> |
| 410 | </widget> | 415 | </widget> |