yuzu-emu
/
yuzu-android
Archived
1
0
Fork 0

Presentation: add Nearest Neighbor filter.

This commit is contained in:
Fernando Sahmkow 2021-10-17 17:22:16 +02:00
parent 77b0812d69
commit b60966041c
6 changed files with 67 additions and 14 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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;

View File

@ -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,
}; };

View File

@ -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;

View File

@ -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>