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.st...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev