[Mesa-dev] [PATCH] gbm: Add gbm_bo_write entry point
Mandeep Baines
mandeep.baines at gmail.com
Thu May 3 14:08:55 PDT 2012
2012/5/2 Kristian Høgsberg <krh at bitplanet.net>:
> This new gbm entry point allows writing data into a gbm bo. The bo has
> to be created with the GBM_BO_USE_WRITE flag, and it's only required to
> work for GBM_BO_USE_CURSOR_64X64 bos.
>
> The gbm API is designed to be the glue layer between EGL and KMS, but there
> was never a mechanism initialize a buffer suitable for use with KMS
> hw cursors. The hw cursor bo is typically not compatible with anything EGL
> can render to, and thus there's no way to get data into such a bo.
>
Hi Kristian,
What is the advantage of this approach over just using dumb buffers
via DRM_IOCTL_MODE_CREATE_DUMB and
DRM_IOCTL_MODE_MAP_DUMB?
Regards,
Mandeep
> gbm_bo_write() fills that gap while staying out of the efficient
> cpu->gpu pixel transfer business.
> ---
> include/GL/internal/dri_interface.h | 10 +++++++++-
> src/gbm/backends/dri/gbm_dri.c | 18 ++++++++++++++++++
> src/gbm/main/gbm.c | 19 +++++++++++++++++++
> src/gbm/main/gbm.h | 9 +++++++++
> src/gbm/main/gbmint.h | 1 +
> src/mesa/drivers/dri/intel/intel_screen.c | 24 ++++++++++++++++++++++--
> 6 files changed, 78 insertions(+), 3 deletions(-)
>
> diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
> index eafbe10..e37917e 100644
> --- a/include/GL/internal/dri_interface.h
> +++ b/include/GL/internal/dri_interface.h
> @@ -894,7 +894,7 @@ struct __DRIdri2ExtensionRec {
> * extensions.
> */
> #define __DRI_IMAGE "DRI_IMAGE"
> -#define __DRI_IMAGE_VERSION 3
> +#define __DRI_IMAGE_VERSION 4
>
> /**
> * These formats correspond to the similarly named MESA_FORMAT_*
> @@ -911,6 +911,7 @@ struct __DRIdri2ExtensionRec {
> #define __DRI_IMAGE_USE_SHARE 0x0001
> #define __DRI_IMAGE_USE_SCANOUT 0x0002
> #define __DRI_IMAGE_USE_CURSOR 0x0004
> +#define __DRI_IMAGE_USE_WRITE 0x0008
>
> /**
> * queryImage attributes
> @@ -955,6 +956,13 @@ struct __DRIimageExtensionRec {
> * \since 2
> */
> GLboolean (*validateUsage)(__DRIimage *image, unsigned int use);
> +
> + /**
> + * Write data into image.
> + *
> + * \since 4
> + */
> + int (*write)(__DRIimage *image, const void *buf, size_t count);
> };
>
>
> diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
> index 4df6e8f..e5ddfb6 100644
> --- a/src/gbm/backends/dri/gbm_dri.c
> +++ b/src/gbm/backends/dri/gbm_dri.c
> @@ -291,6 +291,18 @@ gbm_dri_is_format_supported(struct gbm_device *gbm,
> return 1;
> }
>
> +static int
> +gbm_dri_bo_write(struct gbm_bo *_bo, const void *buf, size_t count)
> +{
> + struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
> + struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
> +
> + if (dri->image->base.version < 4)
> + return -1;
> +
> + return dri->image->write(bo->image, buf, count);
> +}
> +
> static void
> gbm_dri_bo_destroy(struct gbm_bo *_bo)
> {
> @@ -390,6 +402,9 @@ gbm_dri_bo_create(struct gbm_device *gbm,
> int dri_format;
> unsigned dri_use = 0;
>
> + if (dri->image->base.version < 4 && (usage & GBM_BO_USE_WRITE))
> + return NULL;
> +
> bo = calloc(1, sizeof *bo);
> if (bo == NULL)
> return NULL;
> @@ -421,6 +436,8 @@ gbm_dri_bo_create(struct gbm_device *gbm,
> dri_use |= __DRI_IMAGE_USE_SCANOUT;
> if (usage & GBM_BO_USE_CURSOR_64X64)
> dri_use |= __DRI_IMAGE_USE_CURSOR;
> + if (usage & GBM_BO_USE_WRITE)
> + dri_use |= __DRI_IMAGE_USE_WRITE;
>
> bo->image =
> dri->image->createImage(dri->screen,
> @@ -491,6 +508,7 @@ dri_device_create(int 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.is_format_supported = gbm_dri_is_format_supported;
> + dri->base.base.bo_write = gbm_dri_bo_write;
> dri->base.base.bo_destroy = gbm_dri_bo_destroy;
> dri->base.base.destroy = dri_destroy;
> dri->base.base.surface_create = gbm_dri_surface_create;
> diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
> index 987e965..3994f86 100644
> --- a/src/gbm/main/gbm.c
> +++ b/src/gbm/main/gbm.c
> @@ -231,6 +231,25 @@ gbm_bo_get_handle(struct gbm_bo *bo)
> return bo->handle;
> }
>
> +/** Write data into the buffer object
> + *
> + * If the buffer object was created with the GBM_BO_USE_WRITE flag,
> + * this function can used to write data into the buffer object. The
> + * data is copied directly into the object and it's the responsiblity
> + * of the caller to make sure the data represents valid pixel data,
> + * according to the width, height, stride and format of the buffer object.
> + *
> + * \param bo The buffer object
> + * \param buf The data to write
> + * \param count The number of bytes to write
> + * \return Returns -1 on error, 0 otherwise
> + */
> +GBM_EXPORT int
> +gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count)
> +{
> + return bo->gbm->bo_write(bo, buf, count);
> +}
> +
> /** Get the gbm device used to create the buffer object
> *
> * \param bo The buffer object
> diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
> index cf3d475..af5dc5a 100644
> --- a/src/gbm/main/gbm.h
> +++ b/src/gbm/main/gbm.h
> @@ -201,6 +201,12 @@ enum gbm_bo_flags {
> * as the storage for a color buffer
> */
> GBM_BO_USE_RENDERING = (1 << 2),
> + /**
> + * Buffer can be used for gbm_bo_write. This is guaranteed to work
> + * with GBM_BO_USE_CURSOR_64X64. but may not work for other
> + * combinations.
> + */
> + GBM_BO_USE_WRITE = (1 << 3),
> };
>
> int
> @@ -248,6 +254,9 @@ gbm_bo_get_device(struct gbm_bo *bo);
> union gbm_bo_handle
> gbm_bo_get_handle(struct gbm_bo *bo);
>
> +int
> +gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count);
> +
> void
> gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
> void (*destroy_user_data)(struct gbm_bo *, void *));
> diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h
> index 0e98bdf..8eb8671 100644
> --- a/src/gbm/main/gbmint.h
> +++ b/src/gbm/main/gbmint.h
> @@ -70,6 +70,7 @@ struct gbm_device {
> void *egl_dpy, void *egl_img,
> uint32_t width, uint32_t height,
> uint32_t usage);
> + int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data);
> void (*bo_destroy)(struct gbm_bo *bo);
>
> struct gbm_surface *(*surface_create)(struct gbm_device *gbm,
> diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
> index 9db5606..e945d14 100644
> --- a/src/mesa/drivers/dri/intel/intel_screen.c
> +++ b/src/mesa/drivers/dri/intel/intel_screen.c
> @@ -305,6 +305,11 @@ intel_create_image(__DRIscreen *screen,
> tiling = I915_TILING_NONE;
> }
>
> + /* We only support write for cursor drm images */
> + if ((use & __DRI_IMAGE_USE_WRITE) &&
> + use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR))
> + return NULL;
> +
> image = CALLOC(sizeof *image);
> if (image == NULL)
> return NULL;
> @@ -411,15 +416,30 @@ intel_validate_usage(__DRIimage *image, unsigned int use)
> return GL_TRUE;
> }
>
> +static int
> +intel_image_write(__DRIimage *image, const void *buf, size_t count)
> +{
> + if (image->region->map_refcount)
> + return -1;
> + /* if use != WRITE || region->map_refcount; return -1; */
> +
> + drm_intel_bo_map(image->region->bo, true);
> + memcpy(image->region->bo->virtual, buf, count);
> + drm_intel_bo_unmap(image->region->bo);
> +
> + return 0;
> +}
> +
> static struct __DRIimageExtensionRec intelImageExtension = {
> - { __DRI_IMAGE, 3 },
> + { __DRI_IMAGE, 4 },
> intel_create_image_from_name,
> intel_create_image_from_renderbuffer,
> intel_destroy_image,
> intel_create_image,
> intel_query_image,
> intel_dup_image,
> - intel_validate_usage
> + intel_validate_usage,
> + intel_image_write
> };
>
> static const __DRIextension *intelScreenExtensions[] = {
> --
> 1.7.10
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list