On Thu, May 3, 2012 at 3:51 PM, Kristian Høgsberg <k...@bitplanet.net> wrote: > On Thu, May 3, 2012 at 5:08 PM, Mandeep Baines <mandeep.bai...@gmail.com> > wrote: >> 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? > > 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@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