[Mesa-dev] [PATCH RFC 1/2] GBM: add KMS provider interface

Lucas Stach l.stach at pengutronix.de
Fri Mar 4 13:49:15 UTC 2016


The GBM device, which is used to bootstrap the EGL context
should always be constructed atop a render capable DRM device.
If this device is a render node or a standalone renderonly DRM
device, we need a way to set the actual KMS output device to
allow for proper allocations of the buffer objects backing the
window surface and hiding the needed PRIME import/export.

This interface allows this by constructing a second GBM device
on top of the KMS capable DRM device and binding this as the
KMS provider to the render GBM device.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 src/gbm/main/gbm.c    | 35 ++++++++++++++++++++++++++++++++++-
 src/gbm/main/gbm.h    |  7 +++++++
 src/gbm/main/gbmint.h |  5 +++++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
index c046b1ad7c8a..26339747f3a1 100644
--- a/src/gbm/main/gbm.c
+++ b/src/gbm/main/gbm.c
@@ -90,6 +90,25 @@ gbm_device_is_format_supported(struct gbm_device *gbm,
    return gbm->is_format_supported(gbm, format, usage);
 }
 
+/** Set the KMS provider device used for scanout and cursor BO allocations
+ *
+ * \param gbm The created buffer manager
+ * \param provider The buffer manager that should be used for KMS buffers
+ * \return 0 if successful
+ */
+GBM_EXPORT int
+gbm_device_set_kms_provider(struct gbm_device *gbm,
+                            struct gbm_device *provider)
+{
+   /* Changing the provider on the fly is not supported */
+   if (gbm->kms_provider)
+      return -1;
+   else
+      gbm->kms_provider = provider;
+
+   return 0;
+}
+
 /** Destroy the gbm device and free all resources associated with it.
  *
  * \param gbm The device created using gbm_create_device()
@@ -344,12 +363,17 @@ gbm_bo_create(struct gbm_device *gbm,
               uint32_t width, uint32_t height,
               uint32_t format, uint32_t usage)
 {
+   struct gbm_bo *bo;
+
    if (width == 0 || height == 0) {
       errno = EINVAL;
       return NULL;
    }
 
-   return gbm->bo_create(gbm, width, height, format, usage);
+   bo = gbm->bo_create(gbm, width, height, format, usage);
+   bo->type = GBM_BO_TYPE_RENDER | GBM_BO_TYPE_KMS;
+
+   return bo;
 }
 
 /**
@@ -385,6 +409,15 @@ gbm_bo_import(struct gbm_device *gbm,
    return gbm->bo_import(gbm, type, buffer, usage);
 }
 
+GBM_EXPORT struct gbm_bo *
+gbm_bo_get_kms_bo(struct gbm_bo *bo)
+{
+   if (!bo || !(bo->type & GBM_BO_TYPE_KMS))
+      return NULL;
+
+   return bo;
+}
+
 /**
  * Allocate a surface object
  *
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
index 8db2153e84bb..1faff360130b 100644
--- a/src/gbm/main/gbm.h
+++ b/src/gbm/main/gbm.h
@@ -226,6 +226,10 @@ int
 gbm_device_is_format_supported(struct gbm_device *gbm,
                                uint32_t format, uint32_t usage);
 
+int
+gbm_device_set_kms_provider(struct gbm_device *gbm,
+                            struct gbm_device *provider);
+
 void
 gbm_device_destroy(struct gbm_device *gbm);
 
@@ -274,6 +278,9 @@ gbm_bo_get_handle(struct gbm_bo *bo);
 int
 gbm_bo_get_fd(struct gbm_bo *bo);
 
+struct gbm_bo *
+gbm_bo_get_kms_bo(struct gbm_bo *bo);
+
 int
 gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count);
 
diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h
index 155eb12b06bc..218ecf66c0fd 100644
--- a/src/gbm/main/gbmint.h
+++ b/src/gbm/main/gbmint.h
@@ -52,6 +52,7 @@ struct gbm_device {
    /* Hack to make a gbm_device detectable by its first element. */
    struct gbm_device *(*dummy)(int);
 
+   struct gbm_device *kms_provider;
    int fd;
    const char *name;
    unsigned int refcount;
@@ -87,8 +88,12 @@ struct gbm_device {
  *
  * The members in this structure should not be accessed directly.
  */
+#define GBM_BO_TYPE_KMS        (1 << 0)
+#define GBM_BO_TYPE_RENDER     (1 << 1)
+
 struct gbm_bo {
    struct gbm_device *gbm;
+   uint32_t type;
    uint32_t width;
    uint32_t height;
    uint32_t stride;
-- 
2.7.0



More information about the mesa-dev mailing list