diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index 980bd222d16..db1b079663f 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -395,6 +395,7 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable, return NULL; } + pdraw->loader_drawable.dri_screen_display_gpu = psc->driScreenDisplayGPU; return &pdraw->base; } @@ -607,8 +608,13 @@ dri3_destroy_screen(struct glx_screen *base) struct dri3_screen *psc = (struct dri3_screen *) base; /* Free the direct rendering per screen data */ - if (psc->is_different_gpu) + if (psc->is_different_gpu) { + if (psc->driScreenDisplayGPU) { + loader_dri3_close_screen(psc->driScreenDisplayGPU); + (*psc->core->destroyScreen) (psc->driScreenDisplayGPU); + } close(psc->fd_display_gpu); + } loader_dri3_close_screen(psc->driScreen); (*psc->core->destroyScreen) (psc->driScreen); driDestroyConfigs(psc->driver_configs); @@ -836,7 +842,7 @@ dri3_create_screen(int screen, struct glx_display * priv) struct dri3_screen *psc; __GLXDRIscreen *psp; struct glx_config *configs = NULL, *visuals = NULL; - char *driverName, *tmp; + char *driverName, *driverNameDisplayGPU, *tmp; int i; psc = calloc(1, sizeof *psc); @@ -900,6 +906,27 @@ dri3_create_screen(int screen, struct glx_display * priv) goto handle_error; } + if (psc->is_different_gpu) { + driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu); + if (driverNameDisplayGPU) { + + /* check if driver name is matching so that non mesa drivers + * will not crash. Also need this check since image extension + * pointer from render gpu is shared with display gpu. Image + * extension pointer is shared because it keeps things simple. + */ + if (strcmp(driverName, driverNameDisplayGPU) == 0) { + psc->driScreenDisplayGPU = + psc->image_driver->createNewScreen2(screen, psc->fd_display_gpu, + pdp->loader_extensions, + extensions, + &driver_configs, psc); + } + + free(driverNameDisplayGPU); + } + } + psc->driScreen = psc->image_driver->createNewScreen2(screen, psc->fd, pdp->loader_extensions, @@ -1019,6 +1046,9 @@ handle_error: if (psc->driScreen) psc->core->destroyScreen(psc->driScreen); psc->driScreen = NULL; + if (psc->driScreenDisplayGPU) + psc->core->destroyScreen(psc->driScreenDisplayGPU); + psc->driScreenDisplayGPU = NULL; if (psc->fd >= 0) close(psc->fd); if (psc->fd_display_gpu >= 0) diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h index 4ccc832f281..c0e833c16ef 100644 --- a/src/glx/dri3_priv.h +++ b/src/glx/dri3_priv.h @@ -89,6 +89,12 @@ struct dri3_screen { __DRIscreen *driScreen; __GLXDRIscreen vtable; + /* DRI screen is created for display GPU in case of prime. + * This screen is used to allocate linear_buffer from + * display GPU space in dri3_alloc_render_buffer() function. + */ + __DRIscreen *driScreenDisplayGPU; + const __DRIimageExtension *image; const __DRIimageDriverExtension *image_driver; const __DRIcoreExtension *core; diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index 5191c89e7f2..a256c377e6e 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -128,6 +128,9 @@ struct loader_dri3_drawable { bool is_different_gpu; bool multiplanes_available; + /* DRI screen created for display GPU in case of prime */ + __DRIscreen *dri_screen_display_gpu; + /* Present extension capabilities */ uint32_t present_capabilities;