[Mesa-dev] [v4 06/10] intel: prepare for dri images having more than one plane
Topi Pohjolainen
topi.pohjolainen at intel.com
Thu May 2 00:08:23 PDT 2013
v2 (as advised by Eric):
- use ARRAY_SIZE
- re-use 'image_destroy' for cleaning up after failure
- check directly the region pointer instead of the buffer object
when determining if a region exists
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
src/mesa/drivers/dri/intel/intel_screen.c | 103 +++++++++++++++++++++---------
1 file changed, 72 insertions(+), 31 deletions(-)
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 4973441..d822b1c 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -490,8 +490,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 < ARRAY_SIZE(image->regions); ++i) {
+ if (image->regions[i])
+ intel_region_release(&image->regions[i]);
+ }
+
+ free(image);
}
static __DRIimage *
@@ -568,16 +574,22 @@ 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 < ARRAY_SIZE(image->regions); ++i) {
+ if (!orig_image->regions[i])
+ break;
+
+ intel_region_reference(&image->regions[i], orig_image->regions[i]);
+ if (image->regions[i] == NULL) {
+ intel_destroy_image(image);
+ return NULL;
+ }
}
image->internal_format = orig_image->internal_format;
@@ -646,47 +658,76 @@ 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;
+
+ if (f->nplanes == 1)
+ img = intel_allocate_image(f->planes[0].dri_format, loaderPriv);
+ else
+ 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) {
+ intel_destroy_image(img);
+ return NULL;
+ }
+ }
+
+ intel_setup_image_from_dimensions(img);
+
+ 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;
+ struct intel_image_format *f = intel_image_format_lookup(fourcc);
__DRIimage *image;
int i, index;
- if (fds == NULL || num_fds != 1)
- return NULL;
-
- f = intel_image_format_lookup(fourcc);
- 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;
- if (f->nplanes == 1)
- image = intel_allocate_image(f->planes[0].dri_format, loaderPriv);
- else
- image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPriv);
-
+ 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];
- }
- intel_setup_image_from_dimensions(image);
+ /**
+ * 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
More information about the mesa-dev
mailing list