Frontends: Pick best render API based on renderer
Stops unnecessary display recreation in big picture UI.
This commit is contained in:
@ -366,7 +366,7 @@ protected:
|
||||
u32 m_multisamples = 1;
|
||||
u32 m_max_resolution_scale = 1;
|
||||
u32 m_max_multisamples = 1;
|
||||
HostDisplay::RenderAPI m_render_api = HostDisplay::RenderAPI::None;
|
||||
RenderAPI m_render_api = RenderAPI::None;
|
||||
bool m_true_color = true;
|
||||
|
||||
union
|
||||
|
||||
@ -35,7 +35,7 @@ GPURenderer GPU_HW_D3D11::GetRendererType() const
|
||||
|
||||
bool GPU_HW_D3D11::Initialize()
|
||||
{
|
||||
if (!Host::AcquireHostDisplay(HostDisplay::RenderAPI::D3D11))
|
||||
if (!Host::AcquireHostDisplay(RenderAPI::D3D11))
|
||||
{
|
||||
Log_ErrorPrintf("Host render API is incompatible");
|
||||
return false;
|
||||
|
||||
@ -34,7 +34,7 @@ GPURenderer GPU_HW_D3D12::GetRendererType() const
|
||||
|
||||
bool GPU_HW_D3D12::Initialize()
|
||||
{
|
||||
if (!Host::AcquireHostDisplay(HostDisplay::RenderAPI::D3D12))
|
||||
if (!Host::AcquireHostDisplay(RenderAPI::D3D12))
|
||||
{
|
||||
Log_ErrorPrintf("Host render API is incompatible");
|
||||
return false;
|
||||
|
||||
@ -43,16 +43,16 @@ GPURenderer GPU_HW_OpenGL::GetRendererType() const
|
||||
|
||||
bool GPU_HW_OpenGL::Initialize()
|
||||
{
|
||||
if (!Host::AcquireHostDisplay(HostDisplay::RenderAPI::OpenGL))
|
||||
if (!Host::AcquireHostDisplay(RenderAPI::OpenGL))
|
||||
{
|
||||
Log_ErrorPrintf("Host render API type is incompatible");
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool opengl_is_available =
|
||||
((g_host_display->GetRenderAPI() == HostDisplay::RenderAPI::OpenGL &&
|
||||
((g_host_display->GetRenderAPI() == RenderAPI::OpenGL &&
|
||||
(GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_uniform_buffer_object)) ||
|
||||
(g_host_display->GetRenderAPI() == HostDisplay::RenderAPI::OpenGLES && GLAD_GL_ES_VERSION_3_0));
|
||||
(g_host_display->GetRenderAPI() == RenderAPI::OpenGLES && GLAD_GL_ES_VERSION_3_0));
|
||||
if (!opengl_is_available)
|
||||
{
|
||||
Host::AddOSDMessage(Host::TranslateStdString("OSDMessage",
|
||||
|
||||
@ -53,7 +53,7 @@ private:
|
||||
u32 num_uniform_buffer_updates;
|
||||
};
|
||||
|
||||
ALWAYS_INLINE bool IsGLES() const { return (m_render_api == HostDisplay::RenderAPI::OpenGLES); }
|
||||
ALWAYS_INLINE bool IsGLES() const { return (m_render_api == RenderAPI::OpenGLES); }
|
||||
|
||||
std::tuple<s32, s32> ConvertToFramebufferCoordinates(s32 x, s32 y);
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include "common/assert.h"
|
||||
#include <cstdio>
|
||||
|
||||
GPU_HW_ShaderGen::GPU_HW_ShaderGen(HostDisplay::RenderAPI render_api, u32 resolution_scale, u32 multisamples,
|
||||
GPU_HW_ShaderGen::GPU_HW_ShaderGen(RenderAPI render_api, u32 resolution_scale, u32 multisamples,
|
||||
bool per_sample_shading, bool true_color, bool scaled_dithering,
|
||||
GPUTextureFilter texture_filtering, bool uv_limits, bool pgxp_depth,
|
||||
bool supports_dual_source_blend)
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
class GPU_HW_ShaderGen : public ShaderGen
|
||||
{
|
||||
public:
|
||||
GPU_HW_ShaderGen(HostDisplay::RenderAPI render_api, u32 resolution_scale, u32 multisamples, bool per_sample_shading,
|
||||
GPU_HW_ShaderGen(RenderAPI render_api, u32 resolution_scale, u32 multisamples, bool per_sample_shading,
|
||||
bool true_color, bool scaled_dithering, GPUTextureFilter texture_filtering, bool uv_limits,
|
||||
bool pgxp_depth, bool supports_dual_source_blend);
|
||||
~GPU_HW_ShaderGen();
|
||||
|
||||
@ -33,7 +33,7 @@ GPURenderer GPU_HW_Vulkan::GetRendererType() const
|
||||
|
||||
bool GPU_HW_Vulkan::Initialize()
|
||||
{
|
||||
if (!Host::AcquireHostDisplay(HostDisplay::RenderAPI::Vulkan))
|
||||
if (!Host::AcquireHostDisplay(RenderAPI::Vulkan))
|
||||
{
|
||||
Log_ErrorPrintf("Host render API is incompatible");
|
||||
return false;
|
||||
|
||||
@ -21,7 +21,7 @@ HostDisplayTexture::~HostDisplayTexture() = default;
|
||||
|
||||
HostDisplay::~HostDisplay() = default;
|
||||
|
||||
HostDisplay::RenderAPI HostDisplay::GetPreferredAPI()
|
||||
RenderAPI HostDisplay::GetPreferredAPI()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return RenderAPI::D3D11;
|
||||
|
||||
@ -8,6 +8,16 @@
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
enum class RenderAPI : u32
|
||||
{
|
||||
None,
|
||||
D3D11,
|
||||
D3D12,
|
||||
Vulkan,
|
||||
OpenGL,
|
||||
OpenGLES
|
||||
};
|
||||
|
||||
enum class HostDisplayPixelFormat : u32
|
||||
{
|
||||
Unknown,
|
||||
@ -37,16 +47,6 @@ public:
|
||||
class HostDisplay
|
||||
{
|
||||
public:
|
||||
enum class RenderAPI
|
||||
{
|
||||
None,
|
||||
D3D11,
|
||||
D3D12,
|
||||
Vulkan,
|
||||
OpenGL,
|
||||
OpenGLES
|
||||
};
|
||||
|
||||
enum class Alignment
|
||||
{
|
||||
LeftOrTop,
|
||||
@ -304,10 +304,10 @@ protected:
|
||||
extern std::unique_ptr<HostDisplay> g_host_display;
|
||||
|
||||
namespace Host {
|
||||
std::unique_ptr<HostDisplay> CreateDisplayForAPI(HostDisplay::RenderAPI api);
|
||||
std::unique_ptr<HostDisplay> CreateDisplayForAPI(RenderAPI api);
|
||||
|
||||
/// Creates the host display. This may create a new window. The API used depends on the current configuration.
|
||||
bool AcquireHostDisplay(HostDisplay::RenderAPI api);
|
||||
bool AcquireHostDisplay(RenderAPI api);
|
||||
|
||||
/// Destroys the host display. This may close the display window.
|
||||
void ReleaseHostDisplay();
|
||||
|
||||
@ -850,6 +850,30 @@ const char* Settings::GetRendererDisplayName(GPURenderer renderer)
|
||||
return s_gpu_renderer_display_names[static_cast<int>(renderer)];
|
||||
}
|
||||
|
||||
RenderAPI Settings::GetRenderAPIForRenderer(GPURenderer renderer)
|
||||
{
|
||||
switch (renderer)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
case GPURenderer::HardwareD3D11:
|
||||
return RenderAPI::D3D11;
|
||||
case GPURenderer::HardwareD3D12:
|
||||
return RenderAPI::D3D12;
|
||||
#endif
|
||||
#ifdef WITH_VULKAN
|
||||
case GPURenderer::HardwareVulkan:
|
||||
return RenderAPI::Vulkan;
|
||||
#endif
|
||||
#ifdef WITH_OPENGL
|
||||
case GPURenderer::HardwareOpenGL:
|
||||
return RenderAPI::OpenGL;
|
||||
#endif
|
||||
case GPURenderer::Software:
|
||||
default:
|
||||
return HostDisplay::GetPreferredAPI();
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr auto s_texture_filter_names =
|
||||
make_array("Nearest", "Bilinear", "BilinearBinAlpha", "JINC2", "JINC2BinAlpha", "xBR", "xBRBinAlpha");
|
||||
static constexpr auto s_texture_filter_display_names =
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum class RenderAPI : u32;
|
||||
|
||||
struct SettingInfo
|
||||
{
|
||||
enum class Type
|
||||
@ -332,6 +334,7 @@ struct Settings
|
||||
static std::optional<GPURenderer> ParseRendererName(const char* str);
|
||||
static const char* GetRendererName(GPURenderer renderer);
|
||||
static const char* GetRendererDisplayName(GPURenderer renderer);
|
||||
static RenderAPI GetRenderAPIForRenderer(GPURenderer renderer);
|
||||
|
||||
static std::optional<GPUTextureFilter> ParseTextureFilterName(const char* str);
|
||||
static const char* GetTextureFilterName(GPUTextureFilter filter);
|
||||
|
||||
@ -10,22 +10,22 @@
|
||||
|
||||
Log_SetChannel(ShaderGen);
|
||||
|
||||
ShaderGen::ShaderGen(HostDisplay::RenderAPI render_api, bool supports_dual_source_blend)
|
||||
ShaderGen::ShaderGen(RenderAPI render_api, bool supports_dual_source_blend)
|
||||
: m_render_api(render_api),
|
||||
m_glsl(render_api != HostDisplay::RenderAPI::D3D11 && render_api != HostDisplay::RenderAPI::D3D12),
|
||||
m_glsl(render_api != RenderAPI::D3D11 && render_api != RenderAPI::D3D12),
|
||||
m_supports_dual_source_blend(supports_dual_source_blend), m_use_glsl_interface_blocks(false)
|
||||
{
|
||||
#if defined(WITH_OPENGL) || defined(WITH_VULKAN)
|
||||
if (m_glsl)
|
||||
{
|
||||
#ifdef WITH_OPENGL
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGL || m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||
if (m_render_api == RenderAPI::OpenGL || m_render_api == RenderAPI::OpenGLES)
|
||||
SetGLSLVersionString();
|
||||
|
||||
m_use_glsl_interface_blocks = (IsVulkan() || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_VERSION_3_2);
|
||||
m_use_glsl_binding_layout = (IsVulkan() || UseGLSLBindingLayout());
|
||||
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGL)
|
||||
if (m_render_api == RenderAPI::OpenGL)
|
||||
{
|
||||
// SSAA with interface blocks is broken on AMD's OpenGL driver.
|
||||
const char* gl_vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
||||
@ -62,7 +62,7 @@ void ShaderGen::DefineMacro(std::stringstream& ss, const char* name, bool enable
|
||||
void ShaderGen::SetGLSLVersionString()
|
||||
{
|
||||
const char* glsl_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
const bool glsl_es = (m_render_api == HostDisplay::RenderAPI::OpenGLES);
|
||||
const bool glsl_es = (m_render_api == RenderAPI::OpenGLES);
|
||||
Assert(glsl_version != nullptr);
|
||||
|
||||
// Skip any strings in front of the version code.
|
||||
@ -105,14 +105,14 @@ void ShaderGen::SetGLSLVersionString()
|
||||
|
||||
void ShaderGen::WriteHeader(std::stringstream& ss)
|
||||
{
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGL || m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||
if (m_render_api == RenderAPI::OpenGL || m_render_api == RenderAPI::OpenGLES)
|
||||
ss << m_glsl_version_string << "\n\n";
|
||||
else if (m_render_api == HostDisplay::RenderAPI::Vulkan)
|
||||
else if (m_render_api == RenderAPI::Vulkan)
|
||||
ss << "#version 450 core\n\n";
|
||||
|
||||
#ifdef WITH_OPENGL
|
||||
// Extension enabling for OpenGL.
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||
if (m_render_api == RenderAPI::OpenGLES)
|
||||
{
|
||||
// Enable EXT_blend_func_extended for dual-source blend on OpenGL ES.
|
||||
if (GLAD_GL_EXT_blend_func_extended)
|
||||
@ -131,7 +131,7 @@ void ShaderGen::WriteHeader(std::stringstream& ss)
|
||||
ss << "#define DRIVER_POWERVR 1\n";
|
||||
}
|
||||
}
|
||||
else if (m_render_api == HostDisplay::RenderAPI::OpenGL)
|
||||
else if (m_render_api == RenderAPI::OpenGL)
|
||||
{
|
||||
// Need extensions for binding layout if GL<4.3.
|
||||
if (m_use_glsl_binding_layout && !GLAD_GL_VERSION_4_3)
|
||||
@ -150,14 +150,14 @@ void ShaderGen::WriteHeader(std::stringstream& ss)
|
||||
}
|
||||
#endif
|
||||
|
||||
DefineMacro(ss, "API_OPENGL", m_render_api == HostDisplay::RenderAPI::OpenGL);
|
||||
DefineMacro(ss, "API_OPENGL_ES", m_render_api == HostDisplay::RenderAPI::OpenGLES);
|
||||
DefineMacro(ss, "API_D3D11", m_render_api == HostDisplay::RenderAPI::D3D11);
|
||||
DefineMacro(ss, "API_D3D12", m_render_api == HostDisplay::RenderAPI::D3D12);
|
||||
DefineMacro(ss, "API_VULKAN", m_render_api == HostDisplay::RenderAPI::Vulkan);
|
||||
DefineMacro(ss, "API_OPENGL", m_render_api == RenderAPI::OpenGL);
|
||||
DefineMacro(ss, "API_OPENGL_ES", m_render_api == RenderAPI::OpenGLES);
|
||||
DefineMacro(ss, "API_D3D11", m_render_api == RenderAPI::D3D11);
|
||||
DefineMacro(ss, "API_D3D12", m_render_api == RenderAPI::D3D12);
|
||||
DefineMacro(ss, "API_VULKAN", m_render_api == RenderAPI::Vulkan);
|
||||
|
||||
#ifdef WITH_OPENGL
|
||||
if (m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||
if (m_render_api == RenderAPI::OpenGLES)
|
||||
{
|
||||
ss << "precision highp float;\n";
|
||||
ss << "precision highp int;\n";
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
class ShaderGen
|
||||
{
|
||||
public:
|
||||
ShaderGen(HostDisplay::RenderAPI render_api, bool supports_dual_source_blend);
|
||||
ShaderGen(RenderAPI render_api, bool supports_dual_source_blend);
|
||||
~ShaderGen();
|
||||
|
||||
static bool UseGLSLBindingLayout();
|
||||
@ -19,7 +19,7 @@ public:
|
||||
std::string GenerateSampleFragmentShader();
|
||||
|
||||
protected:
|
||||
ALWAYS_INLINE bool IsVulkan() const { return (m_render_api == HostDisplay::RenderAPI::Vulkan); }
|
||||
ALWAYS_INLINE bool IsVulkan() const { return (m_render_api == RenderAPI::Vulkan); }
|
||||
|
||||
const char* GetInterpolationQualifier(bool interface_block, bool centroid_interpolation, bool sample_interpolation,
|
||||
bool is_out) const;
|
||||
@ -45,7 +45,7 @@ protected:
|
||||
bool declare_fragcoord = false, u32 num_color_outputs = 1, bool depth_output = false,
|
||||
bool msaa = false, bool ssaa = false, bool declare_sample_id = false);
|
||||
|
||||
HostDisplay::RenderAPI m_render_api;
|
||||
RenderAPI m_render_api;
|
||||
bool m_glsl;
|
||||
bool m_supports_dual_source_blend;
|
||||
bool m_use_glsl_interface_blocks;
|
||||
|
||||
Reference in New Issue
Block a user