mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-09 01:29:23 +00:00
gl: Autodetect supported OpenGL extensions
cleanup
This commit is contained in:
parent
ea098a920e
commit
ac3b22902a
7 changed files with 145 additions and 61 deletions
|
@ -518,19 +518,37 @@ void GLGSRender::on_init_thread()
|
||||||
GSRender::on_init_thread();
|
GSRender::on_init_thread();
|
||||||
|
|
||||||
gl::init();
|
gl::init();
|
||||||
|
|
||||||
if (g_cfg_rsx_debug_output)
|
if (g_cfg_rsx_debug_output)
|
||||||
gl::enable_debugging();
|
gl::enable_debugging();
|
||||||
|
|
||||||
LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_VERSION));
|
LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_VERSION));
|
||||||
LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
|
LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_VENDOR));
|
LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_VENDOR));
|
||||||
|
|
||||||
|
auto gl_caps = gl::get_driver_caps();
|
||||||
|
|
||||||
|
if (!gl_caps.ARB_texture_buffer_supported)
|
||||||
|
{
|
||||||
|
fmt::throw_exception("Failed to initialize OpenGL renderer. ARB_texture_buffer_object is required but not supported by your GPU");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gl_caps.ARB_dsa_supported && !gl_caps.EXT_dsa_supported)
|
||||||
|
{
|
||||||
|
fmt::throw_exception("Failed to initialize OpenGL renderer. ARB_direct_state_access or EXT_direct_state_access is required but not supported by your GPU");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Use industry standard resource alignment values as defaults
|
||||||
|
m_uniform_buffer_offset_align = 256;
|
||||||
|
m_min_texbuffer_alignment = 256;
|
||||||
|
|
||||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &m_uniform_buffer_offset_align);
|
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &m_uniform_buffer_offset_align);
|
||||||
glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &m_min_texbuffer_alignment);
|
glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &m_min_texbuffer_alignment);
|
||||||
m_vao.create();
|
m_vao.create();
|
||||||
|
|
||||||
const u32 texture_index_offset =
|
const u32 texture_index_offset = rsx::limits::fragment_textures_count + rsx::limits::vertex_textures_count;
|
||||||
rsx::limits::fragment_textures_count + rsx::limits::vertex_textures_count;
|
|
||||||
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||||
{
|
{
|
||||||
auto &tex = m_gl_attrib_buffers[index];
|
auto &tex = m_gl_attrib_buffers[index];
|
||||||
|
@ -541,6 +559,12 @@ void GLGSRender::on_init_thread()
|
||||||
tex.bind();
|
tex.bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gl_caps.ARB_buffer_storage_supported)
|
||||||
|
{
|
||||||
|
LOG_WARNING(RSX, "Forcing use of legacy OpenGL buffers because ARB_buffer_storage is not supported");
|
||||||
|
g_cfg_rsx_gl_legacy_buffers = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_cfg_rsx_gl_legacy_buffers)
|
if (g_cfg_rsx_gl_legacy_buffers)
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "Using legacy openGL buffers.");
|
LOG_WARNING(RSX, "Using legacy openGL buffers.");
|
||||||
|
@ -570,7 +594,13 @@ void GLGSRender::on_init_thread()
|
||||||
m_vao.element_array_buffer = *m_index_ring_buffer;
|
m_vao.element_array_buffer = *m_index_ring_buffer;
|
||||||
|
|
||||||
if (g_cfg_rsx_overlay)
|
if (g_cfg_rsx_overlay)
|
||||||
m_text_printer.init();
|
{
|
||||||
|
if (gl_caps.ARB_shader_draw_parameters_supported)
|
||||||
|
{
|
||||||
|
m_text_printer.init();
|
||||||
|
m_text_printer.set_enabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
namespace gl
|
namespace gl
|
||||||
{
|
{
|
||||||
|
capabilities g_driver_caps;
|
||||||
const fbo screen{};
|
const fbo screen{};
|
||||||
|
|
||||||
GLenum draw_mode(rsx::primitive_type in)
|
GLenum draw_mode(rsx::primitive_type in)
|
||||||
|
@ -49,6 +50,14 @@ namespace gl
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
capabilities &get_driver_caps()
|
||||||
|
{
|
||||||
|
if (!g_driver_caps.initialized)
|
||||||
|
g_driver_caps.initialize();
|
||||||
|
|
||||||
|
return g_driver_caps;
|
||||||
|
}
|
||||||
|
|
||||||
void fbo::create()
|
void fbo::create()
|
||||||
{
|
{
|
||||||
glGenFramebuffers(1, &m_id);
|
glGenFramebuffers(1, &m_id);
|
||||||
|
|
|
@ -53,7 +53,10 @@ namespace gl
|
||||||
#define __glcheck
|
#define __glcheck
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class capabilities;
|
||||||
|
|
||||||
void enable_debugging();
|
void enable_debugging();
|
||||||
|
capabilities& get_driver_caps();
|
||||||
|
|
||||||
class exception : public std::exception
|
class exception : public std::exception
|
||||||
{
|
{
|
||||||
|
@ -67,6 +70,69 @@ namespace gl
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class capabilities
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool EXT_dsa_supported = false;
|
||||||
|
bool ARB_dsa_supported = false;
|
||||||
|
bool ARB_buffer_storage_supported = false;
|
||||||
|
bool ARB_texture_buffer_supported = false;
|
||||||
|
bool ARB_shader_draw_parameters_supported = false;
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
|
void initialize()
|
||||||
|
{
|
||||||
|
int find_count = 5;
|
||||||
|
int ext_count = 0;
|
||||||
|
glGetIntegerv(GL_NUM_EXTENSIONS, &ext_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < ext_count; i++)
|
||||||
|
{
|
||||||
|
if (!find_count) break;
|
||||||
|
|
||||||
|
const char *ext = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
||||||
|
const auto ext_name = std::string(ext);
|
||||||
|
|
||||||
|
if (ext_name == "GL_ARB_shader_draw_parameters")
|
||||||
|
{
|
||||||
|
ARB_shader_draw_parameters_supported = true;
|
||||||
|
find_count --;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext_name == "GL_EXT_direct_state_access")
|
||||||
|
{
|
||||||
|
EXT_dsa_supported = true;
|
||||||
|
find_count --;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext_name == "GL_ARB_direct_state_access")
|
||||||
|
{
|
||||||
|
ARB_dsa_supported = true;
|
||||||
|
find_count --;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext_name == "GL_ARB_buffer_storage")
|
||||||
|
{
|
||||||
|
ARB_buffer_storage_supported = true;
|
||||||
|
find_count --;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext_name == "GL_ARB_texture_buffer_object")
|
||||||
|
{
|
||||||
|
ARB_texture_buffer_supported = true;
|
||||||
|
find_count --;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class fence
|
class fence
|
||||||
{
|
{
|
||||||
GLsync m_value = nullptr;
|
GLsync m_value = nullptr;
|
||||||
|
@ -1453,22 +1519,12 @@ namespace gl
|
||||||
if (get_target() != target::textureBuffer)
|
if (get_target() != target::textureBuffer)
|
||||||
fmt::throw_exception("OpenGL error: texture cannot copy from buffer" HERE);
|
fmt::throw_exception("OpenGL error: texture cannot copy from buffer" HERE);
|
||||||
|
|
||||||
/* if (!offset)
|
auto caps = get_driver_caps();
|
||||||
{
|
|
||||||
copy_from(buf, gl_format_type);
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (glTextureBufferRangeEXT == nullptr)
|
if (caps.EXT_dsa_supported)
|
||||||
fmt::throw_exception("OpenGL error: partial buffer access for textures is unsupported on your system" HERE);
|
__glcheck glTextureBufferRangeEXT(id(), (GLenum)target::textureBuffer, gl_format_type, buf.id(), offset, length);
|
||||||
|
else
|
||||||
__glcheck glTextureBufferRangeEXT(id(), (GLenum)target::textureBuffer, gl_format_type, buf.id(), offset, length);
|
__glcheck glTextureBufferRange(id(), gl_format_type, buf.id(), offset, length);
|
||||||
}
|
|
||||||
|
|
||||||
void copy_from(buffer &buf, u32 gl_format_type)
|
|
||||||
{
|
|
||||||
save_binding_state save(*this);
|
|
||||||
__glcheck glTexBuffer((GLenum)target::textureBuffer, gl_format_type, buf.id());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_from(const buffer& buf, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings)
|
void copy_from(const buffer& buf, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings)
|
||||||
|
|
|
@ -171,6 +171,7 @@ OPENGL_PROC(PFNGLBINDBUFFERBASEPROC, BindBufferBase);
|
||||||
OPENGL_PROC(PFNGLMULTIDRAWARRAYSPROC, MultiDrawArrays);
|
OPENGL_PROC(PFNGLMULTIDRAWARRAYSPROC, MultiDrawArrays);
|
||||||
|
|
||||||
OPENGL_PROC(PFNGLGETTEXTUREIMAGEEXTPROC, GetTextureImageEXT);
|
OPENGL_PROC(PFNGLGETTEXTUREIMAGEEXTPROC, GetTextureImageEXT);
|
||||||
|
OPENGL_PROC(PFNGLGETTEXTUREIMAGEPROC, GetTextureImage);
|
||||||
|
|
||||||
//Sampler Objects
|
//Sampler Objects
|
||||||
OPENGL_PROC(PFNGLGENSAMPLERSPROC, GenSamplers);
|
OPENGL_PROC(PFNGLGENSAMPLERSPROC, GenSamplers);
|
||||||
|
@ -180,8 +181,8 @@ OPENGL_PROC(PFNGLSAMPLERPARAMETERIPROC, SamplerParameteri);
|
||||||
OPENGL_PROC(PFNGLSAMPLERPARAMETERFVPROC, SamplerParameterfv);
|
OPENGL_PROC(PFNGLSAMPLERPARAMETERFVPROC, SamplerParameterfv);
|
||||||
|
|
||||||
//Texture Buffers
|
//Texture Buffers
|
||||||
OPENGL_PROC(PFNGLTEXBUFFERPROC, TexBuffer);
|
|
||||||
OPENGL_PROC(PFNGLTEXTUREBUFFERRANGEEXTPROC, TextureBufferRangeEXT);
|
OPENGL_PROC(PFNGLTEXTUREBUFFERRANGEEXTPROC, TextureBufferRangeEXT);
|
||||||
|
OPENGL_PROC(PFNGLTEXTUREBUFFERRANGEPROC, TextureBufferRange);
|
||||||
|
|
||||||
//ARB_Copy_Image
|
//ARB_Copy_Image
|
||||||
OPENGL_PROC(PFNGLCOPYIMAGESUBDATAPROC, CopyImageSubData);
|
OPENGL_PROC(PFNGLCOPYIMAGESUBDATAPROC, CopyImageSubData);
|
||||||
|
|
|
@ -85,28 +85,6 @@ namespace gl
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
//Check for ARB_shader_draw_parameters
|
|
||||||
//While it is possible to draw text without full multidraw support, issuing separate draw calls per character is not effecient
|
|
||||||
|
|
||||||
int ext_count;
|
|
||||||
glGetIntegerv(GL_NUM_EXTENSIONS, &ext_count);
|
|
||||||
|
|
||||||
for (int i = 0; i < ext_count; i++)
|
|
||||||
{
|
|
||||||
const char *ext = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
|
||||||
if (std::string(ext) == "GL_ARB_shader_draw_parameters")
|
|
||||||
{
|
|
||||||
enabled = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!enabled)
|
|
||||||
{
|
|
||||||
LOG_ERROR(RSX, "Debug overlay could not start because ARB_shader_draw_parameters is not supported by your GPU");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_text_buffer.create();
|
m_text_buffer.create();
|
||||||
m_scale_offsets_buffer.create();
|
m_scale_offsets_buffer.create();
|
||||||
|
|
||||||
|
@ -138,6 +116,11 @@ namespace gl
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_enabled(bool state)
|
||||||
|
{
|
||||||
|
enabled = state;
|
||||||
|
}
|
||||||
|
|
||||||
void print_text(int x, int y, int target_w, int target_h, const std::string &text, color4f color = { 0.3f, 1.f, 0.3f, 1.f })
|
void print_text(int x, int y, int target_w, int target_h, const std::string &text, color4f color = { 0.3f, 1.f, 0.3f, 1.f })
|
||||||
{
|
{
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
|
|
|
@ -278,7 +278,12 @@ namespace gl
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_SWAP_BYTES, pack_unpack_swap_bytes);
|
glPixelStorei(GL_PACK_SWAP_BYTES, pack_unpack_swap_bytes);
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
|
||||||
glGetTextureImageEXT(vram_texture, GL_TEXTURE_2D, 0, (GLenum)format, (GLenum)type, nullptr);
|
|
||||||
|
if (get_driver_caps().EXT_dsa_supported)
|
||||||
|
glGetTextureImageEXT(vram_texture, GL_TEXTURE_2D, 0, (GLenum)format, (GLenum)type, nullptr);
|
||||||
|
else
|
||||||
|
glGetTextureImage(vram_texture, 0, (GLenum)format, (GLenum)type, pbo_size, nullptr);
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
|
|
||||||
m_fence.reset();
|
m_fence.reset();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue