[vid] Allow render systems to unload late

This cleans up the tangled mess of attempting to unload the gl driver in
X11: for whatever reason, the display gets tied in to the library.
This commit is contained in:
Bill Currie 2023-03-06 21:15:15 +09:00
parent 5821ef8d1f
commit f12b3ea134
19 changed files with 85 additions and 64 deletions

View file

@ -57,13 +57,14 @@ void Win_UpdateWindowStatus (int x, int y);
void Win_SetCaption (const char *text);
qboolean Win_SetGamma (double gamma);
struct gl_ctx_s *Win_GL_Context (void);
struct vid_internal_s;
struct gl_ctx_s *Win_GL_Context (struct vid_internal_s *);
void Win_GL_Init_Cvars (void);
struct sw_ctx_s *Win_SW_Context (void);
struct sw_ctx_s *Win_SW_Context (struct vid_internal_s *);
void Win_SW_Init_Cvars (void);
struct vulkan_ctx_s *Win_Vulkan_Context (void);
struct vulkan_ctx_s *Win_Vulkan_Context (struct vid_internal_s *);
void Win_Vulkan_Init_Cvars (void);
void IN_UpdateClipCursor (void);

View file

@ -80,13 +80,14 @@ void X11_SaveMouseAcceleration (void);
void X11_RemoveMouseAcceleration (void);
void X11_RestoreMouseAcceleration (void);
struct gl_ctx_s *X11_GL_Context (void);
struct vid_internal_s;
struct gl_ctx_s *X11_GL_Context (struct vid_internal_s *);
void X11_GL_Init_Cvars (void);
struct sw_ctx_s *X11_SW_Context (void);
struct sw_ctx_s *X11_SW_Context (struct vid_internal_s *);
void X11_SW_Init_Cvars (void);
struct vulkan_ctx_s *X11_Vulkan_Context (void);
struct vulkan_ctx_s *X11_Vulkan_Context (struct vid_internal_s *);
void X11_Vulkan_Init_Cvars (void);
#endif // __context_x11_h_

View file

@ -8,8 +8,7 @@ typedef struct GL_context *GL_context;
typedef struct gl_ctx_s {
GL_context context;
void (*load_gl) (void);
void (*unload_gl) (struct gl_ctx_s *ctx);
void (*load_gl) (struct gl_ctx_s *ctx);
void (*choose_visual) (struct gl_ctx_s *ctx);
void (*create_context) (struct gl_ctx_s *ctx, int core);
void (*init_gl) (void);

View file

@ -15,19 +15,21 @@ typedef struct vid_system_s {
extern vid_system_t vid_system;
typedef struct vid_internal_s {
void (*flush_caches) (void *data);
void (*init_buffers) (void *data);
void (*set_palette) (void *data, const byte *palette);
void (*set_colormap) (void *data, const byte *colormap);
void (*flush_caches) (void *ctx);
void (*init_buffers) (void *ctx);
void (*set_palette) (void *ctx, const byte *palette);
void (*set_colormap) (void *ctx, const byte *colormap);
void (*choose_visual) (void *data);
void (*create_context) (void *data);
void (*choose_visual) (void *ctx);
void (*create_context) (void *ctx);
void *data;
void *ctx;
struct gl_ctx_s *(*gl_context) (void);
struct sw_ctx_s *(*sw_context) (void);
struct vulkan_ctx_s *(*vulkan_context) (void);
struct gl_ctx_s *(*gl_context) (struct vid_internal_s *);
struct sw_ctx_s *(*sw_context) (struct vid_internal_s *);
struct vulkan_ctx_s *(*vulkan_context) (struct vid_internal_s *);
void (*unload) (void *data);
} vid_internal_t;
extern int vid_fullscreen;

View file

@ -55,12 +55,12 @@ d_vidsize_listener (void *data, const viddef_t *vid)
int cachesize = D_SurfaceCacheForRes (vid->width, vid->height);
if (surfcache) {
D_FlushCaches (vid->vid_internal->data);
D_FlushCaches (vid->vid_internal->ctx);
free (surfcache);
surfcache = 0;
}
surfcache = calloc (cachesize, 1);
vid->vid_internal->init_buffers (vid->vid_internal->data);
vid->vid_internal->init_buffers (vid->vid_internal->ctx);
D_InitCaches (surfcache, cachesize);
viddef.recalc_refdef = 1;

View file

@ -1019,7 +1019,7 @@ Draw_BlendScreen (quat_t color)
newpal[2] = vid.gammatable[b];
newpal += 3;
}
vid.vid_internal->set_palette (vid.vid_internal->data, pal);
vid.vid_internal->set_palette (vid.vid_internal->ctx, pal);
}
int

