2012/5/2 Kristian Høgsberg <k...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev