GPU/OpenGL: Use explicit bindings where possible
This commit is contained in:
parent
9dc82a738f
commit
620210cfc9
|
@ -317,6 +317,7 @@ bool GPU_HW_OpenGL::CreateTextureBuffer()
|
||||||
|
|
||||||
bool GPU_HW_OpenGL::CompilePrograms()
|
bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
{
|
{
|
||||||
|
const bool use_binding_layout = GPU_HW_ShaderGen::UseGLSLBindingLayout();
|
||||||
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_scaled_dithering,
|
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_scaled_dithering,
|
||||||
m_texture_filtering, m_supports_dual_source_blend);
|
m_texture_filtering, m_supports_dual_source_blend);
|
||||||
|
|
||||||
|
@ -336,25 +337,28 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
static_cast<BatchRenderMode>(render_mode), static_cast<TextureMode>(texture_mode),
|
static_cast<BatchRenderMode>(render_mode), static_cast<TextureMode>(texture_mode),
|
||||||
ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing));
|
ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing));
|
||||||
|
|
||||||
const auto link_callback = [this, textured](GL::Program& prog) {
|
const auto link_callback = [this, textured, use_binding_layout](GL::Program& prog) {
|
||||||
prog.BindAttribute(0, "a_pos");
|
if (!use_binding_layout)
|
||||||
prog.BindAttribute(1, "a_col0");
|
|
||||||
if (textured)
|
|
||||||
{
|
{
|
||||||
prog.BindAttribute(2, "a_texcoord");
|
prog.BindAttribute(0, "a_pos");
|
||||||
prog.BindAttribute(3, "a_texpage");
|
prog.BindAttribute(1, "a_col0");
|
||||||
}
|
if (textured)
|
||||||
|
|
||||||
if (!m_is_gles)
|
|
||||||
{
|
|
||||||
if (m_supports_dual_source_blend)
|
|
||||||
{
|
{
|
||||||
prog.BindFragDataIndexed(0, "o_col0");
|
prog.BindAttribute(2, "a_texcoord");
|
||||||
prog.BindFragDataIndexed(1, "o_col1");
|
prog.BindAttribute(3, "a_texpage");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!m_is_gles || m_supports_dual_source_blend)
|
||||||
{
|
{
|
||||||
prog.BindFragData(0, "o_col0");
|
if (m_supports_dual_source_blend)
|
||||||
|
{
|
||||||
|
prog.BindFragDataIndexed(0, "o_col0");
|
||||||
|
prog.BindFragDataIndexed(1, "o_col1");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prog.BindFragData(0, "o_col0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -363,11 +367,14 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
if (!prog)
|
if (!prog)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prog->BindUniformBlock("UBOBlock", 1);
|
if (!use_binding_layout)
|
||||||
if (textured)
|
|
||||||
{
|
{
|
||||||
prog->Bind();
|
prog->BindUniformBlock("UBOBlock", 1);
|
||||||
prog->Uniform1i("samp0", 0);
|
if (textured)
|
||||||
|
{
|
||||||
|
prog->Bind();
|
||||||
|
prog->Uniform1i("samp0", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_render_programs[render_mode][texture_mode][dithering][interlacing] = std::move(*prog);
|
m_render_programs[render_mode][texture_mode][dithering][interlacing] = std::move(*prog);
|
||||||
|
@ -380,7 +387,8 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
if (!prog)
|
if (!prog)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prog->BindUniformBlock("UBOBlock", 1);
|
if (!use_binding_layout)
|
||||||
|
prog->BindUniformBlock("UBOBlock", 1);
|
||||||
m_line_render_programs[render_mode][dithering][interlacing] = std::move(*prog);
|
m_line_render_programs[render_mode][dithering][interlacing] = std::move(*prog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,73 +404,89 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
const std::string fs = shadergen.GenerateDisplayFragmentShader(ConvertToBoolUnchecked(depth_24bit),
|
const std::string fs = shadergen.GenerateDisplayFragmentShader(ConvertToBoolUnchecked(depth_24bit),
|
||||||
ConvertToBoolUnchecked(interlaced));
|
ConvertToBoolUnchecked(interlaced));
|
||||||
|
|
||||||
std::optional<GL::Program> prog = m_shader_cache.GetProgram(vs, {}, fs, [this](GL::Program& prog) {
|
std::optional<GL::Program> prog =
|
||||||
if (!m_is_gles)
|
m_shader_cache.GetProgram(vs, {}, fs, [this, use_binding_layout](GL::Program& prog) {
|
||||||
prog.BindFragData(0, "o_col0");
|
if (!m_is_gles && !use_binding_layout)
|
||||||
});
|
prog.BindFragData(0, "o_col0");
|
||||||
|
});
|
||||||
if (!prog)
|
if (!prog)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prog->BindUniformBlock("UBOBlock", 1);
|
if (!use_binding_layout)
|
||||||
|
{
|
||||||
prog->Bind();
|
prog->BindUniformBlock("UBOBlock", 1);
|
||||||
prog->Uniform1i("samp0", 0);
|
prog->Bind();
|
||||||
|
prog->Uniform1i("samp0", 0);
|
||||||
|
}
|
||||||
m_display_programs[depth_24bit][interlaced] = std::move(*prog);
|
m_display_programs[depth_24bit][interlaced] = std::move(*prog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<GL::Program> prog =
|
std::optional<GL::Program> prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
||||||
m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
shadergen.GenerateInterlacedFillFragmentShader(),
|
||||||
shadergen.GenerateInterlacedFillFragmentShader(), [this](GL::Program& prog) {
|
[this, use_binding_layout](GL::Program& prog) {
|
||||||
if (!m_is_gles)
|
if (!m_is_gles && !use_binding_layout)
|
||||||
prog.BindFragData(0, "o_col0");
|
prog.BindFragData(0, "o_col0");
|
||||||
});
|
});
|
||||||
if (!prog)
|
if (!prog)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prog->BindUniformBlock("UBOBlock", 1);
|
if (!use_binding_layout)
|
||||||
prog->Bind();
|
prog->BindUniformBlock("UBOBlock", 1);
|
||||||
|
|
||||||
m_vram_interlaced_fill_program = std::move(*prog);
|
m_vram_interlaced_fill_program = std::move(*prog);
|
||||||
|
|
||||||
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
||||||
shadergen.GenerateVRAMReadFragmentShader(), [this](GL::Program& prog) {
|
shadergen.GenerateVRAMReadFragmentShader(),
|
||||||
if (!m_is_gles)
|
[this, use_binding_layout](GL::Program& prog) {
|
||||||
|
if (!m_is_gles && !use_binding_layout)
|
||||||
prog.BindFragData(0, "o_col0");
|
prog.BindFragData(0, "o_col0");
|
||||||
});
|
});
|
||||||
if (!prog)
|
if (!prog)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prog->BindUniformBlock("UBOBlock", 1);
|
if (!use_binding_layout)
|
||||||
prog->Bind();
|
{
|
||||||
prog->Uniform1i("samp0", 0);
|
prog->BindUniformBlock("UBOBlock", 1);
|
||||||
|
prog->Bind();
|
||||||
|
prog->Uniform1i("samp0", 0);
|
||||||
|
}
|
||||||
m_vram_read_program = std::move(*prog);
|
m_vram_read_program = std::move(*prog);
|
||||||
|
|
||||||
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
||||||
shadergen.GenerateVRAMCopyFragmentShader(), [this](GL::Program& prog) {
|
shadergen.GenerateVRAMCopyFragmentShader(),
|
||||||
if (!m_is_gles)
|
[this, use_binding_layout](GL::Program& prog) {
|
||||||
|
if (!m_is_gles && !use_binding_layout)
|
||||||
prog.BindFragData(0, "o_col0");
|
prog.BindFragData(0, "o_col0");
|
||||||
});
|
});
|
||||||
if (!prog)
|
if (!prog)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prog->BindUniformBlock("UBOBlock", 1);
|
if (!use_binding_layout)
|
||||||
prog->Bind();
|
{
|
||||||
prog->Uniform1i("samp0", 0);
|
prog->BindUniformBlock("UBOBlock", 1);
|
||||||
|
prog->Bind();
|
||||||
|
prog->Uniform1i("samp0", 0);
|
||||||
|
}
|
||||||
m_vram_copy_program = std::move(*prog);
|
m_vram_copy_program = std::move(*prog);
|
||||||
|
|
||||||
if (m_supports_texture_buffer)
|
if (m_supports_texture_buffer)
|
||||||
{
|
{
|
||||||
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
||||||
shadergen.GenerateVRAMWriteFragmentShader(), [this](GL::Program& prog) {
|
shadergen.GenerateVRAMWriteFragmentShader(),
|
||||||
if (!m_is_gles)
|
[this, use_binding_layout](GL::Program& prog) {
|
||||||
|
if (!m_is_gles && !use_binding_layout)
|
||||||
prog.BindFragData(0, "o_col0");
|
prog.BindFragData(0, "o_col0");
|
||||||
});
|
});
|
||||||
if (!prog)
|
if (!prog)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prog->BindUniformBlock("UBOBlock", 1);
|
if (!use_binding_layout)
|
||||||
prog->Bind();
|
{
|
||||||
prog->Uniform1i("samp0", 0);
|
prog->BindUniformBlock("UBOBlock", 1);
|
||||||
|
prog->Bind();
|
||||||
|
prog->Uniform1i("samp0", 0);
|
||||||
|
}
|
||||||
m_vram_write_program = std::move(*prog);
|
m_vram_write_program = std::move(*prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,19 @@ GPU_HW_ShaderGen::GPU_HW_ShaderGen(HostDisplay::RenderAPI render_api, u32 resolu
|
||||||
SetGLSLVersionString();
|
SetGLSLVersionString();
|
||||||
|
|
||||||
m_use_glsl_interface_blocks = (GLAD_GL_ES_VERSION_3_2 || GLAD_GL_VERSION_3_2);
|
m_use_glsl_interface_blocks = (GLAD_GL_ES_VERSION_3_2 || GLAD_GL_VERSION_3_2);
|
||||||
|
m_use_glsl_binding_layout = UseGLSLBindingLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU_HW_ShaderGen::~GPU_HW_ShaderGen() = default;
|
GPU_HW_ShaderGen::~GPU_HW_ShaderGen() = default;
|
||||||
|
|
||||||
|
bool GPU_HW_ShaderGen::UseGLSLBindingLayout()
|
||||||
|
{
|
||||||
|
return (GLAD_GL_ES_VERSION_3_1 || GLAD_GL_VERSION_4_2 ||
|
||||||
|
(GLAD_GL_ARB_explicit_attrib_location && GLAD_GL_ARB_explicit_uniform_location &&
|
||||||
|
GLAD_GL_ARB_shading_language_420pack));
|
||||||
|
}
|
||||||
|
|
||||||
static void DefineMacro(std::stringstream& ss, const char* name, bool enabled)
|
static void DefineMacro(std::stringstream& ss, const char* name, bool enabled)
|
||||||
{
|
{
|
||||||
ss << "#define " << name << " " << BoolToUInt32(enabled) << "\n";
|
ss << "#define " << name << " " << BoolToUInt32(enabled) << "\n";
|
||||||
|
@ -41,13 +49,13 @@ void GPU_HW_ShaderGen::SetGLSLVersionString()
|
||||||
int major_version = 0, minor_version = 0;
|
int major_version = 0, minor_version = 0;
|
||||||
if (std::sscanf(glsl_version_start, "%d.%d", &major_version, &minor_version) == 2)
|
if (std::sscanf(glsl_version_start, "%d.%d", &major_version, &minor_version) == 2)
|
||||||
{
|
{
|
||||||
// Cap at GLSL 3.3, we're not using anything newer for now.
|
// Cap at GLSL 4.3, we're not using anything newer for now.
|
||||||
if (!glsl_es && major_version >= 4)
|
if (!glsl_es && (major_version > 4 || (major_version == 4 && minor_version > 3)))
|
||||||
{
|
{
|
||||||
major_version = 3;
|
major_version = 4;
|
||||||
minor_version = 30;
|
minor_version = 30;
|
||||||
}
|
}
|
||||||
else if (glsl_es && (major_version > 3 || minor_version > 20))
|
else if (glsl_es && (major_version > 3 || (major_version == 3 && minor_version > 20)))
|
||||||
{
|
{
|
||||||
major_version = 3;
|
major_version = 3;
|
||||||
minor_version = 20;
|
minor_version = 20;
|
||||||
|
@ -75,6 +83,24 @@ void GPU_HW_ShaderGen::WriteHeader(std::stringstream& ss)
|
||||||
if (m_render_api == HostDisplay::RenderAPI::OpenGL || m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
if (m_render_api == HostDisplay::RenderAPI::OpenGL || m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||||
ss << m_glsl_version_string << "\n\n";
|
ss << m_glsl_version_string << "\n\n";
|
||||||
|
|
||||||
|
// Extension enabling for OpenGL.
|
||||||
|
if (m_render_api == HostDisplay::RenderAPI::OpenGLES)
|
||||||
|
{
|
||||||
|
// Enable EXT_blend_func_extended for dual-source blend on OpenGL ES.
|
||||||
|
if (GLAD_GL_EXT_blend_func_extended)
|
||||||
|
ss << "#extension GL_EXT_blend_func_extended : require\n";
|
||||||
|
}
|
||||||
|
else if (m_render_api == HostDisplay::RenderAPI::OpenGL)
|
||||||
|
{
|
||||||
|
// Need extensions for binding layout if GL<4.3.
|
||||||
|
if (m_use_glsl_binding_layout && !GLAD_GL_VERSION_4_3)
|
||||||
|
{
|
||||||
|
ss << "#extension GL_ARB_explicit_attrib_location : require\n";
|
||||||
|
ss << "#extension GL_ARB_explicit_uniform_location : require\n";
|
||||||
|
ss << "#extension GL_ARB_shading_language_420pack : require\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DefineMacro(ss, "API_OPENGL", m_render_api == HostDisplay::RenderAPI::OpenGL);
|
DefineMacro(ss, "API_OPENGL", m_render_api == HostDisplay::RenderAPI::OpenGL);
|
||||||
DefineMacro(ss, "API_OPENGL_ES", m_render_api == HostDisplay::RenderAPI::OpenGLES);
|
DefineMacro(ss, "API_OPENGL_ES", m_render_api == HostDisplay::RenderAPI::OpenGLES);
|
||||||
DefineMacro(ss, "API_D3D11", m_render_api == HostDisplay::RenderAPI::D3D11);
|
DefineMacro(ss, "API_D3D11", m_render_api == HostDisplay::RenderAPI::D3D11);
|
||||||
|
@ -185,9 +211,16 @@ float4 RGBA5551ToRGBA8(uint v)
|
||||||
void GPU_HW_ShaderGen::DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members)
|
void GPU_HW_ShaderGen::DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members)
|
||||||
{
|
{
|
||||||
if (m_glsl)
|
if (m_glsl)
|
||||||
ss << "layout(std140) uniform UBOBlock\n";
|
{
|
||||||
|
if (m_use_glsl_binding_layout)
|
||||||
|
ss << "layout(std140, binding = 1) uniform UBOBlock\n";
|
||||||
|
else
|
||||||
|
ss << "layout(std140) uniform UBOBlock\n";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
ss << "cbuffer UBOBlock : register(b0)\n";
|
ss << "cbuffer UBOBlock : register(b0)\n";
|
||||||
|
}
|
||||||
|
|
||||||
ss << "{\n";
|
ss << "{\n";
|
||||||
for (const char* member : members)
|
for (const char* member : members)
|
||||||
|
@ -199,6 +232,9 @@ void GPU_HW_ShaderGen::DeclareTexture(std::stringstream& ss, const char* name, u
|
||||||
{
|
{
|
||||||
if (m_glsl)
|
if (m_glsl)
|
||||||
{
|
{
|
||||||
|
if (m_use_glsl_binding_layout)
|
||||||
|
ss << "layout(binding = " << index << ") ";
|
||||||
|
|
||||||
ss << "uniform sampler2D " << name << ";\n";
|
ss << "uniform sampler2D " << name << ";\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -213,6 +249,9 @@ void GPU_HW_ShaderGen::DeclareTextureBuffer(std::stringstream& ss, const char* n
|
||||||
{
|
{
|
||||||
if (m_glsl)
|
if (m_glsl)
|
||||||
{
|
{
|
||||||
|
if (m_use_glsl_binding_layout)
|
||||||
|
ss << "layout(binding = " << index << ") ";
|
||||||
|
|
||||||
ss << "uniform " << (is_int ? (is_unsigned ? "u" : "i") : "") << "samplerBuffer " << name << ";\n";
|
ss << "uniform " << (is_int ? (is_unsigned ? "u" : "i") : "") << "samplerBuffer " << name << ";\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -229,8 +268,20 @@ void GPU_HW_ShaderGen::DeclareVertexEntryPoint(
|
||||||
{
|
{
|
||||||
if (m_glsl)
|
if (m_glsl)
|
||||||
{
|
{
|
||||||
for (const char* attribute : attributes)
|
if (m_use_glsl_binding_layout && 0)
|
||||||
ss << "in " << attribute << ";\n";
|
{
|
||||||
|
u32 attribute_counter = 0;
|
||||||
|
for (const char* attribute : attributes)
|
||||||
|
{
|
||||||
|
ss << "layout(location = " << attribute_counter << ") " << attribute << ";\n";
|
||||||
|
attribute_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const char* attribute : attributes)
|
||||||
|
ss << "in " << attribute << ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (m_use_glsl_interface_blocks)
|
if (m_use_glsl_interface_blocks)
|
||||||
{
|
{
|
||||||
|
@ -330,9 +381,24 @@ void GPU_HW_ShaderGen::DeclareFragmentEntryPoint(
|
||||||
if (declare_fragcoord)
|
if (declare_fragcoord)
|
||||||
ss << "#define v_pos gl_FragCoord\n";
|
ss << "#define v_pos gl_FragCoord\n";
|
||||||
|
|
||||||
ss << "out float4 o_col0;\n";
|
if (m_use_glsl_binding_layout)
|
||||||
if (dual_color_output)
|
{
|
||||||
ss << "out float4 o_col1;\n";
|
if (dual_color_output)
|
||||||
|
{
|
||||||
|
ss << "layout(location = 0, index = 0) out float4 o_col0;\n";
|
||||||
|
ss << "layout(location = 0, index = 1) out float4 o_col1;\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "layout(location = 0) out float4 o_col0;\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "out float4 o_col0;\n";
|
||||||
|
if (dual_color_output)
|
||||||
|
ss << "out float4 o_col1;\n";
|
||||||
|
}
|
||||||
|
|
||||||
ss << "\n";
|
ss << "\n";
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ public:
|
||||||
bool texture_filtering, bool supports_dual_source_blend);
|
bool texture_filtering, bool supports_dual_source_blend);
|
||||||
~GPU_HW_ShaderGen();
|
~GPU_HW_ShaderGen();
|
||||||
|
|
||||||
|
static bool UseGLSLBindingLayout();
|
||||||
|
|
||||||
std::string GenerateBatchVertexShader(bool textured);
|
std::string GenerateBatchVertexShader(bool textured);
|
||||||
std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode transparency, GPU::TextureMode texture_mode,
|
std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode transparency, GPU::TextureMode texture_mode,
|
||||||
bool dithering, bool interlacing);
|
bool dithering, bool interlacing);
|
||||||
|
@ -24,17 +26,6 @@ public:
|
||||||
std::string GenerateVRAMWriteFragmentShader();
|
std::string GenerateVRAMWriteFragmentShader();
|
||||||
std::string GenerateVRAMCopyFragmentShader();
|
std::string GenerateVRAMCopyFragmentShader();
|
||||||
|
|
||||||
HostDisplay::RenderAPI m_render_api;
|
|
||||||
u32 m_resolution_scale;
|
|
||||||
bool m_true_color;
|
|
||||||
bool m_scaled_dithering;
|
|
||||||
bool m_texture_filering;
|
|
||||||
bool m_glsl;
|
|
||||||
bool m_supports_dual_source_blend;
|
|
||||||
bool m_use_glsl_interface_blocks;
|
|
||||||
|
|
||||||
std::string m_glsl_version_string;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetGLSLVersionString();
|
void SetGLSLVersionString();
|
||||||
void WriteHeader(std::stringstream& ss);
|
void WriteHeader(std::stringstream& ss);
|
||||||
|
@ -51,4 +42,16 @@ private:
|
||||||
|
|
||||||
void WriteCommonFunctions(std::stringstream& ss);
|
void WriteCommonFunctions(std::stringstream& ss);
|
||||||
void WriteBatchUniformBuffer(std::stringstream& ss);
|
void WriteBatchUniformBuffer(std::stringstream& ss);
|
||||||
|
|
||||||
|
HostDisplay::RenderAPI m_render_api;
|
||||||
|
u32 m_resolution_scale;
|
||||||
|
bool m_true_color;
|
||||||
|
bool m_scaled_dithering;
|
||||||
|
bool m_texture_filering;
|
||||||
|
bool m_glsl;
|
||||||
|
bool m_supports_dual_source_blend;
|
||||||
|
bool m_use_glsl_interface_blocks;
|
||||||
|
bool m_use_glsl_binding_layout;
|
||||||
|
|
||||||
|
std::string m_glsl_version_string;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue