[Mesa-dev] [PATCH] gbm: Add gbm_bo_write entry point
Jakob Bornecrantz
jakob at vmware.com
Thu May 3 09:08:14 PDT 2012
----- Ursprungligt meddelande -----
> 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.
Fair enough.
Can you put the "if use != WRITE return -1;" snippet in the
gbm_bo_write function or all the drivers supposed to validate the args?
Cheers, Jakob.
>
> 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