[PATCH 2/3] Add dri image entry point for creating image from fd
Kristian Høgsberg
krh at bitplanet.net
Wed Feb 27 17:52:50 PST 2013
---
include/GL/internal/dri_interface.h | 14 +++++++-
src/mesa/drivers/dri/intel/intel_regions.c | 33 +++++++++++++++++++
src/mesa/drivers/dri/intel/intel_regions.h | 6 ++++
src/mesa/drivers/dri/intel/intel_screen.c | 53 ++++++++++++++++++++++++++++--
4 files changed, 102 insertions(+), 4 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 42147e9..a1392ab 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -938,7 +938,7 @@ struct __DRIdri2ExtensionRec {
* extensions.
*/
#define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 6
+#define __DRI_IMAGE_VERSION 7
/**
* These formats correspond to the similarly named MESA_FORMAT_*
@@ -1021,6 +1021,9 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_ATTRIB_WIDTH 0x2004 /* available in versions 4+ */
#define __DRI_IMAGE_ATTRIB_HEIGHT 0x2005
#define __DRI_IMAGE_ATTRIB_COMPONENTS 0x2006 /* available in versions 5+ */
+#define __DRI_IMAGE_ATTRIB_FD 0x2007 /* available in versions
+ * 7+. Each query will return a
+ * new fd. */
/**
* \name Reasons that __DRIimageExtensionRec::createImageFromTexture might fail
@@ -1117,6 +1120,15 @@ struct __DRIimageExtensionRec {
int level,
unsigned *error,
void *loaderPrivate);
+ /**
+ * Like createImageFromNames, but takes a prime fd instead.
+ *
+ * \since 7
+ */
+ __DRIimage *(*createImageFromFd)(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int fd, int *strides, int *offsets,
+ void *loaderPrivate);
};
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 89d91b0..74f191f 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -284,6 +284,39 @@ intel_region_alloc_for_handle(struct intel_screen *screen,
return region;
}
+struct intel_region *
+intel_region_alloc_for_fd(struct intel_screen *screen,
+ GLuint cpp,
+ GLuint width, GLuint height, GLuint pitch,
+ int fd, const char *name)
+{
+ struct intel_region *region;
+ drm_intel_bo *buffer;
+ int ret;
+ uint32_t bit_6_swizzle, tiling;
+
+ buffer = drm_intel_bo_gem_create_from_prime(screen->bufmgr,
+ fd, height * pitch);
+ if (buffer == NULL)
+ return NULL;
+ ret = drm_intel_bo_get_tiling(buffer, &tiling, &bit_6_swizzle);
+ if (ret != 0) {
+ fprintf(stderr, "Couldn't get tiling of buffer (%s): %s\n",
+ name, strerror(-ret));
+ drm_intel_bo_unreference(buffer);
+ return NULL;
+ }
+
+ region = intel_region_alloc_internal(screen, cpp,
+ width, height, pitch, tiling, buffer);
+ if (region == NULL) {
+ drm_intel_bo_unreference(buffer);
+ return NULL;
+ }
+
+ return region;
+}
+
void
intel_region_reference(struct intel_region **dst, struct intel_region *src)
{
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 28d581c..6757cc2 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -89,6 +89,12 @@ intel_region_alloc_for_handle(struct intel_screen *screen,
GLuint width, GLuint height, GLuint pitch,
unsigned int handle, const char *name);
+struct intel_region *
+intel_region_alloc_for_fd(struct intel_screen *screen,
+ GLuint cpp,
+ GLuint width, GLuint height, GLuint pitch,
+ int fd, const char *name);
+
bool
intel_region_flink(struct intel_region *region, uint32_t *name);
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 277b133..3ee0d69 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -546,6 +546,9 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
return false;
*value = image->planar_format->components;
return true;
+ case __DRI_IMAGE_ATTRIB_FD:
+ drm_intel_bo_gem_export_to_prime(image->region->bo, value);
+ return true;
default:
return false;
}
@@ -623,8 +626,8 @@ intel_create_image_from_names(__DRIscreen *screen,
names[0], strides[0],
loaderPrivate);
- if (image == NULL)
- return NULL;
+ if (image == NULL)
+ return NULL;
image->planar_format = f;
for (i = 0; i < f->nplanes; i++) {
@@ -637,6 +640,49 @@ intel_create_image_from_names(__DRIscreen *screen,
}
static __DRIimage *
+intel_create_image_from_fd(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int fd, int *strides, int *offsets,
+ void *loaderPrivate)
+{
+ struct intel_screen *intelScreen = screen->driverPrivate;
+ struct intel_image_format *f = NULL;
+ __DRIimage *image;
+ int i, index;
+
+ for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
+ if (intel_image_formats[i].fourcc == fourcc) {
+ f = &intel_image_formats[i];
+ }
+ }
+
+ if (f == NULL)
+ return NULL;
+
+ image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
+ if (image == NULL)
+ return NULL;
+
+ image->region = intel_region_alloc_for_fd(intelScreen,
+ 1, width, height,
+ strides[0], fd, "image");
+ if (image->region == NULL) {
+ free(image);
+ return NULL;
+ }
+
+ image->planar_format = f;
+ for (i = 0; i < f->nplanes; i++) {
+ index = f->planes[i].buffer_index;
+ image->offsets[index] = offsets[index];
+ image->strides[index] = strides[index];
+ }
+
+ return image;
+}
+
+
+static __DRIimage *
intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
{
int width, height, offset, stride, dri_format, index;
@@ -693,7 +739,7 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
}
static struct __DRIimageExtensionRec intelImageExtension = {
- .base = { __DRI_IMAGE, 6 },
+ .base = { __DRI_IMAGE, 7 },
.createImageFromName = intel_create_image_from_name,
.createImageFromRenderbuffer = intel_create_image_from_renderbuffer,
@@ -705,6 +751,7 @@ static struct __DRIimageExtensionRec intelImageExtension = {
.createImageFromNames = intel_create_image_from_names,
.fromPlanar = intel_from_planar,
.createImageFromTexture = intel_create_image_from_texture
+ .createImageFromFd = intel_create_image_from_fd
};
static const __DRIextension *intelScreenExtensions[] = {
--
1.8.1.2
More information about the wayland-devel
mailing list