diff options
author | Kristian Høgsberg <[email protected]> | 2013-02-02 08:38:07 -0500 |
---|---|---|
committer | Kristian Høgsberg <[email protected]> | 2013-03-18 21:03:54 -0400 |
commit | 2356e28452454ed3b584af9b4d28c553c2a80769 (patch) | |
tree | 26c5e7dcf720f8b4f219236dfcd3d8259cc605b9 /src/mesa | |
parent | 664fe6dc844358dbc5474aa4e936c6180e86f144 (diff) |
Add dri image entry point for creating image from fd
Reviewed-by: Ander Conselvan de Oliveira <[email protected]>
Diffstat (limited to 'src/mesa')
-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 |
3 files changed, 94 insertions, 4 deletions
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[] = { |