From c2c4e5bae3ba27bbdaafd8787a3e96266f82e70c Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 12 Feb 2018 17:54:41 +0000 Subject: [PATCH] i965: Fix bugs in intel_from_planar This commit fixes two bugs in intel_from_planar. First, if the planar format was non-NULL but only had a single plane, we were falling through to the planar case. If we had a CCS modifier and plane == 1, we would return NULL instead of the CCS plane. Second, if we did end up in the planar_format == NULL case and the modifier was DRM_FORMAT_MOD_INVALID, we would end up segfaulting in isl_drm_modifier_has_aux. Cc: mesa-stable@lists.freedesktop.org Fixes: 8f6e54c92966bb94a3f05f2cc7ea804273e125ad Signed-off-by: Daniel Stone Reviewed-by: Jason Ekstrand --- src/mesa/drivers/dri/i965/intel_screen.c | 56 ++++++++++++------------ 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 1f866cf8459..1c0fffa2e96 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -1312,42 +1312,44 @@ intel_query_dma_buf_modifiers(__DRIscreen *_screen, int fourcc, int max, static __DRIimage * intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate) { - int width, height, offset, stride, dri_format, index; - const struct intel_image_format *f; + int width, height, offset, stride, dri_format; __DRIimage *image; - if (parent == NULL) { + if (parent == NULL) return NULL; - } else if (parent->planar_format == NULL) { - const bool is_aux = - isl_drm_modifier_has_aux(parent->modifier) && plane == 1; - if (!is_aux) - return NULL; - - width = parent->width; - height = parent->height; - dri_format = parent->dri_format; - offset = parent->aux_offset; - stride = parent->aux_pitch; - } else { - /* Planar formats don't support aux buffers/images */ - assert(!isl_drm_modifier_has_aux(parent->modifier)); - f = parent->planar_format; - if (plane >= f->nplanes) - return NULL; + width = parent->width; + height = parent->height; - width = parent->width >> f->planes[plane].width_shift; - height = parent->height >> f->planes[plane].height_shift; + const struct intel_image_format *f = parent->planar_format; + + if (f && plane < f->nplanes) { + /* Use the planar format definition. */ + width >>= f->planes[plane].width_shift; + height >>= f->planes[plane].height_shift; dri_format = f->planes[plane].dri_format; - index = f->planes[plane].buffer_index; + int index = f->planes[plane].buffer_index; offset = parent->offsets[index]; stride = parent->strides[index]; + } else if (plane == 0) { + /* The only plane of a non-planar image: copy the parent definition + * directly. */ + dri_format = parent->dri_format; + offset = parent->offset; + stride = parent->pitch; + } else if (plane == 1 && parent->modifier != DRM_FORMAT_MOD_INVALID && + isl_drm_modifier_has_aux(parent->modifier)) { + /* Auxiliary plane */ + dri_format = parent->dri_format; + offset = parent->aux_offset; + stride = parent->aux_pitch; + } else { + return NULL; + } - if (offset + height * stride > parent->bo->size) { - _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds"); - return NULL; - } + if (offset + height * stride > parent->bo->size) { + _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds"); + return NULL; } image = intel_allocate_image(parent->screen, dri_format, loaderPrivate); -- 2.30.2