View file

@ -183,17 +183,17 @@ static vid_model_funcs_t model_funcs = {
static void
gl_vid_render_init (void)
{
if (!vr_data.vid->vid_internal->sw_context) {
if (!vr_data.vid->vid_internal->gl_context) {
Sys_Error ("Sorry, OpenGL not supported by this program.");
}
gl_ctx = vr_data.vid->vid_internal->gl_context ();
vid_internal_t *vi = vr_data.vid->vid_internal;
gl_ctx = vi->gl_context (vi);
gl_ctx->init_gl = GL_Init_Common;
gl_ctx->load_gl ();
gl_ctx->load_gl (gl_ctx);
vr_data.vid->vid_internal->data = gl_ctx;
vr_data.vid->vid_internal->set_palette = GL_SetPalette;
vr_data.vid->vid_internal->choose_visual = gl_vid_render_choose_visual;
vr_data.vid->vid_internal->create_context = gl_vid_render_create_context;
vi->set_palette = GL_SetPalette;
vi->choose_visual = gl_vid_render_choose_visual;
vi->create_context = gl_vid_render_create_context;
vr_funcs = &gl_vid_render_funcs;
m_funcs = &model_funcs;

View file

@ -94,17 +94,17 @@ static vid_model_funcs_t model_funcs = {
static void
glsl_vid_render_init (void)
{
if (!vr_data.vid->vid_internal->sw_context) {
if (!vr_data.vid->vid_internal->gl_context) {
Sys_Error ("Sorry, OpenGL (GLSL) not supported by this program.");
}
glsl_ctx = vr_data.vid->vid_internal->gl_context ();
vid_internal_t *vi = vr_data.vid->vid_internal;
glsl_ctx = vi->gl_context (vi);
glsl_ctx->init_gl = GLSL_Init_Common;
glsl_ctx->load_gl ();
glsl_ctx->load_gl (glsl_ctx);
vr_data.vid->vid_internal->data = glsl_ctx;
vr_data.vid->vid_internal->set_palette = GLSL_SetPalette;
vr_data.vid->vid_internal->choose_visual = glsl_vid_render_choose_visual;
vr_data.vid->vid_internal->create_context = glsl_vid_render_create_context;
vi->set_palette = GLSL_SetPalette;
vi->choose_visual = glsl_vid_render_choose_visual;
vi->create_context = glsl_vid_render_create_context;
vr_funcs = &glsl_vid_render_funcs;
m_funcs = &model_funcs;
}
@ -114,8 +114,6 @@ glsl_vid_render_shutdown (void)
{
glsl_R_Shutdown ();
GLSL_Shutdown_Common ();
glsl_ctx->unload_gl (glsl_ctx);
}
static unsigned int GLErr_InvalidEnum;

View file

@ -106,9 +106,8 @@ sw_vid_render_init (void)
if (!vr_data.vid->vid_internal->sw_context) {
Sys_Error ("Sorry, software rendering not supported by this program.");
}
sw_ctx = vr_data.vid->vid_internal->sw_context ();
sw_ctx = vr_data.vid->vid_internal->sw_context (vr_data.vid->vid_internal);
vr_data.vid->vid_internal->data = sw_ctx;
vr_data.vid->vid_internal->set_palette = sw_vid_render_set_palette;
vr_data.vid->vid_internal->set_colormap = sw_vid_render_set_colormap;
vr_data.vid->vid_internal->choose_visual = sw_vid_render_choose_visual;

View file

@ -699,15 +699,15 @@ vulkan_vid_render_init (void)
if (!vr_data.vid->vid_internal->vulkan_context) {
Sys_Error ("Sorry, Vulkan not supported by this program.");
}
vulkan_ctx = vr_data.vid->vid_internal->vulkan_context ();
vid_internal_t *vi = vr_data.vid->vid_internal;
vulkan_ctx = vi->vulkan_context (vi);
vulkan_ctx->load_vulkan (vulkan_ctx);
Vulkan_Init_Common (vulkan_ctx);
vr_data.vid->vid_internal->data = vulkan_ctx;
vr_data.vid->vid_internal->set_palette = set_palette;
vr_data.vid->vid_internal->choose_visual = vulkan_vid_render_choose_visual;
vr_data.vid->vid_internal->create_context = vulkan_vid_render_create_context;
vi->set_palette = set_palette;
vi->choose_visual = vulkan_vid_render_choose_visual;
vi->create_context = vulkan_vid_render_create_context;
vr_funcs = &vulkan_vid_render_funcs;
m_funcs = &model_funcs;

View file

@ -224,7 +224,7 @@ VID_UpdateGamma (void)
}
p32[-1] = 0; // color 255 is transparent
// update with the new palette
vi->set_palette (vi->data, viddef.palette);
vi->set_palette (vi->ctx, viddef.palette);
}
}
@ -276,7 +276,7 @@ void
VID_ClearMemory (void)
{
if (vi->flush_caches) {
vi->flush_caches (vi->data);
vi->flush_caches (vi->ctx);
}
}

View file

@ -123,7 +123,7 @@ Win_VID_SetPalette (byte *palette, byte *colormap)
viddef.colormap8 = colormap;
viddef.fullbright = 256 - viddef.colormap8[256 * VID_GRADES];
if (vid_internal.set_colormap) {
vid_internal.set_colormap (vid_internal.data, colormap);
vid_internal.set_colormap (vid_internal.ctx, colormap);
}
VID_InitGamma (palette);

View file

@ -177,7 +177,7 @@ wgl_end_rendering (void)
}
static void
wgl_load_gl (void)
wgl_load_gl (gl_ctx_t *ctx)
{
libgl_handle = LoadLibrary (gl_driver);
if (!libgl_handle) {
@ -198,7 +198,7 @@ wgl_load_gl (void)
}
gl_ctx_t *
Win_GL_Context (void)
Win_GL_Context (vid_internal_t *vi)
{
gl_ctx_t *ctx = calloc (1, sizeof (gl_ctx_t));
ctx->load_gl = wgl_load_gl;
@ -206,6 +206,8 @@ Win_GL_Context (void)
ctx->create_context = wgl_create_context;
ctx->get_proc_address = QFGL_ProcAddress;
ctx->end_rendering = wgl_end_rendering;
vi->ctx = ctx;
return ctx;
}

View file

@ -233,7 +233,7 @@ VID_CreateGDIDriver (int width, int height, const byte *palette, byte **buffer,
// create a palette
VID_InitGamma (palette);
viddef.vid_internal->set_palette (viddef.vid_internal->data, palette);
viddef.vid_internal->set_palette (viddef.vid_internal->ctx, palette);
}
void
@ -478,13 +478,15 @@ win_create_context (sw_ctx_t *ctx)
}
sw_ctx_t *
Win_SW_Context (void)
Win_SW_Context (vid_internal_t *vi)
{
sw_ctx_t *ctx = calloc (1, sizeof (sw_ctx_t));
ctx->set_palette = win_set_palette;
ctx->choose_visual = win_choose_visual;
ctx->create_context = win_create_context;
ctx->update = win_sw_update;
vi->ctx = ctx;
return ctx;
}

View file

@ -174,7 +174,7 @@ win_vulkan_create_surface (vulkan_ctx_t *ctx)
}
vulkan_ctx_t *
Win_Vulkan_Context (void)
Win_Vulkan_Context (vid_internal_t *vi)
{
vulkan_ctx_t *ctx = calloc (1, sizeof (vulkan_ctx_t));
ctx->load_vulkan = load_vulkan_library;
@ -186,6 +186,8 @@ Win_Vulkan_Context (void)
ctx->required_extensions = required_extensions;
ctx->va_ctx = va_create_context (4);
ctx->twod_scale = 1;
vi->ctx = ctx;
return ctx;
}

