summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/GL/internal/dri_interface.h10
-rw-r--r--src/gbm/backends/dri/gbm_dri.c18
-rw-r--r--src/gbm/main/gbm.c19
-rw-r--r--src/gbm/main/gbm.h9
-rw-r--r--src/gbm/main/gbmint.h1
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.h1
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c32
7 files changed, 87 insertions, 3 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index eafbe10f9b0..e37917eda99 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 4df6e8fcf06..e5ddfb6ce69 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 987e96500f8..3994f86aafc 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 cf3d4752c36..af5dc5aee8c 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 0e98bdf3d8d..8eb8671aeb2 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_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 4ea970ad6d1..af3a059560a 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -132,6 +132,7 @@ void _mesa_copy_rect(GLubyte * dst,
struct __DRIimageRec {
struct intel_region *region;
GLenum internal_format;
+ uint32_t usage;
uint32_t dri_format;
GLuint format;
GLenum data_type;
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 9db56064bea..458178fe927 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -305,10 +305,16 @@ 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;
+ image->usage = use;
image->dri_format = format;
switch (format) {
@@ -392,6 +398,7 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
}
image->internal_format = orig_image->internal_format;
+ image->usage = orig_image->usage;
image->dri_format = orig_image->dri_format;
image->format = orig_image->format;
image->data_type = orig_image->data_type;
@@ -408,18 +415,39 @@ intel_validate_usage(__DRIimage *image, unsigned int use)
return GL_FALSE;
}
+ /* We only support write for cursor drm images */
+ if ((use & __DRI_IMAGE_USE_WRITE) &&
+ use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR))
+ return GL_FALSE;
+
return GL_TRUE;
}
+static int
+intel_image_write(__DRIimage *image, const void *buf, size_t count)
+{
+ if (image->region->map_refcount)
+ return -1;
+ if (!(image->usage & __DRI_IMAGE_USE_WRITE))
+ 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[] = {