From f369e3c4763f3ac233cfedc428e93de1dd63da08 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Mon, 4 Jan 2021 01:32:14 +1000 Subject: [PATCH] HostDisplay: Fix vram pixels bleeding into edges of display with linear filtering --- src/frontend-common/d3d11_host_display.cpp | 11 +++++++---- src/frontend-common/opengl_host_display.cpp | 12 ++++++++---- src/frontend-common/vulkan_host_display.cpp | 10 ++++++---- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/frontend-common/d3d11_host_display.cpp b/src/frontend-common/d3d11_host_display.cpp index 52faef725..ee8b30575 100644 --- a/src/frontend-common/d3d11_host_display.cpp +++ b/src/frontend-common/d3d11_host_display.cpp @@ -764,10 +764,13 @@ void D3D11HostDisplay::RenderDisplay(s32 left, s32 top, s32 width, s32 height, v m_context->PSSetShaderResources(0, 1, reinterpret_cast(&texture_handle)); m_context->PSSetSamplers(0, 1, linear_filter ? m_linear_sampler.GetAddressOf() : m_point_sampler.GetAddressOf()); - const float uniforms[4] = {static_cast(texture_view_x) / static_cast(texture_width), - static_cast(texture_view_y) / static_cast(texture_height), - (static_cast(texture_view_width) - 0.5f) / static_cast(texture_width), - (static_cast(texture_view_height) - 0.5f) / static_cast(texture_height)}; + const float position_adjust = m_display_linear_filtering ? 0.5f : 0.0f; + const float size_adjust = m_display_linear_filtering ? 1.0f : 0.0f; + const float uniforms[4] = { + (static_cast(texture_view_x) + position_adjust) / static_cast(texture_width), + (static_cast(texture_view_y) + position_adjust) / static_cast(texture_height), + (static_cast(texture_view_width) - size_adjust) / static_cast(texture_width), + (static_cast(texture_view_height) - size_adjust) / static_cast(texture_height)}; const auto map = m_display_uniform_buffer.Map(m_context.Get(), m_display_uniform_buffer.GetSize(), sizeof(uniforms)); std::memcpy(map.pointer, uniforms, sizeof(uniforms)); m_display_uniform_buffer.Unmap(m_context.Get(), sizeof(uniforms)); diff --git a/src/frontend-common/opengl_host_display.cpp b/src/frontend-common/opengl_host_display.cpp index 0c3b818f5..b6bce7f06 100644 --- a/src/frontend-common/opengl_host_display.cpp +++ b/src/frontend-common/opengl_host_display.cpp @@ -775,10 +775,14 @@ void OpenGLHostDisplay::RenderDisplay(s32 left, s32 bottom, s32 width, s32 heigh if (!m_use_gles2_draw_path) { - m_display_program.Uniform4f(0, static_cast(texture_view_x) / static_cast(texture_width), - static_cast(texture_view_y) / static_cast(texture_height), - (static_cast(texture_view_width) - 0.5f) / static_cast(texture_width), - (static_cast(texture_view_height) + 0.5f) / static_cast(texture_height)); + const float position_adjust = m_display_linear_filtering ? 0.5f : 0.0f; + const float size_adjust = m_display_linear_filtering ? 1.0f : 0.0f; + const float flip_adjust = (texture_view_height < 0) ? -1.0f : 1.0f; + m_display_program.Uniform4f( + 0, (static_cast(texture_view_x) + position_adjust) / static_cast(texture_width), + (static_cast(texture_view_y) + (position_adjust * flip_adjust)) / static_cast(texture_height), + (static_cast(texture_view_width) - size_adjust) / static_cast(texture_width), + (static_cast(texture_view_height) - (size_adjust * flip_adjust)) / static_cast(texture_height)); glBindSampler(0, linear_filter ? m_display_linear_sampler : m_display_nearest_sampler); glBindVertexArray(m_display_vao); glDrawArrays(GL_TRIANGLES, 0, 3); diff --git a/src/frontend-common/vulkan_host_display.cpp b/src/frontend-common/vulkan_host_display.cpp index da493d6d1..303ae60f0 100644 --- a/src/frontend-common/vulkan_host_display.cpp +++ b/src/frontend-common/vulkan_host_display.cpp @@ -714,10 +714,12 @@ void VulkanHostDisplay::RenderDisplay(s32 left, s32 top, s32 width, s32 height, dsupdate.Update(g_vulkan_context->GetDevice()); } - const PushConstants pc{static_cast(texture_view_x) / static_cast(texture_width), - static_cast(texture_view_y) / static_cast(texture_height), - (static_cast(texture_view_width) - 0.5f) / static_cast(texture_width), - (static_cast(texture_view_height) - 0.5f) / static_cast(texture_height)}; + const float position_adjust = m_display_linear_filtering ? 0.5f : 0.0f; + const float size_adjust = m_display_linear_filtering ? 1.0f : 0.0f; + const PushConstants pc{(static_cast(texture_view_x) + position_adjust) / static_cast(texture_width), + (static_cast(texture_view_y) + position_adjust) / static_cast(texture_height), + (static_cast(texture_view_width) - size_adjust) / static_cast(texture_width), + (static_cast(texture_view_height) - size_adjust) / static_cast(texture_height)}; vkCmdBindPipeline(cmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_display_pipeline); vkCmdPushConstants(cmdbuffer, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(pc), &pc);