View file

@ -86,6 +86,9 @@ X11_VID_Shutdown (void)
{
Sys_MaskPrintf (SYS_vid, "X11_VID_shutdown\n");
X11_CloseDisplay ();
if (vid_internal.unload) {
vid_internal.unload (vid_internal.ctx);
}
}
static void
@ -94,11 +97,11 @@ X11_VID_SetPalette (byte *palette, byte *colormap)
viddef.colormap8 = colormap;
viddef.fullbright = 256 - viddef.colormap8[256 * VID_GRADES];
if (vid_internal.set_colormap) {
vid_internal.set_colormap (vid_internal.data, colormap);
vid_internal.set_colormap (vid_internal.ctx, colormap);
}
VID_InitGamma (palette);
vid_internal.set_palette (vid_internal.data, viddef.palette);
vid_internal.set_palette (vid_internal.ctx, viddef.palette);
}
/*
@ -123,11 +126,11 @@ X11_VID_Init (byte *palette, byte *colormap)
VID_GetWindowSize (640, 480);
X11_OpenDisplay ();
vid_internal.choose_visual (vid_internal.data);
vid_internal.choose_visual (vid_internal.ctx);
X11_SetVidMode (viddef.width, viddef.height);
X11_CreateWindow (viddef.width, viddef.height);
X11_CreateNullCursor (); // hide mouse pointer
vid_internal.create_context (vid_internal.data);
vid_internal.create_context (vid_internal.ctx);
X11_VID_SetPalette (palette, colormap);

View file

@ -103,6 +103,7 @@ static GLXContext (*qfglXCreateContextAttribsARB) (Display *dpy,
GLXContext ctx,
Bool direct,
const int *attribs);
static void (*qfglXDestroyContext) ( Display *dpy, GLXContext ctx );
static GLXFBConfig *(*qfglXChooseFBConfig) (Display *dpy, int screen,
const int *attribs, int *nitems);
static XVisualInfo *(*qfglXGetVisualFromFBConfig) (Display *dpy,
@ -191,8 +192,8 @@ glx_choose_visual (gl_ctx_t *ctx)
}
Sys_MaskPrintf (SYS_vid, "Found %d matching FB configs.\n", fbcount);
glx_cfg = fbc[0];
XFree (fbc);
x_visinfo = qfglXGetVisualFromFBConfig (x_disp, glx_cfg);
XFree (fbc);
if (!x_visinfo) {
Sys_Error ("Error couldn't get an RGB, Double-buffered, Depth visual");
}
@ -225,7 +226,7 @@ glx_end_rendering (void)
}
static void
glx_load_gl (void)
glx_load_gl (gl_ctx_t *ctx)
{
libgl_handle = dlopen (gl_driver, RTLD_NOW);
if (!libgl_handle) {
@ -241,6 +242,7 @@ glx_load_gl (void)
qfglXGetVisualFromFBConfig = QFGL_ProcAddress ("glXGetVisualFromFBConfig", true);
qfglXGetFBConfigAttrib = QFGL_ProcAddress ("glXGetFBConfigAttrib", true);
qfglXCreateContextAttribsARB = QFGL_ProcAddress ("glXCreateContextAttribsARB", true);
qfglXDestroyContext = QFGL_ProcAddress ("glXDestroyContext", true);
qfglXMakeCurrent = QFGL_ProcAddress ("glXMakeCurrent", true);
use_gl_procaddress = 1;
@ -249,22 +251,28 @@ glx_load_gl (void)
}
static void
glx_unload_gl (gl_ctx_t *ctx)
glx_unload_gl (void *_ctx)
{
dlclose (libgl_handle);
gl_ctx_t *ctx = _ctx;
if (libgl_handle) {
dlclose (libgl_handle);
libgl_handle = 0;
}
free (ctx);
}
gl_ctx_t *
X11_GL_Context (void)
X11_GL_Context (vid_internal_t *vi)
{
gl_ctx_t *ctx = calloc (1, sizeof (gl_ctx_t));
ctx->load_gl = glx_load_gl;
ctx->unload_gl = glx_unload_gl;
ctx->choose_visual = glx_choose_visual;
ctx->create_context = glx_create_context;
ctx->get_proc_address = QFGL_ProcAddress;
ctx->end_rendering = glx_end_rendering;
vi->unload = glx_unload_gl;
vi->ctx = ctx;
return ctx;
}

View file

@ -693,13 +693,15 @@ x11_create_context (sw_ctx_t *ctx)
}
sw_ctx_t *
X11_SW_Context (void)
X11_SW_Context (vid_internal_t *vi)
{
sw_ctx_t *ctx = calloc (1, sizeof (sw_ctx_t));
ctx->set_palette = x11_set_palette;
ctx->choose_visual = x11_choose_visual;
ctx->create_context = x11_create_context;
ctx->update = x11_sw8_8_update;
vi->ctx = ctx;
return ctx;
}

View file

@ -213,7 +213,7 @@ x11_vulkan_create_surface (vulkan_ctx_t *ctx)
}
vulkan_ctx_t *
X11_Vulkan_Context (void)
X11_Vulkan_Context (vid_internal_t *vi)
{
vulkan_ctx_t *ctx = calloc (1, sizeof (vulkan_ctx_t));
ctx->load_vulkan = load_vulkan_library;
@ -225,6 +225,8 @@ X11_Vulkan_Context (void)
ctx->required_extensions = required_extensions;
ctx->va_ctx = va_create_context (32);
ctx->twod_scale = 1;
vi->ctx = ctx;
return ctx;
}