Add gbm_bo_map() and gbm_bo_unmap(). This lets a user access the contents of a bo using the CPU.
--- I'm not sure about the extra flags. We do have GBM_BO_USE_WRITE but that is defined to always work with GBM_BO_USE_CURSOR_64X64. Reusing that would imply that these buffers are always mappable or an API change. --- src/gbm/backends/dri/gbm_dri.c | 4 ++++ src/gbm/backends/intel/gbm_intel.c | 21 +++++++++++++++++++++ src/gbm/backends/intel/gbm_intel.h | 2 ++ src/gbm/main/gbm.c | 25 +++++++++++++++++++++++++ src/gbm/main/gbm.h | 14 ++++++++++++++ src/gbm/main/gbmint.h | 2 ++ 6 files changed, 68 insertions(+) diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index 9998308..bdd1c85 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -315,6 +315,10 @@ gbm_dri_is_format_supported(struct gbm_device *gbm, usage & GBM_BO_USE_RENDERING) return 0; + if (usage & GBM_BO_USE_CPU_WRITE || + usage & GBM_BO_USE_CPU_READ) + return 0; + return 1; } diff --git a/src/gbm/backends/intel/gbm_intel.c b/src/gbm/backends/intel/gbm_intel.c index 9f17df7..f8baa98 100644 --- a/src/gbm/backends/intel/gbm_intel.c +++ b/src/gbm/backends/intel/gbm_intel.c @@ -73,6 +73,24 @@ gbm_intel_bo_write(struct gbm_bo *bo, const void *buf, size_t count) return drm_intel_bo_unmap(ibo->bo); } +static void * +gbm_intel_bo_map(struct gbm_bo *bo) +{ + struct gbm_intel_bo *ibo = gbm_intel_bo(bo); + + drm_intel_bo_map(ibo->bo, 1); + + return ibo->bo->virtual; +} + +static void +gbm_intel_bo_unmap(struct gbm_bo *bo) +{ + struct gbm_intel_bo *ibo = gbm_intel_bo(bo); + + drm_intel_bo_unmap(ibo->bo); +} + static void gbm_intel_bo_destroy(struct gbm_bo *_bo) { @@ -102,6 +120,7 @@ gbm_intel_bo_create_with_bo(struct gbm_device *gbm, return NULL; ibo->bo = bo; + ibo->usage = usage; ibo->base.base.gbm = gbm; ibo->base.base.width = width; @@ -225,6 +244,8 @@ gbm_intel_device_create(int fd) igbm->base.base.bo_export = gbm_intel_bo_export; igbm->base.base.is_format_supported = gbm_intel_is_format_supported; igbm->base.base.bo_write = gbm_intel_bo_write; + igbm->base.base.bo_map = gbm_intel_bo_map; + igbm->base.base.bo_unmap = gbm_intel_bo_unmap; igbm->base.base.bo_destroy = gbm_intel_bo_destroy; igbm->base.base.destroy = gbm_intel_destroy; igbm->base.base.surface_create = gbm_intel_surface_create; diff --git a/src/gbm/backends/intel/gbm_intel.h b/src/gbm/backends/intel/gbm_intel.h index 4691ecc..8136c78 100644 --- a/src/gbm/backends/intel/gbm_intel.h +++ b/src/gbm/backends/intel/gbm_intel.h @@ -46,6 +46,8 @@ struct gbm_intel_device { struct gbm_intel_bo { struct gbm_drm_bo base; + uint32_t usage; + drm_intel_bo *bo; uint32_t name; }; diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index b68ead0..f41b4c9 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -250,6 +250,31 @@ gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count) return bo->gbm->bo_write(bo, buf, count); } +/** Map a buffer object in CPU accesible memory + * + * \param bo The buffer object to be mapped + * \return Pointer to the mapped buffer object or NULL on failure + */ +GBM_EXPORT void * +gbm_bo_map(struct gbm_bo *bo) +{ + if (bo->gbm->bo_map) + return bo->gbm->bo_map(bo); + else + return NULL; +} + +/** Unmap a preivously mapped buffer object + * + * \param The buffer object to be unmapped + */ +GBM_EXPORT void +gbm_bo_unmap(struct gbm_bo *bo) +{ + if (bo->gbm->bo_unmap) + bo->gbm->bo_unmap(bo); +} + /** 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 3854c4c..b3942d3 100644 --- a/src/gbm/main/gbm.h +++ b/src/gbm/main/gbm.h @@ -207,6 +207,14 @@ enum gbm_bo_flags { * combinations. */ GBM_BO_USE_WRITE = (1 << 3), + /** + * Buffer can be mapped with gbm_bo_map() for writing. + */ + GBM_BO_USE_CPU_WRITE = (1 << 4), + /** + * Buffer can be mapped with gbm_bo_map() for reading. + */ + GBM_BO_USE_CPU_READ = (1 << 5), }; int @@ -262,6 +270,12 @@ 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_map(struct gbm_bo *bo); + +void +gbm_bo_unmap(struct gbm_bo *bo); + 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 a8cf49e..f17a46f 100644 --- a/src/gbm/main/gbmint.h +++ b/src/gbm/main/gbmint.h @@ -70,6 +70,8 @@ struct gbm_device { void *buffer, uint32_t usage); int (*bo_export)(struct gbm_bo *bo, uint32_t type, void **buffer); int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data); + void *(*bo_map)(struct gbm_bo *bo); + void (*bo_unmap)(struct gbm_bo *bo); void (*bo_destroy)(struct gbm_bo *bo); struct gbm_surface *(*surface_create)(struct gbm_device *gbm, -- 1.7.9.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev