diff --git a/Source/Core/Common/WindowSystemInfo.h b/Source/Core/Common/WindowSystemInfo.h index 897d034c2c..bea853d445 100644 --- a/Source/Core/Common/WindowSystemInfo.h +++ b/Source/Core/Common/WindowSystemInfo.h @@ -32,4 +32,7 @@ struct WindowSystemInfo // on the platform. e.g. HWND for Windows, Window for X11. If the surface is // set to nullptr, the video backend will run in headless mode. void* render_surface = nullptr; + + // Scale of the render surface. For hidpi systems, this will be >1. + float render_surface_scale = 1.0f; }; diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index ef9557e3db..9caf98d966 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -164,6 +164,7 @@ static WindowSystemInfo GetWindowSystemInfo(QWindow* window) else wsi.render_surface = window ? reinterpret_cast(window->winId()) : nullptr; #endif + wsi.render_surface_scale = window ? static_cast(window->devicePixelRatio()) : 1.0f; return wsi; } diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index aff6fe6bc0..8e98fc8832 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -62,8 +62,9 @@ typedef struct _Nv_Stereo_Image_Header #define NVSTEREO_IMAGE_SIGNATURE 0x4433564e -Renderer::Renderer(int backbuffer_width, int backbuffer_height) - : ::Renderer(backbuffer_width, backbuffer_height, AbstractTextureFormat::RGBA8) +Renderer::Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale) + : ::Renderer(backbuffer_width, backbuffer_height, backbuffer_scale, + AbstractTextureFormat::RGBA8) { m_last_multisamples = g_ActiveConfig.iMultisamples; m_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off; diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index 68f7f2b669..fc0b95acfc 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -18,7 +18,7 @@ class D3DTexture2D; class Renderer : public ::Renderer { public: - Renderer(int backbuffer_width, int backbuffer_height); + Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale); ~Renderer() override; StateCache& GetStateCache() { return m_state_cache; } diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp index 684bc1350b..27c880e730 100644 --- a/Source/Core/VideoBackends/D3D/main.cpp +++ b/Source/Core/VideoBackends/D3D/main.cpp @@ -147,7 +147,8 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi) } // internal interfaces - g_renderer = std::make_unique(backbuffer_width, backbuffer_height); + g_renderer = + std::make_unique(backbuffer_width, backbuffer_height, wsi.render_surface_scale); g_shader_cache = std::make_unique(); g_texture_cache = std::make_unique(); g_vertex_manager = std::make_unique(); diff --git a/Source/Core/VideoBackends/Null/Render.cpp b/Source/Core/VideoBackends/Null/Render.cpp index f905d95a0f..ff427626d3 100644 --- a/Source/Core/VideoBackends/Null/Render.cpp +++ b/Source/Core/VideoBackends/Null/Render.cpp @@ -14,7 +14,7 @@ namespace Null { // Init functions -Renderer::Renderer() : ::Renderer(1, 1, AbstractTextureFormat::RGBA8) +Renderer::Renderer() : ::Renderer(1, 1, 1.0f, AbstractTextureFormat::RGBA8) { UpdateActiveConfig(); } diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index dc724353d7..630cea738e 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -351,10 +351,10 @@ static void InitDriverInfo() } // Init functions -Renderer::Renderer(std::unique_ptr main_gl_context) +Renderer::Renderer(std::unique_ptr main_gl_context, float backbuffer_scale) : ::Renderer(static_cast(std::max(main_gl_context->GetBackBufferWidth(), 1u)), static_cast(std::max(main_gl_context->GetBackBufferHeight(), 1u)), - AbstractTextureFormat::RGBA8), + backbuffer_scale, AbstractTextureFormat::RGBA8), m_main_gl_context(std::move(main_gl_context)), m_current_rasterization_state(RenderState::GetInvalidRasterizationState()), m_current_depth_state(RenderState::GetInvalidDepthState()), diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index d31a87ce6a..43c110996b 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -83,7 +83,7 @@ extern VideoConfig g_ogl_config; class Renderer : public ::Renderer { public: - Renderer(std::unique_ptr main_gl_context); + Renderer(std::unique_ptr main_gl_context, float backbuffer_scale); ~Renderer() override; bool IsHeadless() const override; diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index c4ccbdcfd5..3624a7fd7a 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -172,7 +172,7 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi) if (!InitializeGLExtensions(main_gl_context.get()) || !FillBackendInfo()) return false; - g_renderer = std::make_unique(std::move(main_gl_context)); + g_renderer = std::make_unique(std::move(main_gl_context), wsi.render_surface_scale); g_vertex_manager = std::make_unique(); g_perf_query = GetPerfQuery(); ProgramShaderCache::Init(); diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp index 0dac3b264b..edddd5156f 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.cpp +++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp @@ -25,7 +25,7 @@ #include "VideoCommon/VideoConfig.h" SWRenderer::SWRenderer(std::unique_ptr window) - : ::Renderer(static_cast(MAX_XFB_WIDTH), static_cast(MAX_XFB_HEIGHT), + : ::Renderer(static_cast(MAX_XFB_WIDTH), static_cast(MAX_XFB_HEIGHT), 1.0f, AbstractTextureFormat::RGBA8), m_window(std::move(window)) { diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index eca10a1504..683df63d21 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -46,9 +46,9 @@ namespace Vulkan { -Renderer::Renderer(std::unique_ptr swap_chain) +Renderer::Renderer(std::unique_ptr swap_chain, float backbuffer_scale) : ::Renderer(swap_chain ? static_cast(swap_chain->GetWidth()) : 1, - swap_chain ? static_cast(swap_chain->GetHeight()) : 0, + swap_chain ? static_cast(swap_chain->GetHeight()) : 0, backbuffer_scale, swap_chain ? swap_chain->GetTextureFormat() : AbstractTextureFormat::Undefined), m_swap_chain(std::move(swap_chain)) { diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.h b/Source/Core/VideoBackends/Vulkan/Renderer.h index 7d109965cc..1fa3db7008 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.h +++ b/Source/Core/VideoBackends/Vulkan/Renderer.h @@ -29,7 +29,7 @@ class VKTexture; class Renderer : public ::Renderer { public: - Renderer(std::unique_ptr swap_chain); + Renderer(std::unique_ptr swap_chain, float backbuffer_scale); ~Renderer() override; static Renderer* GetInstance(); diff --git a/Source/Core/VideoBackends/Vulkan/main.cpp b/Source/Core/VideoBackends/Vulkan/main.cpp index 63d61c9d01..af3a7b56d8 100644 --- a/Source/Core/VideoBackends/Vulkan/main.cpp +++ b/Source/Core/VideoBackends/Vulkan/main.cpp @@ -225,7 +225,7 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi) // Create main wrapper instances. g_framebuffer_manager = std::make_unique(); - g_renderer = std::make_unique(std::move(swap_chain)); + g_renderer = std::make_unique(std::move(swap_chain), wsi.render_surface_scale); g_vertex_manager = std::make_unique(); g_texture_cache = std::make_unique(); ::g_shader_cache = std::make_unique(); diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index dd988b3f5c..be0e48728e 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -81,10 +81,10 @@ static float AspectToWidescreen(float aspect) return aspect * ((16.0f / 9.0f) / (4.0f / 3.0f)); } -Renderer::Renderer(int backbuffer_width, int backbuffer_height, +Renderer::Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, AbstractTextureFormat backbuffer_format) : m_backbuffer_width(backbuffer_width), m_backbuffer_height(backbuffer_height), - m_backbuffer_format(backbuffer_format) + m_backbuffer_scale(backbuffer_scale), m_backbuffer_format(backbuffer_format) { UpdateActiveConfig(); UpdateDrawRectangle(); diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index df0de0fa48..410d998497 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -63,7 +63,8 @@ extern int frameCount; class Renderer { public: - Renderer(int backbuffer_width, int backbuffer_height, AbstractTextureFormat backbuffer_format); + Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, + AbstractTextureFormat backbuffer_format); virtual ~Renderer(); using ClearColor = std::array; @@ -125,6 +126,7 @@ public: // Display resolution int GetBackbufferWidth() const { return m_backbuffer_width; } int GetBackbufferHeight() const { return m_backbuffer_height; } + float GetBackbufferScale() const { return m_backbuffer_scale; } void SetWindowSize(int width, int height); // EFB coordinate conversion functions @@ -229,6 +231,7 @@ protected: // Backbuffer (window) size and render area int m_backbuffer_width = 0; int m_backbuffer_height = 0; + float m_backbuffer_scale = 1.0f; AbstractTextureFormat m_backbuffer_format = AbstractTextureFormat::Undefined; TargetRectangle m_target_rectangle = {};