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: 8f6e54c929
Signed-off-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
Daniel Stone 2018-02-12 17:54:41 +00:00 committed by Jason Ekstrand
parent 1aed66dc1e
commit c2c4e5bae3

View file

@ -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;
width = parent->width;
height = parent->height;
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;
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 {
/* Planar formats don't support aux buffers/images */
assert(!isl_drm_modifier_has_aux(parent->modifier));
f = parent->planar_format;
return NULL;
}
if (plane >= f->nplanes)
return NULL;
width = parent->width >> f->planes[plane].width_shift;
height = parent->height >> f->planes[plane].height_shift;
dri_format = f->planes[plane].dri_format;
index = f->planes[plane].buffer_index;
offset = parent->offsets[index];
stride = parent->strides[index];
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);