mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-04 12:34:39 +08:00 
			
		
		
		
	Presentation: add Nearest Neighbor filter.
This commit is contained in:
		
							parent
							
								
									77b0812d69
								
							
						
					
					
						commit
						b60966041c
					
				@ -61,10 +61,11 @@ enum class ResolutionSetup : u32 {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum class ScalingFilter : u32 {
 | 
					enum class ScalingFilter : u32 {
 | 
				
			||||||
    Bilinear = 0,
 | 
					    NearestNeighbor = 0,
 | 
				
			||||||
    Bicubic = 1,
 | 
					    Bilinear = 1,
 | 
				
			||||||
    ScaleForce = 2,
 | 
					    Bicubic = 2,
 | 
				
			||||||
    Fsr = 3,
 | 
					    ScaleForce = 3,
 | 
				
			||||||
 | 
					    Fsr = 4,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ResolutionScalingInfo {
 | 
					struct ResolutionScalingInfo {
 | 
				
			||||||
 | 
				
			|||||||
@ -264,6 +264,10 @@ void RendererOpenGL::InitOpenGLObjects() {
 | 
				
			|||||||
    glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
					    glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
				
			||||||
    glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 | 
					    glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    present_sampler_nn.Create();
 | 
				
			||||||
 | 
					    glSamplerParameteri(present_sampler_nn.handle, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
				
			||||||
 | 
					    glSamplerParameteri(present_sampler_nn.handle, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Generate VBO handle for drawing
 | 
					    // Generate VBO handle for drawing
 | 
				
			||||||
    vertex_buffer.Create();
 | 
					    vertex_buffer.Create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -346,6 +350,9 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
 | 
				
			|||||||
    GLuint fragment_handle;
 | 
					    GLuint fragment_handle;
 | 
				
			||||||
    const auto filter = Settings::values.scaling_filter.GetValue();
 | 
					    const auto filter = Settings::values.scaling_filter.GetValue();
 | 
				
			||||||
    switch (filter) {
 | 
					    switch (filter) {
 | 
				
			||||||
 | 
					    case Settings::ScalingFilter::NearestNeighbor:
 | 
				
			||||||
 | 
					        fragment_handle = present_bilinear_fragment.handle;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    case Settings::ScalingFilter::Bilinear:
 | 
					    case Settings::ScalingFilter::Bilinear:
 | 
				
			||||||
        fragment_handle = present_bilinear_fragment.handle;
 | 
					        fragment_handle = present_bilinear_fragment.handle;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -355,6 +362,12 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
 | 
				
			|||||||
    case Settings::ScalingFilter::ScaleForce:
 | 
					    case Settings::ScalingFilter::ScaleForce:
 | 
				
			||||||
        fragment_handle = present_scaleforce_fragment.handle;
 | 
					        fragment_handle = present_scaleforce_fragment.handle;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case Settings::ScalingFilter::Fsr:
 | 
				
			||||||
 | 
					        LOG_WARNING(
 | 
				
			||||||
 | 
					            Render_OpenGL,
 | 
				
			||||||
 | 
					            "FidelityFX FSR Super Sampling is not supported in OpenGL, changing to ScaleForce");
 | 
				
			||||||
 | 
					        fragment_handle = present_scaleforce_fragment.handle;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        fragment_handle = present_bilinear_fragment.handle;
 | 
					        fragment_handle = present_bilinear_fragment.handle;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -464,7 +477,11 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    glBindTextureUnit(0, screen_info.display_texture);
 | 
					    glBindTextureUnit(0, screen_info.display_texture);
 | 
				
			||||||
    glBindSampler(0, present_sampler.handle);
 | 
					    if (Settings::values.scaling_filter.GetValue() != Settings::ScalingFilter::NearestNeighbor) {
 | 
				
			||||||
 | 
					        glBindSampler(0, present_sampler.handle);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        glBindSampler(0, present_sampler_nn.handle);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    glClear(GL_COLOR_BUFFER_BIT);
 | 
					    glClear(GL_COLOR_BUFFER_BIT);
 | 
				
			||||||
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 | 
					    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 | 
				
			||||||
 | 
				
			|||||||
@ -109,6 +109,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // OpenGL object IDs
 | 
					    // OpenGL object IDs
 | 
				
			||||||
    OGLSampler present_sampler;
 | 
					    OGLSampler present_sampler;
 | 
				
			||||||
 | 
					    OGLSampler present_sampler_nn;
 | 
				
			||||||
    OGLBuffer vertex_buffer;
 | 
					    OGLBuffer vertex_buffer;
 | 
				
			||||||
    OGLProgram present_vertex;
 | 
					    OGLProgram present_vertex;
 | 
				
			||||||
    OGLProgram present_bilinear_fragment;
 | 
					    OGLProgram present_bilinear_fragment;
 | 
				
			||||||
 | 
				
			|||||||
@ -152,7 +152,9 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
 | 
				
			|||||||
        use_accelerated ? screen_info.image_view : *raw_image_views[image_index];
 | 
					        use_accelerated ? screen_info.image_view : *raw_image_views[image_index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!fsr) {
 | 
					    if (!fsr) {
 | 
				
			||||||
        UpdateDescriptorSet(image_index, source_image_view);
 | 
					        const bool is_nn =
 | 
				
			||||||
 | 
					            Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::NearestNeighbor;
 | 
				
			||||||
 | 
					        UpdateDescriptorSet(image_index, source_image_view, is_nn);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BufferData data;
 | 
					    BufferData data;
 | 
				
			||||||
@ -247,7 +249,7 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
 | 
				
			|||||||
        crop_rect = crop_rect.Scale(Settings::values.resolution_info.up_factor);
 | 
					        crop_rect = crop_rect.Scale(Settings::values.resolution_info.up_factor);
 | 
				
			||||||
        VkImageView fsr_image_view =
 | 
					        VkImageView fsr_image_view =
 | 
				
			||||||
            fsr->Draw(scheduler, image_index, source_image_view, crop_rect);
 | 
					            fsr->Draw(scheduler, image_index, source_image_view, crop_rect);
 | 
				
			||||||
        UpdateDescriptorSet(image_index, fsr_image_view);
 | 
					        UpdateDescriptorSet(image_index, fsr_image_view, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    scheduler.Record(
 | 
					    scheduler.Record(
 | 
				
			||||||
@ -286,6 +288,9 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
 | 
				
			|||||||
            const auto filter = Settings::values.scaling_filter.GetValue();
 | 
					            const auto filter = Settings::values.scaling_filter.GetValue();
 | 
				
			||||||
            cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
 | 
					            cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
 | 
				
			||||||
            switch (filter) {
 | 
					            switch (filter) {
 | 
				
			||||||
 | 
					            case Settings::ScalingFilter::NearestNeighbor:
 | 
				
			||||||
 | 
					                cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
            case Settings::ScalingFilter::Bilinear:
 | 
					            case Settings::ScalingFilter::Bilinear:
 | 
				
			||||||
                cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline);
 | 
					                cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
@ -745,13 +750,33 @@ void VKBlitScreen::CreateGraphicsPipeline() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void VKBlitScreen::CreateSampler() {
 | 
					void VKBlitScreen::CreateSampler() {
 | 
				
			||||||
    bool linear = Settings::values.scaling_filter.GetValue() != Settings::ScalingFilter::Fsr;
 | 
					 | 
				
			||||||
    const VkSamplerCreateInfo ci{
 | 
					    const VkSamplerCreateInfo ci{
 | 
				
			||||||
        .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
 | 
					        .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
 | 
				
			||||||
        .pNext = nullptr,
 | 
					        .pNext = nullptr,
 | 
				
			||||||
        .flags = 0,
 | 
					        .flags = 0,
 | 
				
			||||||
        .magFilter = linear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST,
 | 
					        .magFilter = VK_FILTER_LINEAR,
 | 
				
			||||||
        .minFilter = linear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST,
 | 
					        .minFilter = VK_FILTER_LINEAR,
 | 
				
			||||||
 | 
					        .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
 | 
				
			||||||
 | 
					        .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
 | 
				
			||||||
 | 
					        .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
 | 
				
			||||||
 | 
					        .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
 | 
				
			||||||
 | 
					        .mipLodBias = 0.0f,
 | 
				
			||||||
 | 
					        .anisotropyEnable = VK_FALSE,
 | 
				
			||||||
 | 
					        .maxAnisotropy = 0.0f,
 | 
				
			||||||
 | 
					        .compareEnable = VK_FALSE,
 | 
				
			||||||
 | 
					        .compareOp = VK_COMPARE_OP_NEVER,
 | 
				
			||||||
 | 
					        .minLod = 0.0f,
 | 
				
			||||||
 | 
					        .maxLod = 0.0f,
 | 
				
			||||||
 | 
					        .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
 | 
				
			||||||
 | 
					        .unnormalizedCoordinates = VK_FALSE,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const VkSamplerCreateInfo ci_nn{
 | 
				
			||||||
 | 
					        .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
 | 
				
			||||||
 | 
					        .pNext = nullptr,
 | 
				
			||||||
 | 
					        .flags = 0,
 | 
				
			||||||
 | 
					        .magFilter = VK_FILTER_NEAREST,
 | 
				
			||||||
 | 
					        .minFilter = VK_FILTER_NEAREST,
 | 
				
			||||||
        .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
 | 
					        .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
 | 
				
			||||||
        .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
 | 
					        .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
 | 
				
			||||||
        .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
 | 
					        .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
 | 
				
			||||||
@ -768,6 +793,7 @@ void VKBlitScreen::CreateSampler() {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sampler = device.GetLogical().CreateSampler(ci);
 | 
					    sampler = device.GetLogical().CreateSampler(ci);
 | 
				
			||||||
 | 
					    nn_sampler = device.GetLogical().CreateSampler(ci_nn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void VKBlitScreen::CreateFramebuffers() {
 | 
					void VKBlitScreen::CreateFramebuffers() {
 | 
				
			||||||
@ -862,7 +888,8 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const {
 | 
					void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view,
 | 
				
			||||||
 | 
					                                       bool nn) const {
 | 
				
			||||||
    const VkDescriptorBufferInfo buffer_info{
 | 
					    const VkDescriptorBufferInfo buffer_info{
 | 
				
			||||||
        .buffer = *buffer,
 | 
					        .buffer = *buffer,
 | 
				
			||||||
        .offset = offsetof(BufferData, uniform),
 | 
					        .offset = offsetof(BufferData, uniform),
 | 
				
			||||||
@ -883,7 +910,7 @@ void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView imag
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const VkDescriptorImageInfo image_info{
 | 
					    const VkDescriptorImageInfo image_info{
 | 
				
			||||||
        .sampler = *sampler,
 | 
					        .sampler = nn ? *nn_sampler : *sampler,
 | 
				
			||||||
        .imageView = image_view,
 | 
					        .imageView = image_view,
 | 
				
			||||||
        .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
 | 
					        .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
				
			|||||||
@ -90,7 +90,7 @@ private:
 | 
				
			|||||||
    void CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer);
 | 
					    void CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer);
 | 
				
			||||||
    void CreateRawImages(const Tegra::FramebufferConfig& framebuffer);
 | 
					    void CreateRawImages(const Tegra::FramebufferConfig& framebuffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const;
 | 
					    void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view, bool nn) const;
 | 
				
			||||||
    void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const;
 | 
					    void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const;
 | 
				
			||||||
    void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer,
 | 
					    void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer,
 | 
				
			||||||
                       const Layout::FramebufferLayout layout) const;
 | 
					                       const Layout::FramebufferLayout layout) const;
 | 
				
			||||||
@ -115,12 +115,14 @@ private:
 | 
				
			|||||||
    vk::DescriptorPool descriptor_pool;
 | 
					    vk::DescriptorPool descriptor_pool;
 | 
				
			||||||
    vk::DescriptorSetLayout descriptor_set_layout;
 | 
					    vk::DescriptorSetLayout descriptor_set_layout;
 | 
				
			||||||
    vk::PipelineLayout pipeline_layout;
 | 
					    vk::PipelineLayout pipeline_layout;
 | 
				
			||||||
 | 
					    vk::Pipeline nearest_neightbor_pipeline;
 | 
				
			||||||
    vk::Pipeline bilinear_pipeline;
 | 
					    vk::Pipeline bilinear_pipeline;
 | 
				
			||||||
    vk::Pipeline bicubic_pipeline;
 | 
					    vk::Pipeline bicubic_pipeline;
 | 
				
			||||||
    vk::Pipeline scaleforce_pipeline;
 | 
					    vk::Pipeline scaleforce_pipeline;
 | 
				
			||||||
    vk::RenderPass renderpass;
 | 
					    vk::RenderPass renderpass;
 | 
				
			||||||
    std::vector<vk::Framebuffer> framebuffers;
 | 
					    std::vector<vk::Framebuffer> framebuffers;
 | 
				
			||||||
    vk::DescriptorSets descriptor_sets;
 | 
					    vk::DescriptorSets descriptor_sets;
 | 
				
			||||||
 | 
					    vk::Sampler nn_sampler;
 | 
				
			||||||
    vk::Sampler sampler;
 | 
					    vk::Sampler sampler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vk::Buffer buffer;
 | 
					    vk::Buffer buffer;
 | 
				
			||||||
 | 
				
			|||||||
@ -387,6 +387,11 @@
 | 
				
			|||||||
           </item>
 | 
					           </item>
 | 
				
			||||||
           <item>
 | 
					           <item>
 | 
				
			||||||
            <widget class="QComboBox" name="scaling_filter_combobox">
 | 
					            <widget class="QComboBox" name="scaling_filter_combobox">
 | 
				
			||||||
 | 
					             <item>
 | 
				
			||||||
 | 
					              <property name="text">
 | 
				
			||||||
 | 
					               <string>Nearest Neighbor</string>
 | 
				
			||||||
 | 
					              </property>
 | 
				
			||||||
 | 
					             </item>
 | 
				
			||||||
             <item>
 | 
					             <item>
 | 
				
			||||||
              <property name="text">
 | 
					              <property name="text">
 | 
				
			||||||
               <string>Bilinear</string>
 | 
					               <string>Bilinear</string>
 | 
				
			||||||
@ -404,7 +409,7 @@
 | 
				
			|||||||
             </item>
 | 
					             </item>
 | 
				
			||||||
             <item>
 | 
					             <item>
 | 
				
			||||||
              <property name="text">
 | 
					              <property name="text">
 | 
				
			||||||
               <string>FidelityFX Super Resolution</string>
 | 
					               <string>FidelityFX Super Resolution [Vulkan Only]</string>
 | 
				
			||||||
              </property>
 | 
					              </property>
 | 
				
			||||||
             </item>
 | 
					             </item>
 | 
				
			||||||
            </widget>
 | 
					            </widget>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user