summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2015-09-08 11:44:40 -0400
committerRob Clark <robdclark@gmail.com>2015-09-08 11:44:44 -0400
commit048992f71c3c10c5ad50329fa8e38299b69acc48 (patch)
treecf30cd646d7cb8f3b7bcdff72c925d729fbbb259
parentab2280c059f3a9b4d28bf33629e8dafbfc99ba4a (diff)
downloaddrm_gralloc-048992f71c3c10c5ad50329fa8e38299b69acc48.tar.gz
WIP: pipe: use load_pipe_screen()
Rather than duplicate logic about which pipe driver to load, and statically link pipe driver and winsys code into gralloc, dlopen() gallium_dri.so and use the newly introduced load_pipe_screen() to find our pipe driver. This is important, as otherwise we end up w/ two copies of winsys, one in GLES and one in gralloc. Which defeats the purpose of logic in the winsys to avoid having two pipe_screen's (and therefore two fd_device's) for same drm fd. Otherwise we end up w/ scenario's where one pipe_screen (fd_device) closes GEM handles that the other is still using, which leads to SUBMIT ioctl errors and generally a bad time.
-rw-r--r--Android.mk11
-rw-r--r--gralloc_drm_pipe.c216
2 files changed, 58 insertions, 169 deletions
diff --git a/Android.mk b/Android.mk
index b718425..1a64993 100644
--- a/Android.mk
+++ b/Android.mk
@@ -102,15 +102,8 @@ LOCAL_C_INCLUDES += \
hardware/mesa/src/gallium/winsys \
hardware/mesa/src/gallium/drivers \
hardware/mesa/src/gallium/auxiliary
-LOCAL_STATIC_LIBRARIES += \
- libmesa_winsys_freedreno \
- libmesa_pipe_freedreno \
- libmesa_glsl \
- libmesa_gallium \
- libmesa_st_mesa \
- libmesa_util
-LOCAL_CFLAGS += -DENABLE_PIPE -DENABLE_PIPE_FREEDRENO -DDMABUF
-LOCAL_SHARED_LIBRARIES += libdrm_freedreno libdl
+LOCAL_CFLAGS += -DENABLE_PIPE -DDMABUF
+LOCAL_SHARED_LIBRARIES += libdl
endif
ifneq ($(filter $(intel_drivers), $(DRM_GPU_DRIVERS)),)
diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c
index 2c77c54..4666e9d 100644
--- a/gralloc_drm_pipe.c
+++ b/gralloc_drm_pipe.c
@@ -25,6 +25,7 @@
#include <cutils/log.h>
#include <errno.h>
+#include <dlfcn.h>
#define _C99_MATH_H_ /* hack to avoid pulling in c99_math.h which explodes.. */
@@ -41,10 +42,11 @@ struct pipe_manager {
struct gralloc_drm_drv_t base;
int fd;
- char driver[16];
+ void *gallium;
pthread_mutex_t mutex;
struct pipe_screen *screen;
struct pipe_context *context;
+ struct pipe_loader_device *dev;
};
struct pipe_buffer {
@@ -364,6 +366,7 @@ static void pipe_blit(struct gralloc_drm_drv_t *drv,
static void pipe_init_kms_features(struct gralloc_drm_drv_t *drv, struct gralloc_drm_t *drm)
{
struct pipe_manager *pm = (struct pipe_manager *) drv;
+ const char *vendor;
switch (drm->primary.fb_format) {
case HAL_PIXEL_FORMAT_BGRA_8888:
@@ -374,7 +377,8 @@ static void pipe_init_kms_features(struct gralloc_drm_drv_t *drv, struct gralloc
break;
}
- if (strcmp(pm->driver, "vmwgfx") == 0) {
+ vendor = pm->screen->get_vendor(pm->screen);
+ if (strcmp(vendor, "VMware, Inc.") == 0) {
drm->mode_quirk_vmwgfx = 1;
drm->swap_mode = DRM_SWAP_COPY;
}
@@ -394,177 +398,74 @@ static void pipe_destroy(struct gralloc_drm_drv_t *drv)
if (pm->context)
pm->context->destroy(pm->context);
pm->screen->destroy(pm->screen);
+ dlclose(pm->gallium);
FREE(pm);
}
-#ifdef ENABLE_PIPE_FREEDRENO
-#include "freedreno/drm/freedreno_drm_public.h"
-#endif
-#ifdef ENABLE_PIPE_NOUVEAU
-#include "nouveau/drm/nouveau_drm_public.h"
-#endif
-#ifdef ENABLE_PIPE_R300
-#include "radeon/drm/radeon_drm_public.h"
-#include "r300/r300_public.h"
-#endif
-#ifdef ENABLE_PIPE_R600
-#include "radeon/drm/radeon_winsys.h"
-#include "r600/r600_public.h"
-#endif
-#ifdef ENABLE_PIPE_VMWGFX
-#include "svga/drm/svga_drm_public.h"
-#include "svga/svga_winsys.h"
-#include "svga/svga_public.h"
-#endif
-#include "target-helpers/inline_debug_helper.h"
-
-static int pipe_init_screen(struct pipe_manager *pm)
+/* would be nice to move this into a shared helper, since basically
+ * duplicated from dri2_open_driver()..
+ */
+#define DEFAULT_DRIVER_DIR "/system/lib/dri"
+static void * find_driver(const char *driver_name)
{
- struct pipe_screen *screen;
-
-#ifdef ENABLE_PIPE_FREEDRENO
- if (strcmp(pm->driver, "msm") == 0)
- screen = fd_drm_screen_create(pm->fd);
- else
-#endif
-#ifdef ENABLE_PIPE_NOUVEAU
- if (strcmp(pm->driver, "nouveau") == 0)
- screen = nouveau_drm_screen_create(pm->fd);
- else
-#endif
-#ifdef ENABLE_PIPE_R300
- if (strcmp(pm->driver, "r300") == 0) {
- struct radeon_winsys *sws =
- radeon_drm_winsys_create(pm->fd, r300_screen_create);
-
- screen = sws ? sws->screen : NULL;
- }
- else
-#endif
-#ifdef ENABLE_PIPE_R600
- if (strcmp(pm->driver, "r600") == 0) {
- struct radeon_winsys *sws =
- radeon_drm_winsys_create(pm->fd, r600_screen_create);
-
- screen = sws ? sws->screen : NULL;
- }
- else
-#endif
-#ifdef ENABLE_PIPE_VMWGFX
- if (strcmp(pm->driver, "vmwgfx") == 0) {
- struct svga_winsys_screen *sws =
- svga_drm_winsys_screen_create(pm->fd);
+ char path[PATH_MAX], *search_paths, *p, *next, *end;
+ void *driver = NULL;
- screen = sws ? svga_screen_create(sws) : NULL;
+ search_paths = NULL;
+ if (geteuid() == getuid()) {
+ /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
+ search_paths = getenv("LIBGL_DRIVERS_PATH");
}
- else
+ if (search_paths == NULL)
+ search_paths = DEFAULT_DRIVER_DIR;
+
+ end = search_paths + strlen(search_paths);
+ for (p = search_paths; p < end; p = next + 1) {
+ int len;
+ next = strchr(p, ':');
+ if (next == NULL)
+ next = end;
+
+ len = next - p;
+#if GLX_USE_TLS
+ snprintf(path, sizeof path,
+ "%.*s/tls/%s_dri.so", len, p, driver_name);
+ driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
#endif
- screen = NULL;
-
- if (!screen) {
- ALOGW("failed to create pipe screen for %s", pm->driver);
- return -EINVAL;
+ if (driver == NULL) {
+ snprintf(path, sizeof path,
+ "%.*s/%s_dri.so", len, p, driver_name);
+ driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (driver == NULL)
+ ALOGD("failed to open %s: %s\n", path, dlerror());
+ }
+ /* not need continue to loop all paths once the driver is found */
+ if (driver != NULL)
+ break;
}
- pm->screen = debug_screen_wrap(screen);
-
- return 0;
+ return driver;
}
-#include <xf86drm.h>
-#include <i915_drm.h>
-#include <radeon_drm.h>
-static int pipe_get_pci_id(struct pipe_manager *pm,
- const char *name, int *vendor, int *device)
+static int pipe_init_screen(struct pipe_manager *pm)
{
- int err = -EINVAL;
-
- if (strcmp(name, "i915") == 0) {
- struct drm_i915_getparam gp;
-
- *vendor = 0x8086;
-
- memset(&gp, 0, sizeof(gp));
- gp.param = I915_PARAM_CHIPSET_ID;
- gp.value = device;
- err = drmCommandWriteRead(pm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
- }
- else if (strcmp(name, "radeon") == 0) {
- struct drm_radeon_info info;
+ pm->gallium = find_driver("gallium");
+ if (pm->gallium) {
+ struct pipe_screen *(*load_pipe_screen)(struct pipe_loader_device **dev, int fd);
- *vendor = 0x1002;
+ load_pipe_screen = dlsym(pm->gallium, "load_pipe_screen");
- memset(&info, 0, sizeof(info));
- info.request = RADEON_INFO_DEVICE_ID;
- info.value = (long) device;
- err = drmCommandWriteRead(pm->fd, DRM_RADEON_INFO, &info, sizeof(info));
+ pm->screen = load_pipe_screen(&pm->dev, pm->fd);
+ } else {
+ ALOGW("failed to load gallium");
}
- else if (strcmp(name, "nouveau") == 0) {
- *vendor = 0x10de;
- *device = 0;
- err = 0;
- }
- else if (strcmp(name, "vmwgfx") == 0) {
- *vendor = 0x15ad;
- /* assume SVGA II */
- *device = 0x0405;
- err = 0;
- }
- else {
- err = -EINVAL;
- }
-
- return err;
-}
-
-#define DRIVER_MAP_GALLIUM_ONLY
-#include "pci_ids/pci_id_driver_map.h"
-static int pipe_find_driver(struct pipe_manager *pm, const char *name)
-{
- int vendor, device;
- int err;
- const char *driver;
-
- err = pipe_get_pci_id(pm, name, &vendor, &device);
- if (!err) {
- int idx;
-
- /* look up in the driver map */
- for (idx = 0; driver_map[idx].driver; idx++) {
- int i;
-
- if (vendor != driver_map[idx].vendor_id)
- continue;
-
- if (driver_map[idx].num_chips_ids == -1)
- break;
- for (i = 0; i < driver_map[idx].num_chips_ids; i++) {
- if (driver_map[idx].chip_ids[i] == device)
- break;
- }
- if (i < driver_map[idx].num_chips_ids)
- break;
- }
-
- driver = driver_map[idx].driver;
- err = (driver) ? 0 : -ENODEV;
- }
- else {
- if (strcmp(name, "vmwgfx") == 0) {
- driver = "vmwgfx";
- err = 0;
- }
- if (strcmp(name, "msm") == 0) {
- driver = "msm";
- err = 0;
- }
+ if (!pm->screen) {
+ ALOGW("failed to create pipe screen");
+ return -EINVAL;
}
- if (!err)
- strncpy(pm->driver, driver, sizeof(pm->driver) - 1);
-
- return err;
+ return 0;
}
struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *name)
@@ -580,11 +481,6 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *na
pm->fd = fd;
pthread_mutex_init(&pm->mutex, NULL);
- if (pipe_find_driver(pm, name)) {
- FREE(pm);
- return NULL;
- }
-
if (pipe_init_screen(pm)) {
FREE(pm);
return NULL;