glamor: fix Option "GlxVendorLibrary"

The old code tried to use a screen pointer that was uninitialized and set to NULL.
This caused it to segfault when this option was set.

When this option was used with the modesetting driver, `glamor_egl_init`
is called indirectly in the driver PreInit proc.

`xf86ScrnToScreen(scrn)` then returns NULL.

This patch moves setting the gl vendor later in the initialization process,
when we already have a non-null pScreen.

Minimal reproducer:
```
$ cat /etc/X11/xorg.conf.d/99-screen.conf
Section "Screen"
	Identifier "Default"
	Option "GlxVendorLibrary" "Name"
EndSection
```

Backtrace:
```
| #0  in abort ()
| #1  in OsAbort () at os/utils.c:1361
| #2  in AbortServer () at os/log.c:879
| #3  FatalError () at os/log.c:1017
| #4  in OsSigHandler () at os/osinit.c:156
| #5  OsSigHandler () at os/osinit.c:110
| #6  <signal handler called>
| #7  in __pthread_kill_implementation () from /lib64/libc.so.6
| #8  in raise () from /lib64/libc.so.6
| #9  in abort () from /lib64/libc.so.6
| #10 in __assert_fail_base.cold () from /lib64/libc.so.6
| #11 in xf86ScrnToScreen () at hw/xfree86/common/xf86Helper.c:1734
| #12 in glamor_egl_init () at glamor/glamor_egl.c:1108
| #13 in try_enable_glamor () at hw/xfree86/drivers/modesetting/driver.c:984
| #14 PreInit () at hw/xfree86/drivers/modesetting/driver.c:1211
| #15 in InitOutput () at hw/xfree86/common/xf86Init.c:478
| #16 in dix_main () at dix/main.c:190
| #17 main () at dix/stubmain.c:34
```

Fixes: a449bb4c5 - glamor_egl: add support of GlxVendorLibrary option

Signed-off-by: stefan11111 <stefan11111@shitposting.expert>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2096>
This commit is contained in:
stefan11111 2025-11-07 14:44:55 +02:00
parent a5047d4a65
commit eccee47185

View file

@ -59,7 +59,7 @@ struct glamor_egl_screen_private {
int fd;
struct gbm_device *gbm;
int dmabuf_capable;
Bool force_vendor; /* if GLVND vendor is forced from options */
char *glvnd_vendor; /* GLVND vendor if forced from options or NULL otherwise */
CloseScreenProcPtr saved_close_screen;
DestroyPixmapProcPtr saved_destroy_pixmap;
@ -917,11 +917,13 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
glamor_ctx->make_current = glamor_egl_make_current;
/* Use dynamic logic only if vendor is not forced via xorg.conf */
if (!glamor_egl->force_vendor) {
if (!glamor_egl->glvnd_vendor) {
gbm_backend_name = gbm_device_get_backend_name(glamor_egl->gbm);
/* Mesa uses "drm" as backend name, in that case, just do nothing */
if (gbm_backend_name && strcmp(gbm_backend_name, "drm") != 0)
glamor_set_glvnd_vendor(screen, gbm_backend_name);
} else {
glamor_set_glvnd_vendor(screen, glamor_egl->glvnd_vendor);
}
#ifdef DRI3
/* Tell the core that we have the interfaces for import/export
@ -972,6 +974,7 @@ static void glamor_egl_cleanup(struct glamor_egl_screen_private *glamor_egl)
if (glamor_egl->gbm)
gbm_device_destroy(glamor_egl->gbm);
free(glamor_egl->device_path);
free(glamor_egl->glvnd_vendor);
free(glamor_egl);
}
@ -1108,10 +1111,9 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
memcpy(options, GlamorEGLOptions, sizeof(GlamorEGLOptions));
xf86ProcessOptions(scrn->scrnIndex, scrn->options, options);
glvnd_vendor = xf86GetOptValString(options, GLAMOREGLOPT_VENDOR_LIBRARY);
if (glvnd_vendor) {
glamor_set_glvnd_vendor(xf86ScrnToScreen(scrn), glvnd_vendor);
glamor_egl->force_vendor = TRUE;
}
if (glvnd_vendor)
glamor_egl->glvnd_vendor = XNFstrdup(glvnd_vendor);
api = xf86GetOptValString(options, GLAMOREGLOPT_RENDERING_API);
if (api && !strncasecmp(api, "es", 2))
force_es = TRUE;