summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-05-03 13:33:42 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-05-16 10:43:15 +0200
commit701d8889414fd4e0075990ba70629b90f56c0bab (patch)
tree5351468fcc9de646e4e8745a13b437c03d4cd679
parent34e3dc461753cba213ef16a17c6d59d6fe9c0558 (diff)
wip: gbm gallium backend
-rw-r--r--src/gallium/auxiliary/Makefile1
-rw-r--r--src/gallium/state_trackers/egl/Makefile2
-rw-r--r--src/gallium/state_trackers/egl/drm/modeset.c36
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.c42
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.h4
-rw-r--r--src/gbm/Makefile19
-rw-r--r--src/gbm/api.c3
-rw-r--r--src/gbm/gallium_drm.c285
-rw-r--r--src/gbm/gallium_drm_internal.h37
-rw-r--r--src/gbm/internal.h2
-rw-r--r--src/gbm/test.c4
11 files changed, 413 insertions, 22 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 2be4509b7a..dc77f75ca3 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -109,6 +109,7 @@ C_SOURCES = \
util/u_dl.c \
util/u_draw.c \
util/u_draw_quad.c \
+ util/u_drm_screen.c \
util/u_format.c \
util/u_format_other.c \
util/u_format_latc.c \
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index 763e7b58a4..7ced8d3c50 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)
+drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm) -I$(TOP)/src/
drm_SOURCES = $(wildcard drm/*.c)
drm_OBJECTS = $(drm_SOURCES:.c=.o)
diff --git a/src/gallium/state_trackers/egl/drm/modeset.c b/src/gallium/state_trackers/egl/drm/modeset.c
index 3fff954090..73968d1343 100644
--- a/src/gallium/state_trackers/egl/drm/modeset.c
+++ b/src/gallium/state_trackers/egl/drm/modeset.c
@@ -290,6 +290,42 @@ drm_display_create_surface(struct native_display *ndpy,
return drmsurf;
}
+struct native_surface *
+drm_display_create_surface_from_resource(struct native_display *ndpy,
+ struct pipe_resource *resource)
+{
+ struct drm_display *drmdpy = drm_display(ndpy);
+ struct drm_surface *drmsurf;
+ enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+ drmsurf = CALLOC_STRUCT(drm_surface);
+ if (!drmsurf)
+ return NULL;
+
+ drmsurf->drmdpy = drmdpy;
+ drmsurf->color_format = resource->format;
+ drmsurf->width = resource->width0;
+ drmsurf->height = resource->height0;
+ drmsurf->have_pageflip = FALSE;
+
+ drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
+ drmsurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+
+ resource_surface_import_resource(drmsurf->rsurf, natt, resource);
+
+ drmsurf->base.destroy = drm_surface_destroy;
+ drmsurf->base.present = drm_surface_present;
+ drmsurf->base.validate = drm_surface_validate;
+ drmsurf->base.wait = drm_surface_wait;
+
+ return &drmsurf->base;
+}
+
+
/**
* Choose a CRTC that supports all given connectors.
*/
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c
index c89a6d4767..7233370158 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.c
+++ b/src/gallium/state_trackers/egl/drm/native_drm.c
@@ -37,6 +37,8 @@
#include <radeon_drm.h>
#include "radeon/drm/radeon_drm_public.h"
+#include "gbm/gallium_drm_internal.h"
+
#ifdef HAVE_LIBUDEV
#include <libudev.h>
#endif
@@ -140,6 +142,7 @@ drm_display_destroy(struct native_display *ndpy)
FREE(drmdpy);
}
+#if 0
static const char *
get_drm_screen_name(int fd, drmVersionPtr version)
{
@@ -191,6 +194,7 @@ drm_display_init_screen(struct native_display *ndpy)
return TRUE;
}
+#endif
static struct pipe_resource *
drm_display_import_buffer(struct native_display *ndpy,
@@ -310,9 +314,19 @@ static struct native_display_wayland_bufmgr drm_display_wayland_bufmgr = {
#endif /* HAVE_WAYLAND_BACKEND */
+static struct native_surface *
+drm_create_pixmap_surface(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct gbm_gallium_drm_bo *bo = (void *) pix;
+
+ return drm_display_create_surface_from_resource(ndpy, bo->resource);
+}
+
static struct native_display *
-drm_create_display(int fd, struct native_event_handler *event_handler,
- void *user_data)
+drm_create_display(struct gbm_gallium_drm_device *gbmdrm,
+ struct native_event_handler *event_handler, void *user_data)
{
struct drm_display *drmdpy;
@@ -320,20 +334,20 @@ drm_create_display(int fd, struct native_event_handler *event_handler,
if (!drmdpy)
return NULL;
- drmdpy->fd = fd;
+ drmdpy->fd = gbmdrm->base.base.fd;
drmdpy->device_name = drm_get_device_name(fd);
+
drmdpy->event_handler = event_handler;
drmdpy->base.user_data = user_data;
- if (!drm_display_init_screen(&drmdpy->base)) {
- drm_display_destroy(&drmdpy->base);
- return NULL;
- }
+ drmdpy->base.screen = gbmdrm->screen;
drmdpy->base.destroy = drm_display_destroy;
drmdpy->base.get_param = drm_display_get_param;
drmdpy->base.get_configs = drm_display_get_configs;
+ drmdpy->base.create_pixmap_surface = drm_create_pixmap_surface;
+
drmdpy->base.buffer = &drm_display_buffer;
#ifdef HAVE_WAYLAND_BACKEND
if (drmdpy->device_name)
@@ -355,18 +369,20 @@ native_set_event_handler(struct native_event_handler *event_handler)
static struct native_display *
native_create_display(void *dpy, boolean use_sw, void *user_data)
{
+ struct gbm_gallium_drm_device *gbm;
int fd;
- if (dpy) {
- fd = dup((int) pointer_to_intptr(dpy));
- }
- else {
+ gbm = dpy;
+
+ if (gbm == NULL) {
fd = open("/dev/dri/card0", O_RDWR);
+ gbm = gbm_gallium_drm_device(gbm_device_create(fd));
}
- if (fd < 0)
+
+ if (gbm == NULL)
return NULL;
- return drm_create_display(fd, drm_event_handler, user_data);
+ return drm_create_display(gbm, drm_event_handler, user_data);
}
static const struct native_platform drm_platform = {
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h
index 41cdc4f9d0..f938edeada 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.h
+++ b/src/gallium/state_trackers/egl/drm/native_drm.h
@@ -154,4 +154,8 @@ drm_display_init_modeset(struct native_display *ndpy);
void
drm_display_fini_modeset(struct native_display *ndpy);
+struct native_surface *
+drm_display_create_surface_from_resource(struct native_display *ndpy,
+ struct pipe_resource *resource);
+
#endif /* _NATIVE_DRM_H_ */
diff --git a/src/gbm/Makefile b/src/gbm/Makefile
index 78c60eb5ed..173374f82d 100644
--- a/src/gbm/Makefile
+++ b/src/gbm/Makefile
@@ -3,7 +3,11 @@
TOP = ../..
include $(TOP)/configs/current
-INCLUDE_DIRS = -I$(TOP)/include
+PIPE_PREFIX := pipe_
+
+INCLUDE_DIRS = -I$(TOP)/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/include
HEADERS = \
common.h \
@@ -15,18 +19,25 @@ SOURCES = \
api.c \
common.c \
common_drm.c \
- dri.c
+ dri.c \
+ gallium_drm.c
OBJECTS = $(SOURCES:.c=.o)
# use dl*() to load drivers
LOCAL_CFLAGS = -D_OS_UNIX=1 $(LIBDRM_CFLAGS) $(LIBUDEV_CFLAGS) $(DLOPEN_CFLAGS)
-LOCAL_LIBS =
+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)\"
+ -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 $@
diff --git a/src/gbm/api.c b/src/gbm/api.c
index fab261213a..b144cdace9 100644
--- a/src/gbm/api.c
+++ b/src/gbm/api.c
@@ -28,7 +28,8 @@ gbm_device_create(int fd)
{
struct gbm_device *gbm;
- gbm = dri_device_create(fd);
+ //gbm = dri_device_create(fd);
+ gbm = gbm_gallium_drm_device_create(fd);
if (gbm == NULL)
return NULL;
diff --git a/src/gbm/gallium_drm.c b/src/gbm/gallium_drm.c
new file mode 100644
index 0000000000..71c8a5a567
--- /dev/null
+++ b/src/gbm/gallium_drm.c
@@ -0,0 +1,285 @@
+#include <limits.h>
+
+#include "util/u_memory.h"
+#include "util/u_string.h"
+#include "util/u_dl.h"
+#include "util/u_inlines.h"
+
+#include "state_tracker/drm_driver.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#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 gbm_gallium_drmVERS_PATH */
+ search_paths = getenv("gbm_gallium_drmVERS_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;
+
+ //_eglSearchPathForEach(dlopen_pipe_module_cb, (void *) pmod);
+
+ 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 = drm_fd_get_driver(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(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_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
new file mode 100644
index 0000000000..7f9bc081ae
--- /dev/null
+++ b/src/gbm/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/internal.h b/src/gbm/internal.h
index d70aff9b1b..c0fcc48001 100644
--- a/src/gbm/internal.h
+++ b/src/gbm/internal.h
@@ -43,6 +43,6 @@ struct gbm_device *
dri_device_create(int fd);
struct gbm_device *
-gallium_drm_device_create(int fd);
+gbm_gallium_drm_device_create(int fd);
#endif
diff --git a/src/gbm/test.c b/src/gbm/test.c
index d1b81199d2..83fa561208 100644
--- a/src/gbm/test.c
+++ b/src/gbm/test.c
@@ -18,7 +18,7 @@ int main(void)
if (fd == -1)
return 1;
- gbm = gbm_create(fd);
+ gbm = gbm_device_create(fd);
if (gbm == NULL)
return 1;
else
@@ -27,7 +27,7 @@ int main(void)
bo = gbm_bo_create(gbm, 250, 250, GBM_BO_FORMAT_XRGB8888,
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
- gbm_destroy(gbm);
+ gbm_device_destroy(gbm);
close(fd);