From: Ander Conselvan de Oliveira <ander.conselvan.de.olive...@intel.com>
Add gbm_bo_map() and gbm_bo_unmap(). This lets a user access the contents of a bo using the CPU. --- src/gbm/backends/dri/gbm_dri.c | 3 +++ src/gbm/backends/intel/gbm_intel.c | 24 ++++++++++++++++++++++++ src/gbm/backends/intel/gbm_intel.h | 2 ++ src/gbm/main/gbm.c | 36 ++++++++++++++++++++++++++++++++++++ src/gbm/main/gbm.h | 10 ++++++++++ src/gbm/main/gbmint.h | 2 ++ 6 files changed, 77 insertions(+) diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index cbb4c8c..8295a25 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -346,6 +346,9 @@ gbm_dri_is_format_supported(struct gbm_device *gbm, usage & GBM_BO_USE_RENDERING) return 0; + if (usage & GBM_BO_USE_MAP) + return 0; + return 1; } diff --git a/src/gbm/backends/intel/gbm_intel.c b/src/gbm/backends/intel/gbm_intel.c index 2c5336d..2252159 100644 --- a/src/gbm/backends/intel/gbm_intel.c +++ b/src/gbm/backends/intel/gbm_intel.c @@ -76,6 +76,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) { @@ -105,6 +123,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; @@ -147,6 +166,9 @@ gbm_intel_bo_create(struct gbm_device *gbm, tiling = I915_TILING_NONE; } + if (usage & GBM_BO_USE_MAP) + tiling = I915_TILING_NONE; + if (usage & GBM_BO_USE_RENDERING) flags |= BO_ALLOC_FOR_RENDER; @@ -237,6 +259,8 @@ gbm_intel_device_create(int fd) igbm->base.base.is_format_supported = gbm_intel_is_format_supported; igbm->base.base.bo_write = gbm_intel_bo_write; igbm->base.base.bo_get_fd = gbm_intel_bo_get_fd; + 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 af0689b..1958355 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; }; diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index 907ca3c..f7c777a 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -267,6 +267,42 @@ 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 + * + * This makes the content of the bo available for CPU access until + * \ref gbm_bo_unmap() is called. Synchronization between CPU and GPU + * will be done at unmap time, so the caller shouldn't assume coherency + * for mapped buffers. + * + * \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) { + errno = ENOSYS; + return NULL; + } + + return bo->gbm->bo_map(bo); +} + +/** Unmap a previously mapped buffer object + * + * Unmaps the given bo and perform any necessary synchronization such as + * cache flushing, copying, etc, so that the GPU sees the same data as + * written by the CPU. + * + * \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 92d472a..2d081de 100644 --- a/src/gbm/main/gbm.h +++ b/src/gbm/main/gbm.h @@ -207,6 +207,10 @@ enum gbm_bo_flags { * combinations. */ GBM_BO_USE_WRITE = (1 << 3), + /** + * Buffer can be mapped with gbm_bo_map(). + */ + GBM_BO_USE_MAP = (1 << 4), }; int @@ -270,6 +274,12 @@ gbm_bo_get_fd(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 d7520ad..eea7d4d 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_write)(struct gbm_bo *bo, const void *buf, size_t data); int (*bo_get_fd)(struct gbm_bo *bo); + 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.8.3.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev