render/opengl/linux/egl: pick config in init; pass to context; bind pbuffer

This commit is contained in:
Малов Андрей Владимирович
2026-06-09 16:02:28 -07:00
committed by Ryan Fleury
parent eee1a64d14
commit d64912be7e
2 changed files with 73 additions and 58 deletions
@@ -51,7 +51,63 @@ r_ogl_os_init(CmdLine *cmdln)
wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't initialize EGL API to OpenGL.")); wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't initialize EGL API to OpenGL."));
abort_self(1); abort_self(1);
} }
//- choose EGL config, extract matching X11 visual/colormap, publish to os layer
{
EGLint config_filter[] =
{
EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT,
EGL_CONFORMANT, EGL_OPENGL_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8,
EGL_NONE,
};
EGLConfig configs[256] = {0};
EGLint configs_count = 0;
if(!eglChooseConfig(r_ogl_lnx_state->display, config_filter, configs, ArrayCount(configs), &configs_count) || configs_count == 0)
{
wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't choose EGL configuration."));
abort_self(1);
}
int screen = DefaultScreen(lnx_wm_state->display);
XVisualInfo vi_template = {0};
XVisualInfo *vi = 0;
int vi_count = 0;
for(EGLint idx = 0; idx < configs_count && vi == 0; idx += 1)
{
EGLint native_visual_id = 0;
if(!eglGetConfigAttrib(r_ogl_lnx_state->display, configs[idx], EGL_NATIVE_VISUAL_ID, &native_visual_id) || native_visual_id == 0)
{
continue;
}
vi_template.visualid = native_visual_id;
vi_template.screen = screen;
vi = XGetVisualInfo(lnx_wm_state->display, VisualIDMask|VisualScreenMask, &vi_template, &vi_count);
if(vi != 0 && vi_count > 0)
{
r_ogl_lnx_state->config = configs[idx];
break;
}
if(vi != 0) { XFree(vi); vi = 0; }
}
if(vi == 0 || r_ogl_lnx_state->config == 0)
{
wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't find an EGL config with a matching X11 visual."));
abort_self(1);
}
lnx_wm_state->window_visual = vi->visual;
lnx_wm_state->window_depth = vi->depth;
lnx_wm_state->window_colormap = XCreateColormap(lnx_wm_state->display,
XRootWindow(lnx_wm_state->display, vi->screen),
vi->visual, AllocNone);
XFree(vi);
}
//- rjf: construct context //- rjf: construct context
{ {
B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug"));
@@ -66,16 +122,23 @@ r_ogl_os_init(CmdLine *cmdln)
debug_mode ? EGL_CONTEXT_OPENGL_DEBUG : EGL_NONE, EGL_TRUE, debug_mode ? EGL_CONTEXT_OPENGL_DEBUG : EGL_NONE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
r_ogl_lnx_state->context = eglCreateContext(r_ogl_lnx_state->display, 0, EGL_NO_CONTEXT, options); r_ogl_lnx_state->context = eglCreateContext(r_ogl_lnx_state->display, r_ogl_lnx_state->config, EGL_NO_CONTEXT, options);
if(r_ogl_lnx_state->context == EGL_NO_CONTEXT) if(r_ogl_lnx_state->context == EGL_NO_CONTEXT)
{ {
wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't create OpenGL context with EGL.")); wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't create OpenGL context with EGL."));
abort_self(1); abort_self(1);
} }
} }
eglMakeCurrent(r_ogl_lnx_state->display, 0, 0, r_ogl_lnx_state->context); //- bind context to 1x1 pbuffer so GL calls work before any window exists
glDrawBuffer(GL_BACK); {
EGLint pbuffer_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
EGLSurface init_surface = eglCreatePbufferSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, pbuffer_attribs);
if(init_surface == EGL_NO_SURFACE || !eglMakeCurrent(r_ogl_lnx_state->display, init_surface, init_surface, r_ogl_lnx_state->context))
{
eglMakeCurrent(r_ogl_lnx_state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, r_ogl_lnx_state->context);
}
}
} }
internal R_Handle internal R_Handle
@@ -97,60 +160,11 @@ r_ogl_os_window_equip(WM_Window window)
EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB,
EGL_NONE, EGL_NONE,
}; };
if(r_ogl_lnx_state->config == 0) w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, surface_options);
if(w->surface == EGL_NO_SURFACE)
{ {
//- rjf: get all EGL configs EGLint surface_options_linear[] = { EGL_NONE };
EGLConfig configs[256] = {0}; w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, surface_options_linear);
EGLint configs_count = 0;
{
EGLint options[] =
{
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_CONFORMANT, EGL_OPENGL_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8,
EGL_NONE,
};
if(!eglChooseConfig(r_ogl_lnx_state->display, options, configs, ArrayCount(configs), &configs_count) || configs_count == 0)
{
wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't choose EGL configuration."));
abort_self(1);
}
}
//- rjf: actually choose the egl config
{
EGLint config_options[] =
{
EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB,
EGL_NONE,
};
for(U32 idx = 0; idx < configs_count; idx += 1)
{
w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, configs[idx], window_os->window, config_options);
if(w->surface != EGL_NO_SURFACE)
{
r_ogl_lnx_state->config = configs[idx];
break;
}
}
if(r_ogl_lnx_state->config == 0)
{
wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't find a suitable EGL configuration."));
abort_self(1);
}
}
}
else
{
w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, surface_options);
} }
if(w->surface == EGL_NO_SURFACE) if(w->surface == EGL_NO_SURFACE)
{ {
@@ -7,6 +7,7 @@
#define glTexImage3D glTexImage3D__static #define glTexImage3D glTexImage3D__static
#define glTexSubImage3D glTexSubImage3D__static #define glTexSubImage3D glTexSubImage3D__static
#define glActiveTexture glActiveTexture__static #define glActiveTexture glActiveTexture__static
#include <X11/Xutil.h>
#include <GL/gl.h> #include <GL/gl.h>
#include <EGL/egl.h> #include <EGL/egl.h>
#undef glTexImage3D #undef glTexImage3D