Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> --- src/mesa/drivers/dri/intel/intel_screen.c | 101 +++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 30 deletions(-)
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 3d0344e..8716688 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -496,8 +496,14 @@ intel_create_image_from_texture(__DRIcontext *context, int target, static void intel_destroy_image(__DRIimage *image) { - intel_region_release(&image->regions[0]); - free(image); + int i; + + for (i = 0; i < sizeof(image->regions) / sizeof(struct intel_region); ++i) { + if (image->regions[i]->bo) + intel_region_release(&image->regions[i]); + } + + free(image); } static __DRIimage * @@ -571,16 +577,25 @@ intel_query_image(__DRIimage *image, int attrib, int *value) static __DRIimage * intel_dup_image(__DRIimage *orig_image, void *loaderPrivate) { + int i; __DRIimage *image; image = calloc(1, sizeof *image); if (image == NULL) return NULL; - intel_region_reference(&image->regions[0], orig_image->regions[0]); - if (image->regions[0] == NULL) { - free(image); - return NULL; + for (i = 0; i < sizeof(image->regions) / sizeof(struct intel_region); ++i) { + if (!orig_image->regions[i]->bo) + break; + + intel_region_reference(&image->regions[i], orig_image->regions[i]); + if (image->regions[i] == NULL) { + for (--i; i >= 0; --i) + intel_region_release(&image->regions[i]); + + free(image); + return NULL; + } } image->internal_format = orig_image->internal_format; @@ -649,45 +664,71 @@ intel_create_image_from_names(__DRIscreen *screen, } static __DRIimage * +intel_setup_image_from_fds(struct intel_screen *screen, int width, int height, + const struct intel_image_format *f, + const int *fds, int num_fds, const int *strides, + void *loaderPriv) +{ + int i; + __DRIimage *img = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPriv); + + if (img == NULL) + return NULL; + + for (i = 0; i < num_fds; i++) { + img->regions[i] = intel_region_alloc_for_fd(screen, f->planes[i].cpp, + width >> f->planes[i].width_shift, + height >> f->planes[i].height_shift, + strides[i], fds[i], "image"); + + if (img->regions[i] == NULL) { + for (--i; i >= 0; --i) + intel_region_release(&img->regions[i]); + + free(img); + return NULL; + } + } + + return img; +} + +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; + struct intel_image_format *f = intel_image_format_lookup(fourcc); __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) + /** + * In case the image is to consist of multiple regions, there must be exactly + * one region per plane. + */ + if (fds == NULL || f == NULL || (num_fds > 1 && f->nplanes != num_fds)) return NULL; - image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate); + image = intel_setup_image_from_fds(intelScreen, width, height, f, + fds, num_fds, strides, loaderPrivate); if (image == NULL) return NULL; - image->regions[0] = intel_region_alloc_for_fd(intelScreen, - 1, width, height, - strides[0], fds[0], "image"); - if (image->regions[0] == 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]; + + /** + * In case the image is to consist of multiple planes all in the same region, + * one needs to record not only the invidual strides, but also the locations + * of the planes within the region. + */ + if (num_fds == 1 && f->nplanes > 1) { + 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; -- 1.8.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev