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

Kristian Høgsberg krh at bitplanet.net
Thu May 3 07:56:01 PDT 2012


On Thu, May 3, 2012 at 7:47 AM, Jakob Bornecrantz <jakob at vmware.com> wrote:
> Hi Kristian,
>
> s/gbm_bo_write/gbm_bo_write_to_cursor/g and make fail on anything
> other then cursors and I'm happy. Not making it just happen
> to work on some hardware really sucks for those that it doesn't
> work on because people will expect it to work.

I think we have a good compromise the way the patch is.  I don't want
to restrict the write entrypoint to only cursors.  Not because I think
it should work with generic gbm bos, but becase I don't want to
preclude gbm_bo_write from working with a future similar restricted,
special case bo type.

Kristian

> Cheers, Jakob.
>
> ----- Original Message -----
>> 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.
>>
>> 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