diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index 567d883ad..fbb6cb461 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -1016,10 +1016,13 @@ EnumD3DAdapters(bool (*callback)(void *, const char *, uint32_t), void *param) } } -bool device_enum_adapters(bool (*callback)(void *param, const char *name, +bool device_enum_adapters(gs_device_t *device, + bool (*callback)(void *param, const char *name, uint32_t id), void *param) { + UNUSED_PARAMETER(device); + try { EnumD3DAdapters(callback, param); return true; diff --git a/libobs-opengl/gl-egl-common.c b/libobs-opengl/gl-egl-common.c index e53f5a275..77618dc58 100644 --- a/libobs-opengl/gl-egl-common.c +++ b/libobs-opengl/gl-egl-common.c @@ -204,6 +204,53 @@ struct gs_texture *gl_egl_create_texture_from_eglimage( return texture; } +bool gl_egl_enum_adapters(EGLDisplay display, + bool (*callback)(void *param, const char *name, + uint32_t id), + void *param) +{ + EGLDeviceEXT display_dev; + if (eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, + (EGLAttrib *)&display_dev) && + eglGetError() == EGL_SUCCESS) { + const char *display_node = eglQueryDeviceStringEXT( + display_dev, EGL_DRM_RENDER_NODE_FILE_EXT); + if (eglGetError() != EGL_SUCCESS || display_node == NULL) { + display_node = "/Software"; + } + if (!callback(param, display_node, 0)) { + return true; + } + } + + EGLint num_devices = 0; + EGLDeviceEXT devices[32]; + if (!eglQueryDevicesEXT(32, devices, &num_devices)) { + eglGetError(); + return true; + } + + for (int i = 0; i < num_devices; i++) { + const char *node = eglQueryDeviceStringEXT( + devices[i], EGL_DRM_RENDER_NODE_FILE_EXT); + if (node == NULL || eglGetError() != EGL_SUCCESS) { + // Do not enumerate additional software renderers. + continue; + } + if (!callback(param, node, i + 1)) { + return true; + } + } + return true; +} + +uint32_t gs_get_adapter_count() +{ + EGLint num_devices = 0; + eglQueryDevicesEXT(0, NULL, &num_devices); + return 1 + num_devices; // Display + devices. +} + struct gs_texture * gl_egl_create_dmabuf_image(EGLDisplay egl_display, unsigned int width, unsigned int height, uint32_t drm_format, diff --git a/libobs-opengl/gl-egl-common.h b/libobs-opengl/gl-egl-common.h index a168c580e..8cc9648f0 100644 --- a/libobs-opengl/gl-egl-common.h +++ b/libobs-opengl/gl-egl-common.h @@ -27,3 +27,9 @@ gl_egl_create_texture_from_pixmap(EGLDisplay egl_display, uint32_t width, uint32_t height, enum gs_color_format color_format, EGLint target, EGLClientBuffer pixmap); + +bool gl_egl_enum_adapters(EGLDisplay display, + bool (*callback)(void *param, const char *name, + uint32_t id), + void *param); +uint32_t gs_get_adapter_count(); diff --git a/libobs-opengl/gl-nix.c b/libobs-opengl/gl-nix.c index 6d01e211d..12bb43dc8 100644 --- a/libobs-opengl/gl-nix.c +++ b/libobs-opengl/gl-nix.c @@ -95,6 +95,14 @@ extern void device_leave_context(gs_device_t *device) gl_vtable->device_leave_context(device); } +extern bool device_enum_adapters(gs_device_t *device, + bool (*callback)(void *param, const char *name, + uint32_t id), + void *param) +{ + return gl_vtable->device_enum_adapters(device, callback, param); +} + extern void *device_get_device_obj(gs_device_t *device) { return gl_vtable->device_get_device_obj(device); diff --git a/libobs-opengl/gl-nix.h b/libobs-opengl/gl-nix.h index f2801d5d6..f0c4d2007 100644 --- a/libobs-opengl/gl-nix.h +++ b/libobs-opengl/gl-nix.h @@ -73,4 +73,9 @@ struct gl_winsys_vtable { gs_device_t *device, uint32_t width, uint32_t height, enum gs_color_format color_format, uint32_t target, void *pixmap); + bool (*device_enum_adapters)(gs_device_t *device, + bool (*callback)(void *param, + const char *name, + uint32_t id), + void *param); }; diff --git a/libobs-opengl/gl-wayland-egl.c b/libobs-opengl/gl-wayland-egl.c index bd7e14dad..a28f9df58 100644 --- a/libobs-opengl/gl-wayland-egl.c +++ b/libobs-opengl/gl-wayland-egl.c @@ -397,6 +397,15 @@ static struct gs_texture *gl_wayland_egl_device_texture_create_from_pixmap( return NULL; } +static bool gl_wayland_egl_enum_adapters(gs_device_t *device, + bool (*callback)(void *param, + const char *name, + uint32_t id), + void *param) +{ + return gl_egl_enum_adapters(device->plat->display, callback, param); +} + static const struct gl_winsys_vtable egl_wayland_winsys_vtable = { .windowinfo_create = gl_wayland_egl_windowinfo_create, .windowinfo_destroy = gl_wayland_egl_windowinfo_destroy, @@ -420,6 +429,7 @@ static const struct gl_winsys_vtable egl_wayland_winsys_vtable = { gl_wayland_egl_device_query_dmabuf_modifiers_for_format, .device_texture_create_from_pixmap = gl_wayland_egl_device_texture_create_from_pixmap, + .device_enum_adapters = gl_wayland_egl_enum_adapters, }; const struct gl_winsys_vtable *gl_wayland_egl_get_winsys_vtable(void) diff --git a/libobs-opengl/gl-x11-egl.c b/libobs-opengl/gl-x11-egl.c index 56086a997..d6b00c309 100644 --- a/libobs-opengl/gl-x11-egl.c +++ b/libobs-opengl/gl-x11-egl.c @@ -612,6 +612,15 @@ static bool gl_x11_egl_device_query_dmabuf_modifiers_for_format( plat->edisplay, drm_format, modifiers, n_modifiers); } +static bool gl_x11_egl_enum_adapters(gs_device_t *device, + bool (*callback)(void *param, + const char *name, + uint32_t id), + void *param) +{ + return gl_egl_enum_adapters(device->plat->edisplay, callback, param); +} + static const struct gl_winsys_vtable egl_x11_winsys_vtable = { .windowinfo_create = gl_x11_egl_windowinfo_create, .windowinfo_destroy = gl_x11_egl_windowinfo_destroy, @@ -635,6 +644,7 @@ static const struct gl_winsys_vtable egl_x11_winsys_vtable = { gl_x11_egl_device_query_dmabuf_modifiers_for_format, .device_texture_create_from_pixmap = gl_x11_egl_device_texture_create_from_pixmap, + .device_enum_adapters = gl_x11_egl_enum_adapters, }; const struct gl_winsys_vtable *gl_x11_egl_get_winsys_vtable(void) diff --git a/libobs/graphics/device-exports.h b/libobs/graphics/device-exports.h index 4a11d50ee..50fadef99 100644 --- a/libobs/graphics/device-exports.h +++ b/libobs/graphics/device-exports.h @@ -25,7 +25,8 @@ extern "C" { EXPORT const char *device_get_name(void); EXPORT int device_get_type(void); -EXPORT bool device_enum_adapters(bool (*callback)(void *param, const char *name, +EXPORT bool device_enum_adapters(gs_device_t *device, + bool (*callback)(void *param, const char *name, uint32_t id), void *param); EXPORT const char *device_preprocessor_name(void); diff --git a/libobs/graphics/graphics-imports.c b/libobs/graphics/graphics-imports.c index e27cc6a17..8e7bcc4d6 100644 --- a/libobs/graphics/graphics-imports.c +++ b/libobs/graphics/graphics-imports.c @@ -203,6 +203,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT(device_debug_marker_begin); GRAPHICS_IMPORT(device_debug_marker_end); + GRAPHICS_IMPORT_OPTIONAL(gs_get_adapter_count); + /* OSX/Cocoa specific functions */ #ifdef __APPLE__ GRAPHICS_IMPORT(device_shared_texture_available); @@ -222,7 +224,6 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT_OPTIONAL(gs_duplicator_get_texture); GRAPHICS_IMPORT_OPTIONAL(gs_duplicator_get_color_space); GRAPHICS_IMPORT_OPTIONAL(gs_duplicator_get_sdr_white_level); - GRAPHICS_IMPORT_OPTIONAL(gs_get_adapter_count); GRAPHICS_IMPORT_OPTIONAL(device_can_adapter_fast_clear); GRAPHICS_IMPORT_OPTIONAL(device_texture_create_gdi); GRAPHICS_IMPORT_OPTIONAL(gs_texture_get_dc); diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index e2bcb90bf..87cdbeae0 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -26,7 +26,8 @@ struct gs_exports { const char *(*device_get_name)(void); int (*device_get_type)(void); - bool (*device_enum_adapters)(bool (*callback)(void *, const char *, + bool (*device_enum_adapters)(gs_device_t *device, + bool (*callback)(void *, const char *, uint32_t), void *); const char *(*device_preprocessor_name)(void); @@ -291,6 +292,8 @@ struct gs_exports { const float color[4]); void (*device_debug_marker_end)(gs_device_t *device); + uint32_t (*gs_get_adapter_count)(void); + #ifdef __APPLE__ /* OSX/Cocoa specific functions */ gs_texture_t *(*device_texture_create_from_iosurface)(gs_device_t *dev, @@ -321,7 +324,6 @@ struct gs_exports { gs_duplicator_t *duplicator); float (*gs_duplicator_get_sdr_white_level)(gs_duplicator_t *duplicator); - uint32_t (*gs_get_adapter_count)(void); bool (*device_can_adapter_fast_clear)(gs_device_t *device); gs_texture_t *(*device_texture_create_gdi)(gs_device_t *device, diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index 7cdedf806..c064413f8 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -82,7 +82,8 @@ void gs_enum_adapters(bool (*callback)(void *param, const char *name, return; if (graphics->exports.device_enum_adapters) { - if (graphics->exports.device_enum_adapters(callback, param)) { + if (graphics->exports.device_enum_adapters(graphics->device, + callback, param)) { return; } } @@ -2986,6 +2987,16 @@ bool gs_texture_create_p010(gs_texture_t **tex_y, gs_texture_t **tex_uv, return true; } +uint32_t gs_get_adapter_count(void) +{ + if (!gs_valid("gs_get_adapter_count")) + return 0; + if (!thread_graphics->exports.gs_get_adapter_count) + return 0; + + return thread_graphics->exports.gs_get_adapter_count(); +} + #ifdef __APPLE__ /** Platform specific functions */ @@ -3108,16 +3119,6 @@ bool gs_duplicator_update_frame(gs_duplicator_t *duplicator) return thread_graphics->exports.gs_duplicator_update_frame(duplicator); } -uint32_t gs_get_adapter_count(void) -{ - if (!gs_valid("gs_get_adapter_count")) - return 0; - if (!thread_graphics->exports.gs_get_adapter_count) - return 0; - - return thread_graphics->exports.gs_get_adapter_count(); -} - bool gs_can_adapter_fast_clear(void) { if (!gs_valid("gs_can_adapter_fast_clear")) diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index 21c25cc17..2237e6662 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -525,6 +525,7 @@ struct gs_init_data { EXPORT const char *gs_get_device_name(void); EXPORT int gs_get_device_type(void); +EXPORT uint32_t gs_get_adapter_count(void); EXPORT void gs_enum_adapters(bool (*callback)(void *param, const char *name, uint32_t id), void *param); @@ -929,7 +930,6 @@ EXPORT enum gs_color_space gs_duplicator_get_color_space(gs_duplicator_t *duplicator); EXPORT float gs_duplicator_get_sdr_white_level(gs_duplicator_t *duplicator); -EXPORT uint32_t gs_get_adapter_count(void); EXPORT bool gs_can_adapter_fast_clear(void); /** creates a windows GDI-lockable texture */