summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/egl_g3d/common/native.h37
-rw-r--r--src/gallium/state_trackers/egl_g3d/kms/native_kms.c12
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/native_x11.c76
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/x11_screen.c25
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/x11_screen.h3
5 files changed, 146 insertions, 7 deletions
diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h
index f374f2e4a6..72a9cec7ef 100644
--- a/src/gallium/state_trackers/egl_g3d/common/native.h
+++ b/src/gallium/state_trackers/egl_g3d/common/native.h
@@ -47,6 +47,27 @@ enum native_attachment {
NUM_NATIVE_ATTACHMENTS
};
+/**
+ * Enumerations for probe results.
+ */
+enum native_probe_result {
+ NATIVE_PROBE_UNKNOWN,
+ NATIVE_PROBE_FALLBACK,
+ NATIVE_PROBE_SUPPORTED,
+ NATIVE_PROBE_EXACT,
+};
+
+/**
+ * A probe object for display probe.
+ */
+struct native_probe {
+ int magic;
+ EGLNativeDisplayType display;
+ void *data;
+
+ void (*destroy)(struct native_probe *nprobe);
+};
+
struct native_surface {
void (*destroy)(struct native_surface *nsurf);
@@ -231,6 +252,22 @@ native_attachment_mask_test(uint mask, enum native_attachment att)
return !!(mask & (1 << att));
}
+/**
+ * Return a probe object for the given display.
+ *
+ * Note that the returned object may be cached and used by different native
+ * display modules. It allows fast probing when multiple modules probe the
+ * same display.
+ */
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy);
+
+/**
+ * Probe the probe object.
+ */
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe);
+
const char *
native_get_name(void);
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
index dc66436630..d5baf2c2f0 100644
--- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
@@ -820,6 +820,18 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
return &kdpy->base;
}
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+ return NULL;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+ return NATIVE_PROBE_UNKNOWN;
+}
+
/* the api is destroyed with the native display */
static struct drm_api *drm_api;
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
index 583ce3d329..695ab88010 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
@@ -24,13 +24,89 @@
#include <string.h>
#include "util/u_debug.h"
+#include "util/u_memory.h"
#include "state_tracker/drm_api.h"
#include "egllog.h"
#include "native_x11.h"
+#include "x11_screen.h"
+
+#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
static struct drm_api *api;
+static void
+x11_probe_destroy(struct native_probe *nprobe)
+{
+ if (nprobe->data)
+ free(nprobe->data);
+ free(nprobe);
+}
+
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+ struct native_probe *nprobe;
+ struct x11_screen *xscr;
+ int scr;
+ const char *driver_name = NULL;
+ Display *xdpy;
+
+ nprobe = CALLOC_STRUCT(native_probe);
+ if (!nprobe)
+ return NULL;
+
+ xdpy = dpy;
+ if (!xdpy) {
+ xdpy = XOpenDisplay(NULL);
+ if (!xdpy) {
+ free(nprobe);
+ return NULL;
+ }
+ }
+
+ scr = DefaultScreen(xdpy);
+ xscr = x11_screen_create(xdpy, scr);
+ if (xscr) {
+ if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
+ driver_name = x11_screen_probe_dri2(xscr);
+ nprobe->data = strdup(driver_name);
+ }
+
+ x11_screen_destroy(xscr);
+ }
+
+ if (xdpy != dpy)
+ XCloseDisplay(xdpy);
+
+ nprobe->magic = X11_PROBE_MAGIC;
+ nprobe->display = dpy;
+
+ nprobe->destroy = x11_probe_destroy;
+
+ return nprobe;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+ if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
+ return NATIVE_PROBE_UNKNOWN;
+
+ if (!api)
+ api = drm_api_create();
+
+ /* this is a software driver */
+ if (!api)
+ return NATIVE_PROBE_SUPPORTED;
+
+ /* the display does not support DRI2 or the driver mismatches */
+ if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0)
+ return NATIVE_PROBE_FALLBACK;
+
+ return NATIVE_PROBE_EXACT;
+}
+
const char *
native_get_name(void)
{
diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
index 4d68a88d2e..fef7878ab9 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
@@ -250,6 +250,22 @@ x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver)
}
/**
+ * Probe the screen for the DRI2 driver name.
+ */
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr)
+{
+ /* get the driver name and the device name */
+ if (!xscr->dri_driver) {
+ if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
+ &xscr->dri_driver, &xscr->dri_device))
+ xscr->dri_driver = xscr->dri_device = NULL;
+ }
+
+ return xscr->dri_driver;
+}
+
+/**
* Enable DRI2 and returns the file descriptor of the DRM device. The file
* descriptor will be closed automatically when the screen is destoryed.
*/
@@ -261,13 +277,8 @@ x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
drm_magic_t magic;
/* get the driver name and the device name first */
- if (!xscr->dri_driver) {
- if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
- &xscr->dri_driver, &xscr->dri_device)) {
- xscr->dri_driver = xscr->dri_device = NULL;
- return -1;
- }
- }
+ if (!x11_screen_probe_dri2(xscr))
+ return -1;
if (!x11_screen_is_driver_equal(xscr, driver)) {
_eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
index bf48218905..5432858ac3 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
+++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
@@ -70,6 +70,9 @@ x11_screen_get_glx_configs(struct x11_screen *xscr);
const __GLcontextModes *
x11_screen_get_glx_visuals(struct x11_screen *xscr);
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr);
+
int
x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver);