[Mesa-dev] [PATCH 05/10] gbm: Add a native intel backend

Ander Conselvan de Oliveira conselvan2 at gmail.com
Fri Apr 4 01:36:23 PDT 2014


From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>

---
 src/gbm/Makefile.am                |  14 +-
 src/gbm/backends/intel/gbm_intel.c | 258 +++++++++++++++++++++++++++++++++++++
 src/gbm/backends/intel/gbm_intel.h |  74 +++++++++++
 src/gbm/main/backend.c             |   2 +
 src/gbm/main/common_drm.h          |   1 +
 5 files changed, 347 insertions(+), 2 deletions(-)
 create mode 100644 src/gbm/backends/intel/gbm_intel.c
 create mode 100644 src/gbm/backends/intel/gbm_intel.h

diff --git a/src/gbm/Makefile.am b/src/gbm/Makefile.am
index ea06ce1..b53a68d 100644
--- a/src/gbm/Makefile.am
+++ b/src/gbm/Makefile.am
@@ -49,6 +49,16 @@ libgbm_la_LIBADD += \
 	libgbm_dri.la $(top_builddir)/src/mapi/shared-glapi/libglapi.la $(LIBDRM_LIBS)
 endif
 
-TESTS = gbm-symbols-check
+if HAVE_I965_DRI
+noinst_LTLIBRARIES = libgbm_intel.la
+libgbm_intel_la_SOURCES = \
+	backends/intel/gbm_intel.c
+
+libgbm_intel_la_CFLAGS = \
+	$(AM_CFLAGS) $(INTEL_CFLAGS)
+
+libgbm_la_LIBADD += \
+	libgbm_intel.la $(INTEL_LIBS)
+endif
 
-include $(top_srcdir)/install-lib-links.mk
+TESTS = gbm-symbols-check
diff --git a/src/gbm/backends/intel/gbm_intel.c b/src/gbm/backends/intel/gbm_intel.c
new file mode 100644
index 0000000..2e7ced3
--- /dev/null
+++ b/src/gbm/backends/intel/gbm_intel.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright © 2011-2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "gbm_intel.h"
+
+#include "gbmint.h"
+
+static int
+gbm_intel_is_format_supported(struct gbm_device *gbm,
+                            uint32_t format,
+                            uint32_t usage)
+{
+   switch (format) {
+   case GBM_BO_FORMAT_XRGB8888:
+   case GBM_FORMAT_XRGB8888:
+      break;
+   case GBM_BO_FORMAT_ARGB8888:
+   case GBM_FORMAT_ARGB8888:
+      if (usage & GBM_BO_USE_SCANOUT)
+         return 0;
+      break;
+   default:
+      return 0;
+   }
+
+   if (usage & GBM_BO_USE_CURSOR_64X64 &&
+       usage & GBM_BO_USE_RENDERING)
+      return 0;
+
+   return 1;
+}
+
+static int
+gbm_intel_bo_write(struct gbm_bo *bo, const void *buf, size_t count)
+{
+   struct gbm_intel_bo *ibo = gbm_intel_bo(bo);
+   int ret;
+
+   ret = drm_intel_bo_map(ibo->bo, 1);
+   if (ret < 0)
+      return ret;
+
+   memcpy(ibo->bo->virtual, buf, count);
+
+   return drm_intel_bo_unmap(ibo->bo);
+}
+
+static void
+gbm_intel_bo_destroy(struct gbm_bo *_bo)
+{
+   struct gbm_intel_bo *ibo = gbm_intel_bo(_bo);
+
+   drm_intel_bo_unreference(ibo->bo);
+
+   free(ibo);
+}
+
+static inline int
+align(int value, int size)
+{
+   return (value + size - 1) & ~(size - 1);
+}
+
+static struct gbm_intel_bo *
+gbm_intel_bo_create_with_bo(struct gbm_device *gbm,
+                            uint32_t width, uint32_t height, uint32_t stride,
+                            uint32_t format, uint32_t usage,
+                            drm_intel_bo *bo)
+{
+   struct gbm_intel_bo *ibo;
+
+   ibo = calloc(1, sizeof *ibo);
+   if (!ibo)
+      return NULL;
+
+   ibo->bo = bo;
+
+   ibo->base.base.gbm = gbm;
+   ibo->base.base.width = width;
+   ibo->base.base.height = height;
+   ibo->base.base.stride = stride;
+   ibo->base.base.format = format;
+   ibo->base.base.handle.s32 = ibo->bo->handle;
+
+   return ibo;
+}
+
+static struct gbm_bo *
+gbm_intel_bo_create(struct gbm_device *gbm,
+                    uint32_t width, uint32_t height,
+                    uint32_t format, uint32_t usage)
+{
+   struct gbm_intel_device *igbm = gbm_intel_device(gbm);
+   struct gbm_intel_bo *ibo;
+   drm_intel_bo *bo;
+   uint32_t tiling;
+   unsigned long stride, flags = 0;
+
+   switch (format) {
+   case GBM_BO_FORMAT_XRGB8888:
+   case GBM_FORMAT_XRGB8888:
+   case GBM_BO_FORMAT_ARGB8888:
+   case GBM_FORMAT_ARGB8888:
+      break;
+   default:
+      return NULL;
+   }
+
+   tiling = I915_TILING_X;
+
+   if (usage & GBM_BO_USE_CURSOR_64X64) {
+      if (width != 64 || height != 64)
+         return NULL;
+      tiling = I915_TILING_NONE;
+   }
+
+   if (usage & GBM_BO_USE_RENDERING)
+      flags |= BO_ALLOC_FOR_RENDER;
+
+   bo = drm_intel_bo_alloc_tiled(igbm->bufmgr, "intel gbm",
+                                 width, height, 4, &tiling,
+                                 &stride, flags);
+   if (!bo)
+      return NULL;
+
+   ibo = gbm_intel_bo_create_with_bo(gbm, width, height, stride,
+                                     format, usage, bo);
+   if (!ibo) {
+      drm_intel_bo_unreference(bo);
+      return NULL;
+   }
+
+   return &ibo->base.base;
+}
+
+static struct gbm_bo *
+gbm_intel_bo_import(struct gbm_device *gbm,
+                  uint32_t type, void *buffer, uint32_t usage)
+{
+   return NULL;
+}
+
+static int
+gbm_intel_bo_get_fd(struct gbm_bo *bo)
+{
+   struct gbm_intel_bo *ibo = gbm_intel_bo(bo);
+   int fd, ret;
+
+   ret = drm_intel_bo_gem_export_to_prime(ibo->bo, &fd);
+   if (ret < 0)
+      return -1;
+
+   return fd;
+}
+
+static struct gbm_surface *
+gbm_intel_surface_create(struct gbm_device *gbm,
+                       uint32_t width, uint32_t height,
+		       uint32_t format, uint32_t flags)
+{
+   struct gbm_intel_surface *surf;
+
+   surf = calloc(1, sizeof *surf);
+   if (surf == NULL)
+      return NULL;
+
+   surf->base.gbm = gbm;
+   surf->base.width = width;
+   surf->base.height = height;
+   surf->base.format = format;
+   surf->base.flags = flags;
+
+   return &surf->base;
+}
+
+static void
+gbm_intel_surface_destroy(struct gbm_surface *_surf)
+{
+   struct gbm_intel_surface *surf = gbm_intel_surface(_surf);
+
+   free(surf);
+}
+
+static void
+gbm_intel_destroy(struct gbm_device *gbm)
+{
+   struct gbm_intel_device *igbm = gbm_intel_device(gbm);
+
+   drm_intel_bufmgr_destroy(igbm->bufmgr);
+
+   free(igbm);
+}
+
+static struct gbm_device *
+gbm_intel_device_create(int fd)
+{
+   struct gbm_intel_device *igbm;
+
+   igbm = calloc(1, sizeof *igbm);
+
+   igbm->base.base.fd = fd;
+   igbm->base.base.bo_create = gbm_intel_bo_create;
+   igbm->base.base.bo_import = gbm_intel_bo_import;
+   igbm->base.base.is_format_supported = gbm_intel_is_format_supported;
+   igbm->base.base.bo_write = gbm_intel_bo_write;
+   igbm->base.base.bo_get_fd = gbm_intel_bo_get_fd;
+   igbm->base.base.bo_destroy = gbm_intel_bo_destroy;
+   igbm->base.base.destroy = gbm_intel_destroy;
+   igbm->base.base.surface_create = gbm_intel_surface_create;
+   igbm->base.base.surface_destroy = gbm_intel_surface_destroy;
+
+   igbm->base.type = GBM_DRM_DRIVER_TYPE_NATIVE;
+   igbm->base.base.name = "drm";
+
+   igbm->bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
+   if (!igbm->bufmgr) {
+      free(igbm);
+      return NULL;
+   }
+
+   return &igbm->base.base;
+}
+
+struct gbm_backend gbm_intel_backend = {
+   .backend_name = "intel",
+   .create_device = gbm_intel_device_create,
+};
diff --git a/src/gbm/backends/intel/gbm_intel.h b/src/gbm/backends/intel/gbm_intel.h
new file mode 100644
index 0000000..af0689b
--- /dev/null
+++ b/src/gbm/backends/intel/gbm_intel.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2011-2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>
+ */
+
+#ifndef _GBM_INTEL_INTERNAL_H_
+#define _GBM_INTEL_INTERNAL_H_
+
+#include <drm/i915_drm.h>
+#include <libdrm/intel_bufmgr.h>
+
+#include "gbmint.h"
+
+#include "common_drm.h"
+
+struct gbm_intel_surface;
+
+struct gbm_intel_device {
+   struct gbm_drm_device base;
+
+   drm_intel_bufmgr *bufmgr;
+};
+
+struct gbm_intel_bo {
+   struct gbm_drm_bo base;
+
+   drm_intel_bo *bo;
+};
+
+struct gbm_intel_surface {
+   struct gbm_surface base;
+};
+
+static inline struct gbm_intel_device *
+gbm_intel_device(struct gbm_device *gbm)
+{
+   return (struct gbm_intel_device *) gbm;
+}
+
+static inline struct gbm_intel_bo *
+gbm_intel_bo(struct gbm_bo *bo)
+{
+   return (struct gbm_intel_bo *) bo;
+}
+
+static inline struct gbm_intel_surface *
+gbm_intel_surface(struct gbm_surface *surface)
+{
+   return (struct gbm_intel_surface *) surface;
+}
+
+#endif
diff --git a/src/gbm/main/backend.c b/src/gbm/main/backend.c
index aceb662..36a8775 100644
--- a/src/gbm/main/backend.c
+++ b/src/gbm/main/backend.c
@@ -37,6 +37,7 @@
 #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
 
 extern const struct gbm_backend gbm_dri_backend;
+extern const struct gbm_backend gbm_intel_backend;
 
 struct backend_desc {
    const char *name;
@@ -45,6 +46,7 @@ struct backend_desc {
 
 static const struct backend_desc backends[] = {
    { "gbm_dri.so", &gbm_dri_backend },
+   { "gbm_intel.so", &gbm_intel_backend },
    { "gbm_gallium_drm.so", NULL },
 };
 
diff --git a/src/gbm/main/common_drm.h b/src/gbm/main/common_drm.h
index d28c3f0..9fa0716 100644
--- a/src/gbm/main/common_drm.h
+++ b/src/gbm/main/common_drm.h
@@ -33,6 +33,7 @@
 enum gbm_drm_driver_type {
    GBM_DRM_DRIVER_TYPE_DRI,
    GBM_DRM_DRIVER_TYPE_GALLIUM,
+   GBM_DRM_DRIVER_TYPE_NATIVE,
 };
 
 struct gbm_drm_device {
-- 
1.8.3.2



More information about the mesa-dev mailing list