From 8633ac0279f9272f81aa99524aa078ca14e3da1e Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Thu, 5 May 2011 18:25:19 +0200 Subject: wip --- configs/default | 5 +- src/egl/drivers/dri2/Makefile | 1 + src/egl/drivers/dri2/egl_dri2.h | 2 +- src/gallium/state_trackers/egl/Makefile | 2 +- src/gallium/state_trackers/egl/drm/native_drm.c | 2 +- src/gbm/Makefile | 93 ++--- src/gbm/api.c | 99 ------ src/gbm/backends/Makefile | 32 ++ src/gbm/backends/Makefile.template | 66 ++++ src/gbm/backends/dri/Makefile | 28 ++ src/gbm/backends/dri/dri_internal.h | 45 +++ src/gbm/backends/dri/gbm_dri.c | 378 +++++++++++++++++++++ src/gbm/backends/dri/u_drm_screen.c | 1 + src/gbm/backends/gallium_drm/Makefile | 33 ++ .../backends/gallium_drm/gallium_drm_internal.h | 37 ++ src/gbm/backends/gallium_drm/gbm_gallium_drm.c | 374 ++++++++++++++++++++ src/gbm/common.c | 54 --- src/gbm/common.h | 12 - src/gbm/common_drm.h | 21 -- src/gbm/dri.c | 353 ------------------- src/gbm/dri_internal.h | 45 --- src/gbm/gallium_drm.c | 357 ------------------- src/gbm/gallium_drm_internal.h | 37 -- src/gbm/gbm.h | 78 ----- src/gbm/internal.h | 53 --- src/gbm/main/Makefile | 71 ++++ src/gbm/main/api.c | 102 ++++++ src/gbm/main/common.c | 54 +++ src/gbm/main/common.h | 12 + src/gbm/main/common_drm.h | 21 ++ src/gbm/main/gbm.h | 78 +++++ src/gbm/main/internal.h | 63 ++++ src/gbm/main/module.c | 61 ++++ src/gbm/main/module.h | 9 + 34 files changed, 1493 insertions(+), 1186 deletions(-) delete mode 100644 src/gbm/api.c create mode 100644 src/gbm/backends/Makefile create mode 100644 src/gbm/backends/Makefile.template create mode 100644 src/gbm/backends/dri/Makefile create mode 100644 src/gbm/backends/dri/dri_internal.h create mode 100644 src/gbm/backends/dri/gbm_dri.c create mode 120000 src/gbm/backends/dri/u_drm_screen.c create mode 100644 src/gbm/backends/gallium_drm/Makefile create mode 100644 src/gbm/backends/gallium_drm/gallium_drm_internal.h create mode 100644 src/gbm/backends/gallium_drm/gbm_gallium_drm.c delete mode 100644 src/gbm/common.c delete mode 100644 src/gbm/common.h delete mode 100644 src/gbm/common_drm.h delete mode 100644 src/gbm/dri.c delete mode 100644 src/gbm/dri_internal.h delete mode 100644 src/gbm/gallium_drm.c delete mode 100644 src/gbm/gallium_drm_internal.h delete mode 100644 src/gbm/gbm.h delete mode 100644 src/gbm/internal.h create mode 100644 src/gbm/main/Makefile create mode 100644 src/gbm/main/api.c create mode 100644 src/gbm/main/common.c create mode 100644 src/gbm/main/common.h create mode 100644 src/gbm/main/common_drm.h create mode 100644 src/gbm/main/gbm.h create mode 100644 src/gbm/main/internal.h create mode 100644 src/gbm/main/module.c create mode 100644 src/gbm/main/module.h diff --git a/configs/default b/configs/default index 0582a0210a..d401bf6258 100644 --- a/configs/default +++ b/configs/default @@ -61,7 +61,7 @@ GLESv2_LIB = GLESv2 VG_LIB = OpenVG GLAPI_LIB = glapi WAYLAND_EGL_LIB = wayland-egl - +GBM_LIB = gbm # Library names (actual file names) GL_LIB_NAME = lib$(GL_LIB).so @@ -157,6 +157,9 @@ DRI_DRIVER_SEARCH_DIR = $(DRI_DRIVER_INSTALL_DIR) # EGL driver install directory EGL_DRIVER_INSTALL_DIR = $(INSTALL_LIB_DIR)/egl +# gbm backend install directory +GBM_BACKEND_INSTALL_DIR = $(INSTALL_LIB_DIR)/gbm + # Xorg driver install directory (for xorg state-tracker) XORG_DRIVER_INSTALL_DIR = $(INSTALL_LIB_DIR)/xorg/modules/drivers diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile index 90888f2ee7..39b720a54e 100644 --- a/src/egl/drivers/dri2/Makefile +++ b/src/egl/drivers/dri2/Makefile @@ -13,6 +13,7 @@ EGL_INCLUDES = \ -I$(TOP)/src/egl/main \ -I$(TOP)/src/mapi \ -I$(TOP)/src/ \ + -I$(TOP)/src/gbm/main \ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ $(LIBUDEV_CFLAGS) \ $(LIBDRM_CFLAGS) diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 6c9a832fdd..a29de1a60f 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -44,7 +44,7 @@ #include #include -#include +#include #include "eglconfig.h" #include "eglcontext.h" diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index 7ced8d3c50..549b7aeba2 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -33,7 +33,7 @@ wayland_INCLUDES = \ wayland_SOURCES = $(wildcard wayland/*.c) wayland_OBJECTS = $(wayland_SOURCES:.c=.o) -drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm) -I$(TOP)/src/ +drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm) -I$(TOP)/src/ -I$(TOP)/src/gbm/main drm_SOURCES = $(wildcard drm/*.c) drm_OBJECTS = $(drm_SOURCES:.c=.o) diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c index 2773611c29..d386140336 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.c +++ b/src/gallium/state_trackers/egl/drm/native_drm.c @@ -33,7 +33,7 @@ #include "native_drm.h" -#include "gbm/gallium_drm_internal.h" +#include "gbm/backends/gallium_drm/gallium_drm_internal.h" #ifdef HAVE_LIBUDEV #include diff --git a/src/gbm/Makefile b/src/gbm/Makefile index 0e8764a105..19543ec3be 100644 --- a/src/gbm/Makefile +++ b/src/gbm/Makefile @@ -1,84 +1,31 @@ -# src/egl/Makefile +# src/gbm/Makefile TOP = ../.. include $(TOP)/configs/current -PIPE_PREFIX := pipe_ +SUBDIRS = backends main -INCLUDE_DIRS = -I$(TOP)/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/include -HEADERS = \ - common.h \ - internal.h \ - gbm.h +default: subdirs -SOURCES = \ - api.c \ - common.c \ - dri.c \ - gallium_drm.c -OBJECTS = $(SOURCES:.c=.o) +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done -# use dl*() to load drivers -LOCAL_CFLAGS = -D_OS_UNIX=1 $(LIBDRM_CFLAGS) $(LIBUDEV_CFLAGS) $(DLOPEN_CFLAGS) -LOCAL_LIBS = \ - $(TOP)/src/gallium/drivers/identity/libidentity.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/rbug/librbug.a \ - $(GALLIUM_AUXILIARIES) - -GBM_LIB_DEPS += $(LIBDRM_LIB) $(LIBUDEV_LIBS) $(DLOPEN_LIBS) - -LOCAL_CFLAGS += \ - -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ - -D_EGL_GALLIUM_DRIVER_SEARCH_DIR=\"$(EGL_DRIVER_INSTALL_DIR)\" \ - -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ - - -default: depend library - - -library: $(TOP)/$(LIB_DIR)/libgbm.so - -$(TOP)/$(LIB_DIR)/libgbm.so: $(OBJECTS) $(LOCAL_LIBS) - $(MKLIB) -o gbm -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -major 1 -minor 0 \ - -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ - -L$(TOP)/$(LIB_DIR) $(GBM_LIB_DEPS) \ - $(OBJECTS) $(LOCAL_LIBS) - -install-headers: - $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/ - $(INSTALL) -m 644 $(TOP)/src/gbm/gbm.h \ - $(DESTDIR)$(INSTALL_INC_DIR) - - -PKG_CONFIG_DIR = $(INSTALL_LIB_DIR)/pkgconfig - - -install: default install-headers - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/libgbm.so* \ - $(DESTDIR)$(INSTALL_LIB_DIR) +install: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done clean: - -rm -f *.o - -rm -f depend depend.bak - - -depend: $(SOURCES) $(HEADERS) - @ echo "running $(MKDEP)" - @ rm -f depend - @ touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \ - $(SOURCES) $(HEADERS) > /dev/null 2>/dev/null - - --include depend -# DO NOT DELETE + -@for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done diff --git a/src/gbm/api.c b/src/gbm/api.c deleted file mode 100644 index f8aaf7b2a6..0000000000 --- a/src/gbm/api.c +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include - -#include "gbm.h" -#include "internal.h" - -GBM_EXPORT int -gbm_device_get_fd(struct gbm_device *gbm) -{ - return gbm->fd; -} - -/* FIXME: maybe superfluous, use udev subclass from the fd? */ -GBM_EXPORT const char * -gbm_device_get_backend_name(struct gbm_device *gbm) -{ - return gbm->name; -} - -GBM_EXPORT void -gbm_device_destroy(struct gbm_device *gbm) -{ - gbm->destroy(gbm); -} - -GBM_EXPORT struct gbm_device * -gbm_device_create(int fd) -{ - struct gbm_device *gbm; - - gbm = dri_device_create(fd); - //gbm = gbm_gallium_drm_device_create(fd); - if (gbm == NULL) - return NULL; - - gbm->dummy = gbm_device_create; - - return gbm; -} - -GBM_EXPORT unsigned int -gbm_bo_get_width(struct gbm_bo *bo) -{ - return bo->width; -} - -GBM_EXPORT unsigned int -gbm_bo_get_height(struct gbm_bo *bo) -{ - return bo->height; -} - -GBM_EXPORT uint32_t -gbm_bo_get_pitch(struct gbm_bo *bo) -{ - return bo->pitch; -} - -GBM_EXPORT union gbm_bo_handle -gbm_bo_get_handle(struct gbm_bo *bo) -{ - return bo->handle; -} - -GBM_EXPORT void -gbm_bo_destroy(struct gbm_bo *bo) -{ - bo->gbm->bo_destroy(bo); -} - -GBM_EXPORT struct gbm_bo * -gbm_bo_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - enum gbm_bo_format format, uint32_t usage) -{ - if (width == 0 || height == 0) - return NULL; - - /* XXX sanity check type */ - - if (usage & GBM_BO_USE_CURSOR_64X64 && - (width != 64 || height != 64)) - return NULL; - - return gbm->bo_create(gbm, width, height, format, usage); -} - -GBM_EXPORT struct gbm_bo * -gbm_bo_create_from_egl_image(struct gbm_device *gbm, - void *egl_dpy, void *egl_image, - uint32_t width, uint32_t height, - enum gbm_bo_format format) -{ - if (width == 0 || height == 0) - return NULL; - - return gbm->bo_create_from_egl_image(gbm, egl_dpy, egl_image, - width, height, format); -} diff --git a/src/gbm/backends/Makefile b/src/gbm/backends/Makefile new file mode 100644 index 0000000000..994bbba878 --- /dev/null +++ b/src/gbm/backends/Makefile @@ -0,0 +1,32 @@ +# src/gbm/backends/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + +# SUBDIRS = $(EGL_DRIVERS_DIRS) +SUBDIRS = dri gallium_drm + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir ; $(MAKE)) || exit 1 ; \ + fi \ + done + +install: + @ for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir ; $(MAKE) install) || exit 1 ; \ + fi \ + done + +clean: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir ; $(MAKE) clean) ; \ + fi \ + done diff --git a/src/gbm/backends/Makefile.template b/src/gbm/backends/Makefile.template new file mode 100644 index 0000000000..9df2ed930d --- /dev/null +++ b/src/gbm/backends/Makefile.template @@ -0,0 +1,66 @@ +# src/gbm/backends/Makefile.template +# +# Backends should define +# +# GBM_BUILTIN, the driver is built-in or external +# GBM_BACKEND, the driver name +# GBM_SOURCES, the driver sources +# GBM_INCLUDES, the include pathes +# GBM_CFLAGS, additional CFLAGS +# GBM_LIBS, additional LIBS +# +# before including this template. +# + + +GBM_BACKEND_PATH = $(TOP)/$(LIB_DIR)/gbm/$(GBM_BACKEND).so +GBM_OBJECTS = $(GBM_SOURCES:.c=.o) + +# built-in or external +ifeq ($(GBM_BUILTIN),true) +GBM_TARGET = lib$(GBM_BACKEND).a +GBM_INSTALL = +else +GBM_TARGET = $(GBM_BACKEND_PATH) +GBM_INSTALL = install-so +endif + +default: depend $(GBM_TARGET) + +$(GBM_BACKEND_PATH): $(GBM_BACKEND).so + @$(INSTALL) -d $(TOP)/$(LIB_DIR)/gbm + $(INSTALL) $< $(TOP)/$(LIB_DIR)/gbm + +$(GBM_BACKEND).so: $(GBM_OBJECTS) Makefile $(TOP)/src/gbm/backends/Makefile.template + @$(MKLIB) -o $(GBM_BACKEND).so -noprefix \ + -linker '$(CC)' -ldflags '-L$(TOP)/$(LIB_DIR) $(LDFLAGS)' \ + $(MKLIB_OPTIONS) \ + $(GBM_OBJECTS) $(GBM_LIBS) -l$(GBM_LIB) + +lib$(GBM_BACKEND).a: $(GBM_OBJECTS) Makefile $(TOP)/src/gbm/backends/Makefile.template + @$(MKLIB) -o $(GBM_BACKEND) -static $(GBM_OBJECTS) + +.c.o: + $(CC) -c $(GBM_INCLUDES) $(CFLAGS) $(GBM_CFLAGS) $< -o $@ + +install-so: $(GBM_BACKEND_PATH) + $(INSTALL) -d $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR) + $(MINSTALL) $(GBM_BACKEND_PATH) $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR) + +install: $(GBM_INSTALL) + +clean: + rm -f $(GBM_BACKEND).so + rm -f lib$(GBM_BACKEND).a + rm -f $(GBM_OBJECTS) + rm -f depend depend.bak + +depend: $(GBM_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(GBM_INCLUDES) $(GBM_SOURCES) \ + >/dev/null 2>/dev/null + +sinclude depend +# DO NOT DELETE diff --git a/src/gbm/backends/dri/Makefile b/src/gbm/backends/dri/Makefile new file mode 100644 index 0000000000..e47b39b01e --- /dev/null +++ b/src/gbm/backends/dri/Makefile @@ -0,0 +1,28 @@ +# src/gbm/backends/dri/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + +GBM_BACKEND = gbm_dri +GBM_SOURCES = gbm_dri.c u_drm_screen.c + +GBM_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/gbm/main \ + -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ + $(LIBUDEV_CFLAGS) \ + $(LIBDRM_CFLAGS) + +# Includes for u_drm_screen.c +GBM_INCLUDES += \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/include + +GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) + +GBM_CFLAGS = +GBM_BUILTIN = +#GBM_CFLAGS = -D_GBM_MAIN=_eglBuiltInDriverDRI2 +#GBM_BUILTIN = true + +include ../Makefile.template diff --git a/src/gbm/backends/dri/dri_internal.h b/src/gbm/backends/dri/dri_internal.h new file mode 100644 index 0000000000..a065a3c416 --- /dev/null +++ b/src/gbm/backends/dri/dri_internal.h @@ -0,0 +1,45 @@ +#ifndef _GBM_DRI_INTERNAL_H_ +#define _GBM_DRI_INTERNAL_H_ + +#include "internal.h" + +#include "common.h" +#include "common_drm.h" + +struct gbm_dri_device { + struct gbm_drm_device base; + + void *driver; + + __DRIscreen *screen; + + __DRIcoreExtension *core; + __DRIdri2Extension *dri2; + __DRIimageExtension *image; + + const __DRIconfig **driver_configs; + const __DRIextension *extensions[3]; + + __DRIimage *(*lookup_image)(__DRIscreen *screen, void *image, void *data); + void *lookup_user_data; +}; + +struct gbm_dri_bo { + struct gbm_drm_bo base; + + __DRIimage *image; +}; + +static inline struct gbm_dri_device * +gbm_dri_device(struct gbm_device *gbm) +{ + return (struct gbm_dri_device *) gbm; +} + +static inline struct gbm_dri_bo * +gbm_dri_bo(struct gbm_bo *bo) +{ + return (struct gbm_dri_bo *) bo; +} + +#endif diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c new file mode 100644 index 0000000000..a2dd28c013 --- /dev/null +++ b/src/gbm/backends/dri/gbm_dri.c @@ -0,0 +1,378 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include /* dri_interface needs GL types */ +#include + +#include "util/u_drm_screen.h" + +#include "dri_internal.h" + +#include "internal.h" + +static __DRIimage * +dri_lookup_egl_image(__DRIscreen *screen, void *image, void *data) +{ + struct gbm_dri_device *dri = data; + + return dri->lookup_image(screen, image, dri->lookup_user_data); +} + +const __DRIuseInvalidateExtension use_invalidate = { + { __DRI_USE_INVALIDATE, 1 } +}; + +const __DRIimageLookupExtension image_lookup_extension = { + { __DRI_IMAGE_LOOKUP, 1 }, + dri_lookup_egl_image +}; + +struct dri_extension_match { + const char *name; + int version; + int offset; +}; + +static struct dri_extension_match dri_core_extensions[] = { + { __DRI_IMAGE, 1, offsetof(struct gbm_dri_device, image) }, + { NULL, 0, 0 } +}; + +static struct dri_extension_match gbm_dri_device_extensions[] = { + { __DRI_CORE, 1, offsetof(struct gbm_dri_device, core) }, + { __DRI_DRI2, 1, offsetof(struct gbm_dri_device, dri2) }, + { NULL, 0, 0 } +}; + +static int +dri_bind_extensions(struct gbm_dri_device *dri, + struct dri_extension_match *matches, + const __DRIextension **extensions) +{ + int i, j, ret = 0; + void *field; + + for (i = 0; extensions[i]; i++) { + for (j = 0; matches[j].name; j++) { + if (strcmp(extensions[i]->name, matches[j].name) == 0 && + extensions[i]->version >= matches[j].version) { + field = ((char *) dri + matches[j].offset); + *(const __DRIextension **) field = extensions[i]; + } + } + } + + for (j = 0; matches[j].name; j++) { + field = ((char *) dri + matches[j].offset); + if (*(const __DRIextension **) field == NULL) { + ret = -1; + } + } + + return ret; +} + +static int +dri_load_driver(struct gbm_dri_device *dri) +{ + const __DRIextension **extensions; + char path[PATH_MAX], *search_paths, *p, *next, *end; + + search_paths = NULL; + if (geteuid() == getuid()) { + /* don't allow setuid apps to use GBM_DRIVERS_PATH */ + search_paths = getenv("GBM_DRIVERS_PATH"); + } + if (search_paths == NULL) + search_paths = DEFAULT_DRIVER_DIR; + + dri->driver = NULL; + end = search_paths + strlen(search_paths); + for (p = search_paths; p < end && dri->driver == NULL; 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, dri->base.driver_name); + dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); +#endif + if (dri->driver == NULL) { + snprintf(path, sizeof path, + "%.*s/%s_dri.so", len, p, dri->base.driver_name); + dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); + if (dri->driver == NULL) + fprintf(stderr, "failed to open %s: %s\n", path, dlerror()); + } + } + + if (dri->driver == NULL) { + fprintf(stderr, "gbm: failed to open any driver (search paths %s)", + search_paths); + return -1; + } + + extensions = dlsym(dri->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + fprintf(stderr, "gbm: driver exports no extensions (%s)", dlerror()); + dlclose(dri->driver); + return -1; + } + + + if (dri_bind_extensions(dri, gbm_dri_device_extensions, extensions) < 0) { + dlclose(dri->driver); + fprintf(stderr, "failed to bind extensions\n"); + return -1; + } + + return 0; +} + +static int +dri_screen_create(struct gbm_dri_device *dri) +{ + const __DRIextension **extensions; + int ret = 0; + + dri->base.driver_name = util_drm_fd_get_screen_name(dri->base.base.fd); + printf("driver name. %s\n", dri->base.driver_name); + + ret = dri_load_driver(dri); + if (ret) { + fprintf(stderr, "failed to load driver: %s\n", dri->base.driver_name); + return ret; + }; + + dri->extensions[0] = &image_lookup_extension.base; + dri->extensions[1] = &use_invalidate.base; + dri->extensions[2] = NULL; + + if (dri->dri2 == NULL) + return -1; + + dri->screen = dri->dri2->createNewScreen(0, dri->base.base.fd, dri->extensions, + &dri->driver_configs, dri); + + extensions = dri->core->getExtensions(dri->screen); + if (dri_bind_extensions(dri, dri_core_extensions, extensions) < 0) { + ret = -1; + goto free_screen; + } + + dri->lookup_image = NULL; + dri->lookup_user_data = NULL; + + return 0; + +free_screen: + dri->core->destroyScreen(dri->screen); + + return ret; +} + +static void +gbm_dri_bo_destroy(struct gbm_bo *_bo) +{ + struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm); + struct gbm_dri_bo *bo = gbm_dri_bo(_bo); + + dri->image->destroyImage(bo->image); +} + + +/* FIXME: need __DRIimage::dupImage */ +static __DRIimage * +dri_reference_image(struct gbm_dri_device *dri, __DRIimage *orig, + uint32_t width, uint32_t height, uint32_t format, + void *user_data) +{ + __DRIimage *image; + int32_t name, pitch; + + dri->image->queryImage(orig, __DRI_IMAGE_ATTRIB_NAME, &name); + dri->image->queryImage(orig, __DRI_IMAGE_ATTRIB_STRIDE, &pitch); + + image = dri->image->createImageFromName(dri->screen, width, height, + format, name, pitch / 4, user_data); + + return image; +} + +static struct gbm_bo * +gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm, + void *egl_dpy, void *egl_img, + uint32_t width, uint32_t height, + enum gbm_bo_format format) +{ + struct gbm_dri_device *dri = gbm_dri_device(gbm); + struct gbm_dri_bo *bo; + int dri_format; + + bo = calloc(1, sizeof *bo); + if (bo == NULL) + return NULL; + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + switch (format) { + case GBM_BO_FORMAT_XRGB8888: + dri_format = __DRI_IMAGE_FORMAT_XRGB8888; + break; + case GBM_BO_FORMAT_ARGB8888: + dri_format = __DRI_IMAGE_FORMAT_ARGB8888; + break; + default: + return NULL; + } + + if (dri->lookup_image == NULL) + return NULL; + + __DRIimage *tmp = dri->lookup_image(dri->screen, egl_img, dri->lookup_user_data); + + bo->image = dri_reference_image(dri, tmp, width, height, dri_format, bo); + if (bo->image == NULL) + return NULL; + + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, + &bo->base.base.handle.s32); + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, + (int *) &bo->base.base.pitch); + + return &bo->base.base; +} + +static struct gbm_bo * +gbm_dri_bo_create(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, uint32_t usage) +{ + struct gbm_dri_device *dri = gbm_dri_device(gbm); + struct gbm_dri_bo *bo; + int dri_format; + unsigned dri_use = 0; + + bo = calloc(1, sizeof *bo); + if (bo == NULL) + return NULL; + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + switch (format) { + case GBM_BO_FORMAT_XRGB8888: + dri_format = __DRI_IMAGE_FORMAT_XRGB8888; + break; + case GBM_BO_FORMAT_ARGB8888: + dri_format = __DRI_IMAGE_FORMAT_ARGB8888; + break; + default: + return NULL; + } + + if (usage & GBM_BO_USE_SCANOUT) + dri_use |= __DRI_IMAGE_USE_SCANOUT; +#if 0 + if (usage & GBM_BO_USE_CURSOR_64X64) + dri_use = |= __DRI_IMAGE_USE_CURSOR_64X64; +#endif + + bo->image = + dri->image->createImage(dri->screen, + width, height, + dri_format, dri_use, + bo); + if (bo->image == NULL) + return NULL; + + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, + &bo->base.base.handle.s32); + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, + (int *) &bo->base.base.pitch); + + return &bo->base.base; +} + +static void +dri_destroy(struct gbm_device *gbm) +{ + struct gbm_dri_device *dri = gbm_dri_device(gbm); + //int i; + + dri->core->destroyScreen(dri->screen); +#if 0 + for (i = 0; dri->driver_configs[i]; ++i) + free(dri->driver_configs[i]); +#endif + free(dri->driver_configs); + dlclose(dri->driver); + free(dri->base.driver_name); + + free(dri); +} + +static struct gbm_device * +dri_device_create(int fd) +{ + struct gbm_dri_device *dri; + int ret; + + dri = calloc(1, sizeof *dri); + + dri->base.base.fd = fd; + dri->base.base.bo_create = gbm_dri_bo_create; + dri->base.base.bo_create_from_egl_image = gbm_dri_bo_create_from_egl_image; + dri->base.base.bo_destroy = gbm_dri_bo_destroy; + dri->base.base.destroy = dri_destroy; + + dri->base.type = GBM_DRM_DRIVER_TYPE_DRI; + dri->base.base.name = "drm"; + + ret = dri_screen_create(dri); + if (ret) { + free(dri); + return NULL; + } + + return &dri->base.base; +} + +static int +dri_probe(int fd) +{ + char *name; + int ret = 0; + + name = util_drm_fd_get_screen_name(fd); + if (name == NULL) { + ret = -1; + } else { + free(name); + ret = 0; + } + + return ret; +} + + +GBM_EXPORT struct gbm_backend gbm_backend = { + .class_name = "drm", + .backend_name = "dri", + .probe = dri_probe, + .create_device = dri_device_create, +}; diff --git a/src/gbm/backends/dri/u_drm_screen.c b/src/gbm/backends/dri/u_drm_screen.c new file mode 120000 index 0000000000..9e5413df97 --- /dev/null +++ b/src/gbm/backends/dri/u_drm_screen.c @@ -0,0 +1 @@ +../../../gallium/auxiliary/util/u_drm_screen.c \ No newline at end of file diff --git a/src/gbm/backends/gallium_drm/Makefile b/src/gbm/backends/gallium_drm/Makefile new file mode 100644 index 0000000000..0459635f08 --- /dev/null +++ b/src/gbm/backends/gallium_drm/Makefile @@ -0,0 +1,33 @@ +# src/gbm/backends/gallium_drm/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + +PIPE_PREFIX := pipe_ + +GBM_BACKEND = gbm_gallium_drm +GBM_SOURCES = gbm_gallium_drm.c + +GBM_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/gbm/main \ + $(LIBUDEV_CFLAGS) \ + $(LIBDRM_CFLAGS) + +GBM_INCLUDES += \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/include + +GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) \ + $(TOP)/src/gallium/drivers/identity/libidentity.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ + $(GALLIUM_AUXILIARIES) + + +GBM_CFLAGS = -D_EGL_GALLIUM_DRIVER_SEARCH_DIR=\"$(EGL_DRIVER_INSTALL_DIR)\" -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" +GBM_BUILTIN = +#GBM_CFLAGS = -D_GBM_MAIN=_eglBuiltInDriverDRI2 +#GBM_BUILTIN = true + +include ../Makefile.template diff --git a/src/gbm/backends/gallium_drm/gallium_drm_internal.h b/src/gbm/backends/gallium_drm/gallium_drm_internal.h new file mode 100644 index 0000000000..7f9bc081ae --- /dev/null +++ b/src/gbm/backends/gallium_drm/gallium_drm_internal.h @@ -0,0 +1,37 @@ + +#ifndef _GBM_GALLIUM_DRM_INTERNAL_H_ +#define _GBM_GALLIUM_DRM_INTERNAL_H_ + +#include "pipe/p_state.h" + +#include "internal.h" + +#include "common.h" +#include "common_drm.h" + +struct gbm_gallium_drm_device { + struct gbm_drm_device base; + + struct pipe_screen *screen; + void *driver; +}; + +struct gbm_gallium_drm_bo { + struct gbm_drm_bo base; + + struct pipe_resource *resource; +}; + +static inline struct gbm_gallium_drm_device * +gbm_gallium_drm_device(struct gbm_device *gbm) +{ + return (struct gbm_gallium_drm_device *) gbm; +} + +static inline struct gbm_gallium_drm_bo * +gbm_gallium_drm_bo(struct gbm_bo *bo) +{ + return (struct gbm_gallium_drm_bo *) bo; +} + +#endif diff --git a/src/gbm/backends/gallium_drm/gbm_gallium_drm.c b/src/gbm/backends/gallium_drm/gbm_gallium_drm.c new file mode 100644 index 0000000000..6b3fb1e4a9 --- /dev/null +++ b/src/gbm/backends/gallium_drm/gbm_gallium_drm.c @@ -0,0 +1,374 @@ +#include + +#define EGL_EGLEXT_PROTOTYPES +#include "EGL/egl.h" +#include "EGL/eglext.h" + +#include "util/u_memory.h" +#include "util/u_string.h" +#include "util/u_dl.h" +#include "util/u_inlines.h" +#include "util/u_drm_screen.h" + +#include "state_tracker/drm_driver.h" + +#include +#include + +#include "gallium_drm_internal.h" + +static struct pipe_module { + boolean initialized; + char *name; + struct util_dl_library *lib; + const struct drm_driver_descriptor *drmdd; +} pipe_modules[16]; + +static char * +loader_strdup(const char *s) +{ + size_t len = (s) ? strlen(s) : 0; + char *t = MALLOC(len + 1); + if (t) { + memcpy(t, s, len); + t[len] = '\0'; + } + return t; +} + +static void +find_pipe_module(struct pipe_module *pmod, const char *name) +{ + char *search_paths, *end, *next, *p; + char path[PATH_MAX]; + int ret; + + search_paths = NULL; + if (geteuid() == getuid()) { + /* don't allow setuid apps to use EGL_DRIVERS_PATH */ + search_paths = getenv("EGL_DRIVERS_PATH"); + } + if (search_paths == NULL) + search_paths = _EGL_GALLIUM_DRIVER_SEARCH_DIR; + + end = search_paths + strlen(search_paths); + for (p = search_paths; p < end && pmod->lib == NULL; p = next + 1) { + int len; + next = strchr(p, ':'); + if (next == NULL) + next = end; + + len = next - p; + + if (len) { + ret = util_snprintf(path, sizeof(path), + "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, p, pmod->name); + } + else { + ret = util_snprintf(path, sizeof(path), + PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name); + } + if (ret > 0 && ret < sizeof(path)) { + pmod->lib = util_dl_open(path); +#if 0 + if (pmod->lib) + _eglLog(_EGL_DEBUG, "loaded %s", path); +#endif + } + + } +} + +static boolean +load_pipe_module(struct pipe_module *pmod, const char *name) +{ + pmod->name = loader_strdup(name); + if (!pmod->name) + return FALSE; + + find_pipe_module(pmod, name); + + if (pmod->lib) { + pmod->drmdd = (const struct drm_driver_descriptor *) + util_dl_get_proc_address(pmod->lib, "driver_descriptor"); + + /* sanity check on the name */ + if (pmod->drmdd && strcmp(pmod->drmdd->name, pmod->name) != 0) + pmod->drmdd = NULL; + + if (!pmod->drmdd) { + util_dl_close(pmod->lib); + pmod->lib = NULL; + } + } + + return (pmod->drmdd != NULL); +} + +static struct pipe_module * +get_pipe_module(const char *name) +{ + struct pipe_module *pmod = NULL; + int i; + + if (!name) + return NULL; + + for (i = 0; i < Elements(pipe_modules); i++) { + if (!pipe_modules[i].initialized || + strcmp(pipe_modules[i].name, name) == 0) { + pmod = &pipe_modules[i]; + break; + } + } + if (!pmod) + return NULL; + + if (!pmod->initialized) { + load_pipe_module(pmod, name); + pmod->initialized = TRUE; + } + + return pmod; +} + +static struct pipe_screen * +create_drm_screen(const char *name, int fd) +{ + struct pipe_module *pmod = get_pipe_module(name); + + return (pmod && pmod->drmdd && pmod->drmdd->create_screen) ? + pmod->drmdd->create_screen(fd) : NULL; +} + +static int +gallium_screen_create(struct gbm_gallium_drm_device *gdrm) +{ + gdrm->base.driver_name = util_drm_fd_get_screen_name(gdrm->base.base.fd); + printf("driver name. %s\n", gdrm->base.driver_name); + + gdrm->screen = create_drm_screen(gdrm->base.driver_name, gdrm->base.base.fd); + if (gdrm->screen == NULL) { + fprintf(stderr, "failed to load driver: %s\n", gdrm->base.driver_name); + return -1; + }; + + return 0; +} + +static void +gbm_gallium_drm_bo_destroy(struct gbm_bo *_bo) +{ + struct gbm_gallium_drm_bo *bo = gbm_gallium_drm_bo(_bo); + + pipe_resource_reference(&bo->resource, NULL); +} + +static struct gbm_bo * +gbm_gallium_drm_bo_create_from_egl_image(struct gbm_device *gbm, + void *egl_dpy, void *egl_image, + uint32_t width, uint32_t height, + enum gbm_bo_format format) +{ + struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); + struct gbm_gallium_drm_bo *bo; + struct pipe_resource templ; + struct winsys_handle whandle; + uint resource_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + enum pipe_format pf; + + int32_t name, pitch; + + eglExportDRMImageMESA(egl_dpy, egl_image, &name, NULL, &pitch); + + bo = CALLOC_STRUCT(gbm_gallium_drm_bo); + if (bo == NULL) + return NULL; + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + switch (format) { + case GBM_BO_FORMAT_XRGB8888: + pf = PIPE_FORMAT_B8G8R8X8_UNORM; + break; + case GBM_BO_FORMAT_ARGB8888: + pf = PIPE_FORMAT_B8G8R8A8_UNORM; + break; + default: + return NULL; + } + + memset(&templ, 0, sizeof(templ)); + templ.bind = resource_usage; + templ.format = pf; + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.array_size = 1; + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_SHARED; + whandle.handle = name; + whandle.stride = pitch; + + bo->resource = gdrm->screen->resource_from_handle(gdrm->screen, &templ, &whandle); + if (bo->resource == NULL) { + FREE(bo); + return NULL; + } + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_KMS; + gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle); + + bo->base.base.handle.u32 = whandle.handle; + bo->base.base.pitch = whandle.stride; + + return &bo->base.base; +} + +static struct gbm_bo * +gbm_gallium_drm_bo_create(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, uint32_t usage) +{ + struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); + struct gbm_gallium_drm_bo *bo; + struct pipe_resource templ; + struct winsys_handle whandle; + uint resource_usage = 0; + enum pipe_format pf; + + bo = CALLOC_STRUCT(gbm_gallium_drm_bo); + if (bo == NULL) + return NULL; + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + switch (format) { + case GBM_BO_FORMAT_XRGB8888: + pf = PIPE_FORMAT_B8G8R8X8_UNORM; + break; + case GBM_BO_FORMAT_ARGB8888: + pf = PIPE_FORMAT_B8G8R8A8_UNORM; + break; + default: + return NULL; + } + + if (usage & GBM_BO_USE_SCANOUT) + resource_usage |= PIPE_BIND_SCANOUT; + + if (usage & GBM_BO_USE_RENDERING) + resource_usage |= PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + +#if 0 + if (usage & GBM_BO_USE_CURSOR_64X64) + resource_usage |= PIPE_BIND_CURSOR; +#endif + + memset(&templ, 0, sizeof(templ)); + templ.bind = resource_usage; + templ.format = pf; + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.array_size = 1; + + bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ); + if (bo->resource == NULL) { + FREE(bo); + return NULL; + } + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_KMS; + gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle); + + bo->base.base.handle.u32 = whandle.handle; + bo->base.base.pitch = whandle.stride; + + return &bo->base.base; +} + +static boolean +pipe_modules_destroy(void) +{ + //util_dl_close + + return TRUE; +} + +static void +gbm_gallium_drm_destroy(struct gbm_device *gbm) +{ + struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); + + gdrm->screen->destroy(gdrm->screen); + + pipe_modules_destroy(); + FREE(gdrm->base.driver_name); + + FREE(gdrm); +} + +static struct gbm_device * +gbm_gallium_drm_device_create(int fd) +{ + struct gbm_gallium_drm_device *dri; + int ret; + + dri = calloc(1, sizeof *dri); + printf("create g3d\n"); + + dri->base.base.fd = fd; + dri->base.base.bo_create = gbm_gallium_drm_bo_create; + dri->base.base.bo_create_from_egl_image = + gbm_gallium_drm_bo_create_from_egl_image; + dri->base.base.bo_destroy = gbm_gallium_drm_bo_destroy; + dri->base.base.destroy = gbm_gallium_drm_destroy; + + dri->base.type = GBM_DRM_DRIVER_TYPE_GALLIUM; + dri->base.base.name = "drm"; + + ret = gallium_screen_create(dri); + if (ret) { + free(dri); + return NULL; + } + + return &dri->base.base; +} + +static int +gallium_drm_probe(int fd) +{ + char *name; + int ret = 0; + + name = util_drm_fd_get_screen_name(fd); + if (name == NULL) { + ret = -1; + } else { + free(name); + ret = 0; + } + + return ret; +} + + +GBM_EXPORT struct gbm_backend gbm_backend = { + .class_name = "drm", + .backend_name = "gallium", + .probe = gallium_drm_probe, + .create_device = gbm_gallium_drm_device_create, +}; diff --git a/src/gbm/common.c b/src/gbm/common.c deleted file mode 100644 index 9c5aac94fd..0000000000 --- a/src/gbm/common.c +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -#include "common.h" - -struct udev_device * -_udev_device_new_from_fd(struct udev *udev, int fd) -{ - struct udev_device *device; - struct stat buf; - - if (fstat(fd, &buf) < 0) { - fprintf(stderr, "gbm: failed to stat fd %d", fd); - return NULL; - } - - device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev); - if (device == NULL) { - fprintf(stderr, - "gbm: could not create udev device for fd %d", fd); - return NULL; - } - - return device; -} - -char * -fd_get_device_name(int fd) -{ - struct udev *udev; - struct udev_device *device; - char *device_name; - - udev = udev_new(); - device = _udev_device_new_from_fd(udev, fd); - if (device == NULL) - return NULL; - - device_name = (char *) udev_device_get_devnode(device); - if (!device_name) - goto out; - device_name = strdup(device_name); - -out: - udev_device_unref(device); - udev_unref(udev); - - return device_name; -} diff --git a/src/gbm/common.h b/src/gbm/common.h deleted file mode 100644 index ee33e972bb..0000000000 --- a/src/gbm/common.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _COMMON_H_ -#define _COMMON_H_ - -#include - -struct udev_device * -_udev_device_new_from_fd(struct udev *udev, int fd); - -char * -fd_get_device_name(int fd); - -#endif diff --git a/src/gbm/common_drm.h b/src/gbm/common_drm.h deleted file mode 100644 index 44985c42aa..0000000000 --- a/src/gbm/common_drm.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _COMMON_DRM_H_ -#define _COMMON_DRM_H_ - -#include "internal.h" - -enum gbm_drm_driver_type { - GBM_DRM_DRIVER_TYPE_DRI, - GBM_DRM_DRIVER_TYPE_GALLIUM, -}; - -struct gbm_drm_device { - struct gbm_device base; - enum gbm_drm_driver_type type; - char *driver_name; -}; - -struct gbm_drm_bo { - struct gbm_bo base; -}; - -#endif diff --git a/src/gbm/dri.c b/src/gbm/dri.c deleted file mode 100644 index a8c588a6ea..0000000000 --- a/src/gbm/dri.c +++ /dev/null @@ -1,353 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include /* dri_interface needs GL types */ -#include - -#include "util/u_drm_screen.h" - -#include "dri_internal.h" - -#include "internal.h" - -static __DRIimage * -dri_lookup_egl_image(__DRIscreen *screen, void *image, void *data) -{ - struct gbm_dri_device *dri = data; - - return dri->lookup_image(screen, image, dri->lookup_user_data); -} - -const __DRIuseInvalidateExtension use_invalidate = { - { __DRI_USE_INVALIDATE, 1 } -}; - -const __DRIimageLookupExtension image_lookup_extension = { - { __DRI_IMAGE_LOOKUP, 1 }, - dri_lookup_egl_image -}; - -struct dri_extension_match { - const char *name; - int version; - int offset; -}; - -static struct dri_extension_match dri_core_extensions[] = { - { __DRI_IMAGE, 1, offsetof(struct gbm_dri_device, image) }, - { NULL, 0, 0 } -}; - -static struct dri_extension_match gbm_dri_device_extensions[] = { - { __DRI_CORE, 1, offsetof(struct gbm_dri_device, core) }, - { __DRI_DRI2, 1, offsetof(struct gbm_dri_device, dri2) }, - { NULL, 0, 0 } -}; - -static int -dri_bind_extensions(struct gbm_dri_device *dri, - struct dri_extension_match *matches, - const __DRIextension **extensions) -{ - int i, j, ret = 0; - void *field; - - for (i = 0; extensions[i]; i++) { - for (j = 0; matches[j].name; j++) { - if (strcmp(extensions[i]->name, matches[j].name) == 0 && - extensions[i]->version >= matches[j].version) { - field = ((char *) dri + matches[j].offset); - *(const __DRIextension **) field = extensions[i]; - } - } - } - - for (j = 0; matches[j].name; j++) { - field = ((char *) dri + matches[j].offset); - if (*(const __DRIextension **) field == NULL) { - ret = -1; - } - } - - return ret; -} - -static int -dri_load_driver(struct gbm_dri_device *dri) -{ - const __DRIextension **extensions; - char path[PATH_MAX], *search_paths, *p, *next, *end; - - search_paths = NULL; - if (geteuid() == getuid()) { - /* don't allow setuid apps to use GBM_DRIVERS_PATH */ - search_paths = getenv("GBM_DRIVERS_PATH"); - } - if (search_paths == NULL) - search_paths = DEFAULT_DRIVER_DIR; - - dri->driver = NULL; - end = search_paths + strlen(search_paths); - for (p = search_paths; p < end && dri->driver == NULL; 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, dri->base.driver_name); - dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); -#endif - if (dri->driver == NULL) { - snprintf(path, sizeof path, - "%.*s/%s_dri.so", len, p, dri->base.driver_name); - dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); - if (dri->driver == NULL) - fprintf(stderr, "failed to open %s: %s\n", path, dlerror()); - } - } - - if (dri->driver == NULL) { - fprintf(stderr, "gbm: failed to open any driver (search paths %s)", - search_paths); - return -1; - } - - extensions = dlsym(dri->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - fprintf(stderr, "gbm: driver exports no extensions (%s)", dlerror()); - dlclose(dri->driver); - return -1; - } - - - if (dri_bind_extensions(dri, gbm_dri_device_extensions, extensions) < 0) { - dlclose(dri->driver); - fprintf(stderr, "failed to bind extensions\n"); - return -1; - } - - return 0; -} - -static int -dri_screen_create(struct gbm_dri_device *dri) -{ - const __DRIextension **extensions; - int ret = 0; - - dri->base.driver_name = util_drm_fd_get_screen_name(dri->base.base.fd); - printf("driver name. %s\n", dri->base.driver_name); - - ret = dri_load_driver(dri); - if (ret) { - fprintf(stderr, "failed to load driver: %s\n", dri->base.driver_name); - return ret; - }; - - dri->extensions[0] = &image_lookup_extension.base; - dri->extensions[1] = &use_invalidate.base; - dri->extensions[2] = NULL; - - if (dri->dri2 == NULL) - return -1; - - dri->screen = dri->dri2->createNewScreen(0, dri->base.base.fd, dri->extensions, - &dri->driver_configs, dri); - - extensions = dri->core->getExtensions(dri->screen); - if (dri_bind_extensions(dri, dri_core_extensions, extensions) < 0) { - ret = -1; - goto free_screen; - } - - dri->lookup_image = NULL; - dri->lookup_user_data = NULL; - - return 0; - -free_screen: - dri->core->destroyScreen(dri->screen); - - return ret; -} - -static void -gbm_dri_bo_destroy(struct gbm_bo *_bo) -{ - struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm); - struct gbm_dri_bo *bo = gbm_dri_bo(_bo); - - dri->image->destroyImage(bo->image); -} - - -/* FIXME: need __DRIimage::dupImage */ -static __DRIimage * -dri_reference_image(struct gbm_dri_device *dri, __DRIimage *orig, - uint32_t width, uint32_t height, uint32_t format, - void *user_data) -{ - __DRIimage *image; - int32_t name, pitch; - - dri->image->queryImage(orig, __DRI_IMAGE_ATTRIB_NAME, &name); - dri->image->queryImage(orig, __DRI_IMAGE_ATTRIB_STRIDE, &pitch); - - image = dri->image->createImageFromName(dri->screen, width, height, - format, name, pitch / 4, user_data); - - return image; -} - -static struct gbm_bo * -gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm, - void *egl_dpy, void *egl_img, - uint32_t width, uint32_t height, - enum gbm_bo_format format) -{ - struct gbm_dri_device *dri = gbm_dri_device(gbm); - struct gbm_dri_bo *bo; - int dri_format; - - bo = calloc(1, sizeof *bo); - if (bo == NULL) - return NULL; - - bo->base.base.gbm = gbm; - bo->base.base.width = width; - bo->base.base.height = height; - - switch (format) { - case GBM_BO_FORMAT_XRGB8888: - dri_format = __DRI_IMAGE_FORMAT_XRGB8888; - break; - case GBM_BO_FORMAT_ARGB8888: - dri_format = __DRI_IMAGE_FORMAT_ARGB8888; - break; - default: - return NULL; - } - - if (dri->lookup_image == NULL) - return NULL; - - __DRIimage *tmp = dri->lookup_image(dri->screen, egl_img, dri->lookup_user_data); - - bo->image = dri_reference_image(dri, tmp, width, height, dri_format, bo); - if (bo->image == NULL) - return NULL; - - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, - &bo->base.base.handle.s32); - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, - (int *) &bo->base.base.pitch); - - return &bo->base.base; -} - -static struct gbm_bo * -gbm_dri_bo_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - enum gbm_bo_format format, uint32_t usage) -{ - struct gbm_dri_device *dri = gbm_dri_device(gbm); - struct gbm_dri_bo *bo; - int dri_format; - unsigned dri_use = 0; - - bo = calloc(1, sizeof *bo); - if (bo == NULL) - return NULL; - - bo->base.base.gbm = gbm; - bo->base.base.width = width; - bo->base.base.height = height; - - switch (format) { - case GBM_BO_FORMAT_XRGB8888: - dri_format = __DRI_IMAGE_FORMAT_XRGB8888; - break; - case GBM_BO_FORMAT_ARGB8888: - dri_format = __DRI_IMAGE_FORMAT_ARGB8888; - break; - default: - return NULL; - } - - if (usage & GBM_BO_USE_SCANOUT) - dri_use |= __DRI_IMAGE_USE_SCANOUT; -#if 0 - if (usage & GBM_BO_USE_CURSOR_64X64) - dri_use = |= __DRI_IMAGE_USE_CURSOR_64X64; -#endif - - bo->image = - dri->image->createImage(dri->screen, - width, height, - dri_format, dri_use, - bo); - if (bo->image == NULL) - return NULL; - - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, - &bo->base.base.handle.s32); - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, - (int *) &bo->base.base.pitch); - - return &bo->base.base; -} - -static void -dri_destroy(struct gbm_device *gbm) -{ - struct gbm_dri_device *dri = gbm_dri_device(gbm); - //int i; - - dri->core->destroyScreen(dri->screen); -#if 0 - for (i = 0; dri->driver_configs[i]; ++i) - free(dri->driver_configs[i]); -#endif - free(dri->driver_configs); - dlclose(dri->driver); - free(dri->base.driver_name); - - free(dri); -} - -struct gbm_device * -dri_device_create(int fd) -{ - struct gbm_dri_device *dri; - int ret; - - dri = calloc(1, sizeof *dri); - - dri->base.base.fd = fd; - dri->base.base.bo_create = gbm_dri_bo_create; - dri->base.base.bo_create_from_egl_image = gbm_dri_bo_create_from_egl_image; - dri->base.base.bo_destroy = gbm_dri_bo_destroy; - dri->base.base.destroy = dri_destroy; - - dri->base.type = GBM_DRM_DRIVER_TYPE_DRI; - dri->base.base.name = "drm"; - - ret = dri_screen_create(dri); - if (ret) { - free(dri); - return NULL; - } - - return &dri->base.base; -} diff --git a/src/gbm/dri_internal.h b/src/gbm/dri_internal.h deleted file mode 100644 index a065a3c416..0000000000 --- a/src/gbm/dri_internal.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _GBM_DRI_INTERNAL_H_ -#define _GBM_DRI_INTERNAL_H_ - -#include "internal.h" - -#include "common.h" -#include "common_drm.h" - -struct gbm_dri_device { - struct gbm_drm_device base; - - void *driver; - - __DRIscreen *screen; - - __DRIcoreExtension *core; - __DRIdri2Extension *dri2; - __DRIimageExtension *image; - - const __DRIconfig **driver_configs; - const __DRIextension *extensions[3]; - - __DRIimage *(*lookup_image)(__DRIscreen *screen, void *image, void *data); - void *lookup_user_data; -}; - -struct gbm_dri_bo { - struct gbm_drm_bo base; - - __DRIimage *image; -}; - -static inline struct gbm_dri_device * -gbm_dri_device(struct gbm_device *gbm) -{ - return (struct gbm_dri_device *) gbm; -} - -static inline struct gbm_dri_bo * -gbm_dri_bo(struct gbm_bo *bo) -{ - return (struct gbm_dri_bo *) bo; -} - -#endif diff --git a/src/gbm/gallium_drm.c b/src/gbm/gallium_drm.c deleted file mode 100644 index 19bc6a9a14..0000000000 --- a/src/gbm/gallium_drm.c +++ /dev/null @@ -1,357 +0,0 @@ -#include - -#define EGL_EGLEXT_PROTOTYPES -#include "EGL/egl.h" -#include "EGL/eglext.h" - -#include "util/u_memory.h" -#include "util/u_string.h" -#include "util/u_dl.h" -#include "util/u_inlines.h" -#include "util/u_drm_screen.h" - -#include "state_tracker/drm_driver.h" - -#include -#include - -#include "gallium_drm_internal.h" - -static struct pipe_module { - boolean initialized; - char *name; - struct util_dl_library *lib; - const struct drm_driver_descriptor *drmdd; -} pipe_modules[16]; - -static char * -loader_strdup(const char *s) -{ - size_t len = (s) ? strlen(s) : 0; - char *t = MALLOC(len + 1); - if (t) { - memcpy(t, s, len); - t[len] = '\0'; - } - return t; -} - -static void -find_pipe_module(struct pipe_module *pmod, const char *name) -{ - char *search_paths, *end, *next, *p; - char path[PATH_MAX]; - int ret; - - search_paths = NULL; - if (geteuid() == getuid()) { - /* don't allow setuid apps to use EGL_DRIVERS_PATH */ - search_paths = getenv("EGL_DRIVERS_PATH"); - } - if (search_paths == NULL) - search_paths = _EGL_GALLIUM_DRIVER_SEARCH_DIR; - - end = search_paths + strlen(search_paths); - for (p = search_paths; p < end && pmod->lib == NULL; p = next + 1) { - int len; - next = strchr(p, ':'); - if (next == NULL) - next = end; - - len = next - p; - - if (len) { - ret = util_snprintf(path, sizeof(path), - "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, p, pmod->name); - } - else { - ret = util_snprintf(path, sizeof(path), - PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name); - } - if (ret > 0 && ret < sizeof(path)) { - pmod->lib = util_dl_open(path); -#if 0 - if (pmod->lib) - _eglLog(_EGL_DEBUG, "loaded %s", path); -#endif - } - - } -} - -static boolean -load_pipe_module(struct pipe_module *pmod, const char *name) -{ - pmod->name = loader_strdup(name); - if (!pmod->name) - return FALSE; - - find_pipe_module(pmod, name); - - if (pmod->lib) { - pmod->drmdd = (const struct drm_driver_descriptor *) - util_dl_get_proc_address(pmod->lib, "driver_descriptor"); - - /* sanity check on the name */ - if (pmod->drmdd && strcmp(pmod->drmdd->name, pmod->name) != 0) - pmod->drmdd = NULL; - - if (!pmod->drmdd) { - util_dl_close(pmod->lib); - pmod->lib = NULL; - } - } - - return (pmod->drmdd != NULL); -} - -static struct pipe_module * -get_pipe_module(const char *name) -{ - struct pipe_module *pmod = NULL; - int i; - - if (!name) - return NULL; - - for (i = 0; i < Elements(pipe_modules); i++) { - if (!pipe_modules[i].initialized || - strcmp(pipe_modules[i].name, name) == 0) { - pmod = &pipe_modules[i]; - break; - } - } - if (!pmod) - return NULL; - - if (!pmod->initialized) { - load_pipe_module(pmod, name); - pmod->initialized = TRUE; - } - - return pmod; -} - -static struct pipe_screen * -create_drm_screen(const char *name, int fd) -{ - struct pipe_module *pmod = get_pipe_module(name); - - return (pmod && pmod->drmdd && pmod->drmdd->create_screen) ? - pmod->drmdd->create_screen(fd) : NULL; -} - - - - - - - - - - -static int -gallium_screen_create(struct gbm_gallium_drm_device *gdrm) -{ - gdrm->base.driver_name = util_drm_fd_get_screen_name(gdrm->base.base.fd); - printf("driver name. %s\n", gdrm->base.driver_name); - - gdrm->screen = create_drm_screen(gdrm->base.driver_name, gdrm->base.base.fd); - if (gdrm->screen == NULL) { - fprintf(stderr, "failed to load driver: %s\n", gdrm->base.driver_name); - return -1; - }; - - return 0; -} - -static void -gbm_gallium_drm_bo_destroy(struct gbm_bo *_bo) -{ - struct gbm_gallium_drm_bo *bo = gbm_gallium_drm_bo(_bo); - - pipe_resource_reference(&bo->resource, NULL); -} - -static struct gbm_bo * -gbm_gallium_drm_bo_create_from_egl_image(struct gbm_device *gbm, - void *egl_dpy, void *egl_image, - uint32_t width, uint32_t height, - enum gbm_bo_format format) -{ - struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); - struct gbm_gallium_drm_bo *bo; - struct pipe_resource templ; - struct winsys_handle whandle; - uint resource_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; - enum pipe_format pf; - - int32_t name, pitch; - - eglExportDRMImageMESA(egl_dpy, egl_image, &name, NULL, &pitch); - - bo = CALLOC_STRUCT(gbm_gallium_drm_bo); - if (bo == NULL) - return NULL; - - bo->base.base.gbm = gbm; - bo->base.base.width = width; - bo->base.base.height = height; - - switch (format) { - case GBM_BO_FORMAT_XRGB8888: - pf = PIPE_FORMAT_B8G8R8X8_UNORM; - break; - case GBM_BO_FORMAT_ARGB8888: - pf = PIPE_FORMAT_B8G8R8A8_UNORM; - break; - default: - return NULL; - } - - memset(&templ, 0, sizeof(templ)); - templ.bind = resource_usage; - templ.format = pf; - templ.target = PIPE_TEXTURE_2D; - templ.last_level = 0; - templ.width0 = width; - templ.height0 = height; - templ.depth0 = 1; - templ.array_size = 1; - - memset(&whandle, 0, sizeof(whandle)); - whandle.type = DRM_API_HANDLE_TYPE_SHARED; - whandle.handle = name; - whandle.stride = pitch; - - bo->resource = gdrm->screen->resource_from_handle(gdrm->screen, &templ, &whandle); - if (bo->resource == NULL) { - FREE(bo); - return NULL; - } - - memset(&whandle, 0, sizeof(whandle)); - whandle.type = DRM_API_HANDLE_TYPE_KMS; - gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle); - - bo->base.base.handle.u32 = whandle.handle; - bo->base.base.pitch = whandle.stride; - - return &bo->base.base; -} - -static struct gbm_bo * -gbm_gallium_drm_bo_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - enum gbm_bo_format format, uint32_t usage) -{ - struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); - struct gbm_gallium_drm_bo *bo; - struct pipe_resource templ; - struct winsys_handle whandle; - uint resource_usage = 0; - enum pipe_format pf; - - bo = CALLOC_STRUCT(gbm_gallium_drm_bo); - if (bo == NULL) - return NULL; - - bo->base.base.gbm = gbm; - bo->base.base.width = width; - bo->base.base.height = height; - - switch (format) { - case GBM_BO_FORMAT_XRGB8888: - pf = PIPE_FORMAT_B8G8R8X8_UNORM; - break; - case GBM_BO_FORMAT_ARGB8888: - pf = PIPE_FORMAT_B8G8R8A8_UNORM; - break; - default: - return NULL; - } - - if (usage & GBM_BO_USE_SCANOUT) - resource_usage |= PIPE_BIND_SCANOUT; - - if (usage & GBM_BO_USE_RENDERING) - resource_usage |= PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; - -#if 0 - if (usage & GBM_BO_USE_CURSOR_64X64) - resource_usage |= PIPE_BIND_CURSOR; -#endif - - memset(&templ, 0, sizeof(templ)); - templ.bind = resource_usage; - templ.format = pf; - templ.target = PIPE_TEXTURE_2D; - templ.last_level = 0; - templ.width0 = width; - templ.height0 = height; - templ.depth0 = 1; - templ.array_size = 1; - - bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ); - if (bo->resource == NULL) { - FREE(bo); - return NULL; - } - - memset(&whandle, 0, sizeof(whandle)); - whandle.type = DRM_API_HANDLE_TYPE_KMS; - gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle); - - bo->base.base.handle.u32 = whandle.handle; - bo->base.base.pitch = whandle.stride; - - return &bo->base.base; -} - -static boolean -pipe_modules_destroy(void) -{ - //util_dl_close - - return TRUE; -} - -static void -gbm_gallium_drm_destroy(struct gbm_device *gbm) -{ - struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); - - gdrm->screen->destroy(gdrm->screen); - - pipe_modules_destroy(); - FREE(gdrm->base.driver_name); - - FREE(gdrm); -} - -struct gbm_device * -gbm_gallium_drm_device_create(int fd) -{ - struct gbm_gallium_drm_device *dri; - int ret; - - dri = calloc(1, sizeof *dri); - - dri->base.base.fd = fd; - dri->base.base.bo_create = gbm_gallium_drm_bo_create; - dri->base.base.bo_create_from_egl_image = - gbm_gallium_drm_bo_create_from_egl_image; - dri->base.base.bo_destroy = gbm_gallium_drm_bo_destroy; - dri->base.base.destroy = gbm_gallium_drm_destroy; - - dri->base.type = GBM_DRM_DRIVER_TYPE_GALLIUM; - dri->base.base.name = "drm"; - - ret = gallium_screen_create(dri); - if (ret) { - free(dri); - return NULL; - } - - return &dri->base.base; -} diff --git a/src/gbm/gallium_drm_internal.h b/src/gbm/gallium_drm_internal.h deleted file mode 100644 index 7f9bc081ae..0000000000 --- a/src/gbm/gallium_drm_internal.h +++ /dev/null @@ -1,37 +0,0 @@ - -#ifndef _GBM_GALLIUM_DRM_INTERNAL_H_ -#define _GBM_GALLIUM_DRM_INTERNAL_H_ - -#include "pipe/p_state.h" - -#include "internal.h" - -#include "common.h" -#include "common_drm.h" - -struct gbm_gallium_drm_device { - struct gbm_drm_device base; - - struct pipe_screen *screen; - void *driver; -}; - -struct gbm_gallium_drm_bo { - struct gbm_drm_bo base; - - struct pipe_resource *resource; -}; - -static inline struct gbm_gallium_drm_device * -gbm_gallium_drm_device(struct gbm_device *gbm) -{ - return (struct gbm_gallium_drm_device *) gbm; -} - -static inline struct gbm_gallium_drm_bo * -gbm_gallium_drm_bo(struct gbm_bo *bo) -{ - return (struct gbm_gallium_drm_bo *) bo; -} - -#endif diff --git a/src/gbm/gbm.h b/src/gbm/gbm.h deleted file mode 100644 index 9200ca5ae5..0000000000 --- a/src/gbm/gbm.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef _GBM_H_ -#define _GBM_H_ - -#include - -struct gbm_device; -struct gbm_bo; - -union gbm_bo_handle { - void *ptr; - int32_t s32; - uint32_t u32; - int64_t s64; - uint64_t u64; -}; - -enum gbm_bo_format { - GBM_BO_FORMAT_XRGB8888, - GBM_BO_FORMAT_ARGB8888, -}; - -enum gbm_bo_flags { - GBM_BO_USE_SCANOUT = (1 << 0), - GBM_BO_USE_CURSOR_64X64 = (1 << 1), - GBM_BO_USE_RENDERING = (1 << 2), -}; - -int -gbm_device_get_fd(struct gbm_device *gbm); - -const char * -gbm_device_get_backend_name(struct gbm_device *gbm); - -int -gbm_device_is_fromat_supported(struct gbm_device *gbm, - enum gbm_bo_format format, - uint32_t usage); - -void -gbm_device_destroy(struct gbm_device *gbm); - -struct gbm_device * -gbm_device_create(int fd); - -struct gbm_bo * -gbm_bo_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - enum gbm_bo_format format, uint32_t flags); - -struct gbm_bo * -gbm_bo_create_from_egl_image(struct gbm_device *gbm, - void *egl_dpy, void *egl_img, - uint32_t width, uint32_t height, - enum gbm_bo_format format); - -uint32_t -gbm_bo_get_width(struct gbm_bo *bo); - -uint32_t -gbm_bo_get_height(struct gbm_bo *bo); - -uint32_t -gbm_bo_get_pitch(struct gbm_bo *bo); - -union gbm_bo_handle -gbm_bo_get_handle(struct gbm_bo *bo); - -#if 0 -int -gbm_bo_map(struct gbm_bo *bo, void **out); -int -gbm_bo_unmap(struct gbm_bo *bo); -#endif - -void -gbm_bo_destroy(struct gbm_bo *bo); - -#endif diff --git a/src/gbm/internal.h b/src/gbm/internal.h deleted file mode 100644 index 0ceef265e8..0000000000 --- a/src/gbm/internal.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef INTERNAL_H_ -#define INTERNAL_H_ - -#include "gbm.h" - -/* GCC visibility */ -#if defined(__GNUC__) && __GNUC__ >= 4 -#define GBM_EXPORT __attribute__ ((visibility("default"))) -#else -#define GBM_EXPORT -#endif - -struct gbm_device { - /* Hack to make a gbm_device detectable by its first element. */ - struct gbm_device *(*dummy)(int); - - int fd; - const char *name; - - void (*destroy)(struct gbm_device *gbm); - - struct gbm_bo *(*bo_create)(struct gbm_device *gbm, - uint32_t width, uint32_t height, - enum gbm_bo_format format, - uint32_t usage); - - struct gbm_bo *(*bo_create_from_egl_image)(struct gbm_device *gbm, - void *egl_dpy, void *egl_img, - uint32_t width, uint32_t height, - enum gbm_bo_format format); - -#if 0 - int (*bo_map)(struct gbm_bo *bo, void **out); - int (*bo_unmap)(struct gbm_bo *bo); -#endif - void (*bo_destroy)(struct gbm_bo *bo); -}; - -struct gbm_bo { - struct gbm_device *gbm; - uint32_t width; - uint32_t height; - uint32_t pitch; - union gbm_bo_handle handle; -}; - -struct gbm_device * -dri_device_create(int fd); - -struct gbm_device * -gbm_gallium_drm_device_create(int fd); - -#endif diff --git a/src/gbm/main/Makefile b/src/gbm/main/Makefile new file mode 100644 index 0000000000..08877ef2b5 --- /dev/null +++ b/src/gbm/main/Makefile @@ -0,0 +1,71 @@ +# src/gbm/main/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + +INCLUDE_DIRS = -I$(TOP)/include + +HEADERS = \ + common.h \ + module.h \ + internal.h \ + gbm.h + +SOURCES = \ + api.c \ + module.c \ + common.c + +OBJECTS = $(SOURCES:.c=.o) + +# use dl*() to load drivers +LOCAL_CFLAGS = -D_OS_UNIX=1 $(LIBUDEV_CFLAGS) $(DLOPEN_CFLAGS) -DMODULEDIR='"$(GBM_BACKEND_INSTALL_DIR)"' +LOCAL_LIBS = + +GBM_LIB_DEPS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ + + +default: depend library + + +library: $(TOP)/$(LIB_DIR)/libgbm.so + +$(TOP)/$(LIB_DIR)/libgbm.so: $(OBJECTS) $(LOCAL_LIBS) + $(MKLIB) -o gbm -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -major 1 -minor 0 \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + -L$(TOP)/$(LIB_DIR) $(GBM_LIB_DEPS) \ + $(OBJECTS) $(LOCAL_LIBS) + +install-headers: + $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/ + $(INSTALL) -m 644 $(TOP)/src/gbm/main/gbm.h \ + $(DESTDIR)$(INSTALL_INC_DIR) + + +PKG_CONFIG_DIR = $(INSTALL_LIB_DIR)/pkgconfig + + +install: default install-headers + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libgbm.so* \ + $(DESTDIR)$(INSTALL_LIB_DIR) + +clean: + -rm -f *.o + -rm -f depend depend.bak + + +depend: $(SOURCES) $(HEADERS) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \ + $(SOURCES) $(HEADERS) > /dev/null 2>/dev/null + + +-include depend +# DO NOT DELETE diff --git a/src/gbm/main/api.c b/src/gbm/main/api.c new file mode 100644 index 0000000000..24e8c5615c --- /dev/null +++ b/src/gbm/main/api.c @@ -0,0 +1,102 @@ +#include +#include + +#include "gbm.h" +#include "internal.h" +#include "module.h" + +GBM_EXPORT int +gbm_device_get_fd(struct gbm_device *gbm) +{ + return gbm->fd; +} + +/* FIXME: maybe superfluous, use udev subclass from the fd? */ +GBM_EXPORT const char * +gbm_device_get_backend_name(struct gbm_device *gbm) +{ + return gbm->name; +} + +GBM_EXPORT void +gbm_device_destroy(struct gbm_device *gbm) +{ + gbm->destroy(gbm); +} + +GBM_EXPORT struct gbm_device * +gbm_device_create(int fd) +{ + struct gbm_device *gbm; + + //gbm = dri_device_create(fd); + //gbm = gbm_gallium_drm_device_create(fd); + struct gbm_backend *backend = find_backend(fd); + gbm = backend->create_device(fd); + if (gbm == NULL) + return NULL; + + gbm->dummy = gbm_device_create; + + return gbm; +} + +GBM_EXPORT unsigned int +gbm_bo_get_width(struct gbm_bo *bo) +{ + return bo->width; +} + +GBM_EXPORT unsigned int +gbm_bo_get_height(struct gbm_bo *bo) +{ + return bo->height; +} + +GBM_EXPORT uint32_t +gbm_bo_get_pitch(struct gbm_bo *bo) +{ + return bo->pitch; +} + +GBM_EXPORT union gbm_bo_handle +gbm_bo_get_handle(struct gbm_bo *bo) +{ + return bo->handle; +} + +GBM_EXPORT void +gbm_bo_destroy(struct gbm_bo *bo) +{ + bo->gbm->bo_destroy(bo); +} + +GBM_EXPORT struct gbm_bo * +gbm_bo_create(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, uint32_t usage) +{ + if (width == 0 || height == 0) + return NULL; + + /* XXX sanity check type */ + + if (usage & GBM_BO_USE_CURSOR_64X64 && + (width != 64 || height != 64)) + return NULL; + + return gbm->bo_create(gbm, width, height, format, usage); +} + +GBM_EXPORT struct gbm_bo * +gbm_bo_create_from_egl_image(struct gbm_device *gbm, + void *egl_dpy, void *egl_image, + uint32_t width, uint32_t height, + enum gbm_bo_format format) +{ + if (width == 0 || height == 0) + return NULL; + + return gbm->bo_create_from_egl_image(gbm, egl_dpy, egl_image, + width, height, format); +} diff --git a/src/gbm/main/common.c b/src/gbm/main/common.c new file mode 100644 index 0000000000..9c5aac94fd --- /dev/null +++ b/src/gbm/main/common.c @@ -0,0 +1,54 @@ +#include +#include + +#include +#include +#include +#include + +#include "common.h" + +struct udev_device * +_udev_device_new_from_fd(struct udev *udev, int fd) +{ + struct udev_device *device; + struct stat buf; + + if (fstat(fd, &buf) < 0) { + fprintf(stderr, "gbm: failed to stat fd %d", fd); + return NULL; + } + + device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev); + if (device == NULL) { + fprintf(stderr, + "gbm: could not create udev device for fd %d", fd); + return NULL; + } + + return device; +} + +char * +fd_get_device_name(int fd) +{ + struct udev *udev; + struct udev_device *device; + char *device_name; + + udev = udev_new(); + device = _udev_device_new_from_fd(udev, fd); + if (device == NULL) + return NULL; + + device_name = (char *) udev_device_get_devnode(device); + if (!device_name) + goto out; + device_name = strdup(device_name); + +out: + udev_device_unref(device); + udev_unref(udev); + + return device_name; +} diff --git a/src/gbm/main/common.h b/src/gbm/main/common.h new file mode 100644 index 0000000000..ee33e972bb --- /dev/null +++ b/src/gbm/main/common.h @@ -0,0 +1,12 @@ +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include + +struct udev_device * +_udev_device_new_from_fd(struct udev *udev, int fd); + +char * +fd_get_device_name(int fd); + +#endif diff --git a/src/gbm/main/common_drm.h b/src/gbm/main/common_drm.h new file mode 100644 index 0000000000..44985c42aa --- /dev/null +++ b/src/gbm/main/common_drm.h @@ -0,0 +1,21 @@ +#ifndef _COMMON_DRM_H_ +#define _COMMON_DRM_H_ + +#include "internal.h" + +enum gbm_drm_driver_type { + GBM_DRM_DRIVER_TYPE_DRI, + GBM_DRM_DRIVER_TYPE_GALLIUM, +}; + +struct gbm_drm_device { + struct gbm_device base; + enum gbm_drm_driver_type type; + char *driver_name; +}; + +struct gbm_drm_bo { + struct gbm_bo base; +}; + +#endif diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h new file mode 100644 index 0000000000..9200ca5ae5 --- /dev/null +++ b/src/gbm/main/gbm.h @@ -0,0 +1,78 @@ +#ifndef _GBM_H_ +#define _GBM_H_ + +#include + +struct gbm_device; +struct gbm_bo; + +union gbm_bo_handle { + void *ptr; + int32_t s32; + uint32_t u32; + int64_t s64; + uint64_t u64; +}; + +enum gbm_bo_format { + GBM_BO_FORMAT_XRGB8888, + GBM_BO_FORMAT_ARGB8888, +}; + +enum gbm_bo_flags { + GBM_BO_USE_SCANOUT = (1 << 0), + GBM_BO_USE_CURSOR_64X64 = (1 << 1), + GBM_BO_USE_RENDERING = (1 << 2), +}; + +int +gbm_device_get_fd(struct gbm_device *gbm); + +const char * +gbm_device_get_backend_name(struct gbm_device *gbm); + +int +gbm_device_is_fromat_supported(struct gbm_device *gbm, + enum gbm_bo_format format, + uint32_t usage); + +void +gbm_device_destroy(struct gbm_device *gbm); + +struct gbm_device * +gbm_device_create(int fd); + +struct gbm_bo * +gbm_bo_create(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, uint32_t flags); + +struct gbm_bo * +gbm_bo_create_from_egl_image(struct gbm_device *gbm, + void *egl_dpy, void *egl_img, + uint32_t width, uint32_t height, + enum gbm_bo_format format); + +uint32_t +gbm_bo_get_width(struct gbm_bo *bo); + +uint32_t +gbm_bo_get_height(struct gbm_bo *bo); + +uint32_t +gbm_bo_get_pitch(struct gbm_bo *bo); + +union gbm_bo_handle +gbm_bo_get_handle(struct gbm_bo *bo); + +#if 0 +int +gbm_bo_map(struct gbm_bo *bo, void **out); +int +gbm_bo_unmap(struct gbm_bo *bo); +#endif + +void +gbm_bo_destroy(struct gbm_bo *bo); + +#endif diff --git a/src/gbm/main/internal.h b/src/gbm/main/internal.h new file mode 100644 index 0000000000..6f0d4f1f16 --- /dev/null +++ b/src/gbm/main/internal.h @@ -0,0 +1,63 @@ +#ifndef INTERNAL_H_ +#define INTERNAL_H_ + +#include "gbm.h" + +/* GCC visibility */ +#if defined(__GNUC__) && __GNUC__ >= 4 +#define GBM_EXPORT __attribute__ ((visibility("default"))) +#else +#define GBM_EXPORT +#endif + +struct gbm_device { + /* Hack to make a gbm_device detectable by its first element. */ + struct gbm_device *(*dummy)(int); + + int fd; + const char *name; + + void (*destroy)(struct gbm_device *gbm); + + struct gbm_bo *(*bo_create)(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, + uint32_t usage); + + struct gbm_bo *(*bo_create_from_egl_image)(struct gbm_device *gbm, + void *egl_dpy, void *egl_img, + uint32_t width, uint32_t height, + enum gbm_bo_format format); + +#if 0 + int (*bo_map)(struct gbm_bo *bo, void **out); + int (*bo_unmap)(struct gbm_bo *bo); +#endif + void (*bo_destroy)(struct gbm_bo *bo); +}; + +struct gbm_bo { + struct gbm_device *gbm; + uint32_t width; + uint32_t height; + uint32_t pitch; + union gbm_bo_handle handle; +}; + + +struct gbm_backend { + const char *class_name; + const char *backend_name; + int (*probe)(int fd); + struct gbm_device *(*create_device)(int fd); +}; + +#if 0 +struct gbm_device * +dri_device_create(int fd); + +struct gbm_device * +gbm_gallium_drm_device_create(int fd); +#endif + +#endif diff --git a/src/gbm/main/module.c b/src/gbm/main/module.c new file mode 100644 index 0000000000..0a7b37adb1 --- /dev/null +++ b/src/gbm/main/module.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + +#include "module.h" + +static void * +load_module(const char *name, const char *entrypoint) +{ + char path[PATH_MAX]; + void *module, *init; + + if (name[0] != '/') + snprintf(path, sizeof path, MODULEDIR "/%s", name); + else + snprintf(path, sizeof path, "%s", name); + + module = dlopen(path, RTLD_LAZY); + if (!module) { + fprintf(stderr, + "failed to load module: %s\n", dlerror()); + return NULL; + } + + init = dlsym(module, entrypoint); + if (!init) + return NULL; + + return init; +} + +static const char *backends[] = { + "gbm_dri.so", + "gbm_gallium_drm.so", +}; + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) + +struct gbm_backend * +find_backend(int fd) +{ + struct gbm_backend *backend = NULL; + int i; + const char *b; + + b = getenv("GBM_BACKEND"); + if (b) + backend = load_module(b, "gbm_backend"); + + for (i = 0; i < ARRAY_SIZE(backends) && backend == NULL; ++i) { + backend = load_module(backends[i], "gbm_backend"); + if (backend && backend->probe(fd) == 0) + break; + else + backend = NULL; + } + + return backend; +} diff --git a/src/gbm/main/module.h b/src/gbm/main/module.h new file mode 100644 index 0000000000..591062a93d --- /dev/null +++ b/src/gbm/main/module.h @@ -0,0 +1,9 @@ +#ifndef MODULE_H_ +#define MODULE_H_ + +#include "internal.h" + +struct gbm_backend * +find_backend(int fd); + +#endif -- cgit v1.2.3