Presentation: add Nearest Neighbor filter.
This commit is contained in:
parent
77b0812d69
commit
b60966041c
6 changed files with 67 additions and 14 deletions
|
@ -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…
Reference in a new issue