[Mesa-dev] [PATCH] gbm: Add gbm_bo_write entry point

Mandeep Singh Baines msb at chromium.org
Thu May 3 16:49:17 PDT 2012


On Thu, May 3, 2012 at 3:51 PM, Kristian Høgsberg <krh at bitplanet.net> wrote:
> On Thu, May 3, 2012 at 5:08 PM, Mandeep Baines <mandeep.baines at gmail.com> wrote:
>> 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?
>
> Those are DRM ioctls.  gbm is a drm independent API and can work for
> non-drm/mesa EGL stacks.
>
> Kristian
>

Ah. Thanks for the explanation.

Regards,
Mandeep

>> 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