summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-10-17 17:22:16 +0200
committerGravatar Fernando Sahmkow2021-11-16 22:11:31 +0100
commitb60966041c5b1dccd9c5c5ca00fb02353c2151bb (patch)
treea4c8e34aadb27e64989a69b3b3b32584e193fab1 /src
parentexternals: Add only included ffx-fsr headers (diff)
downloadyuzu-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.h9
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp19
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp41
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.h4
-rw-r--r--src/yuzu/configuration/configure_graphics.ui7
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
63enum class ScalingFilter : u32 { 63enum 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
70struct ResolutionScalingInfo { 71struct 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
747void VKBlitScreen::CreateSampler() { 752void 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
773void VKBlitScreen::CreateFramebuffers() { 799void VKBlitScreen::CreateFramebuffers() {
@@ -862,7 +888,8 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
862 } 888 }
863} 889}
864 890
865void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const { 891void 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>