diff options
-rw-r--r-- | include/GL/internal/dri_interface.h | 15 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_regions.c | 33 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_regions.h | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_screen.c | 59 |
4 files changed, 108 insertions, 5 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 42147e90ebd..30ce175e6f0 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,16 @@ struct __DRIimageExtensionRec { int level, unsigned *error, void *loaderPrivate); + /** + * Like createImageFromNames, but takes a prime fd instead. + * + * \since 7 + */ + __DRIimage *(*createImageFromFds)(__DRIscreen *screen, + int width, int height, int fourcc, + int *fds, int num_fds, + 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 90b985d0b97..44f7030c712 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -205,6 +205,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 06a4b989e88..1fb6b275772 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -87,6 +87,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 0d39b9d3b30..32e92594c08 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -546,6 +546,10 @@ intel_query_image(__DRIimage *image, int attrib, int *value) return false; *value = image->planar_format->components; return true; + case __DRI_IMAGE_ATTRIB_FD: + if (drm_intel_bo_gem_export_to_prime(image->region->bo, value) == 0) + return true; + return false; default: return false; } @@ -623,8 +627,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 +641,52 @@ intel_create_image_from_names(__DRIscreen *screen, } static __DRIimage * +intel_create_image_from_fds(__DRIscreen *screen, + int width, int height, int fourcc, + int *fds, int num_fds, int *strides, int *offsets, + void *loaderPrivate) +{ + struct intel_screen *intelScreen = screen->driverPrivate; + struct intel_image_format *f = NULL; + __DRIimage *image; + int i, index; + + if (fds == NULL || num_fds != 1) + return NULL; + + 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], fds[0], "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; @@ -692,7 +742,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, @@ -703,7 +753,8 @@ static struct __DRIimageExtensionRec intelImageExtension = { .validateUsage = intel_validate_usage, .createImageFromNames = intel_create_image_from_names, .fromPlanar = intel_from_planar, - .createImageFromTexture = intel_create_image_from_texture + .createImageFromTexture = intel_create_image_from_texture, + .createImageFromFds = intel_create_image_from_fds }; static const __DRIextension *intelScreenExtensions[] = { |