i965: Fix aux-surface size check

The previous commit reworked the checks intel_from_planar() to check the
right individual cases for regular/planar/aux buffers, and do size
checks in all cases.

Unfortunately, the aux size check was broken, and required the aux
surface to be allocated with the correct aux stride, but full image
height (!).

As the ISL aux surface is not recorded in the DRIimage, we cannot easily
access it to check. Instead, store the aux size from when we do have the
ISL surface to hand, and check against that later when we go to access
the aux surface.

Signed-off-by: Daniel Stone <daniels@collabora.com>
Fixes: c2c4e5bae3 ("i965: Fix bugs in intel_from_planar")
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
Daniel Stone 2018-02-15 15:04:51 +00:00
parent 931ec80eeb
commit 9d21dbeb88
2 changed files with 12 additions and 3 deletions

View File

@ -98,6 +98,9 @@ struct __DRIimageRec {
/** Pitch of the auxiliary compression surface. */ /** Pitch of the auxiliary compression surface. */
uint32_t aux_pitch; uint32_t aux_pitch;
/** Total size in bytes of the auxiliary compression surface. */
uint32_t aux_size;
/** /**
* Provided by EGL_EXT_image_dma_buf_import. * Provided by EGL_EXT_image_dma_buf_import.
* \{ * \{

View File

@ -750,6 +750,7 @@ intel_create_image_common(__DRIscreen *dri_screen,
if (aux_surf.size) { if (aux_surf.size) {
image->aux_offset = surf.size; image->aux_offset = surf.size;
image->aux_pitch = aux_surf.row_pitch; image->aux_pitch = aux_surf.row_pitch;
image->aux_size = aux_surf.size;
} }
return image; return image;
@ -1137,6 +1138,8 @@ intel_create_image_from_fds_common(__DRIscreen *dri_screen,
return NULL; return NULL;
} }
image->aux_size = aux_surf.size;
const int end = image->aux_offset + aux_surf.size; const int end = image->aux_offset + aux_surf.size;
if (size < end) if (size < end)
size = end; size = end;
@ -1312,7 +1315,7 @@ intel_query_dma_buf_modifiers(__DRIscreen *_screen, int fourcc, int max,
static __DRIimage * static __DRIimage *
intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate) intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
{ {
int width, height, offset, stride, dri_format; int width, height, offset, stride, size, dri_format;
__DRIimage *image; __DRIimage *image;
if (parent == NULL) if (parent == NULL)
@ -1331,24 +1334,27 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
int index = f->planes[plane].buffer_index; int index = f->planes[plane].buffer_index;
offset = parent->offsets[index]; offset = parent->offsets[index];
stride = parent->strides[index]; stride = parent->strides[index];
size = height * stride;
} else if (plane == 0) { } else if (plane == 0) {
/* The only plane of a non-planar image: copy the parent definition /* The only plane of a non-planar image: copy the parent definition
* directly. */ * directly. */
dri_format = parent->dri_format; dri_format = parent->dri_format;
offset = parent->offset; offset = parent->offset;
stride = parent->pitch; stride = parent->pitch;
size = height * stride;
} else if (plane == 1 && parent->modifier != DRM_FORMAT_MOD_INVALID && } else if (plane == 1 && parent->modifier != DRM_FORMAT_MOD_INVALID &&
isl_drm_modifier_has_aux(parent->modifier)) { isl_drm_modifier_has_aux(parent->modifier)) {
/* Auxiliary plane */ /* Auxiliary plane */
dri_format = parent->dri_format; dri_format = parent->dri_format;
offset = parent->aux_offset; offset = parent->aux_offset;
stride = parent->aux_pitch; stride = parent->aux_pitch;
size = parent->aux_size;
} else { } else {
return NULL; return NULL;
} }
if (offset + height * stride > parent->bo->size) { if (offset + size > parent->bo->size) {
_mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds"); _mesa_warning(NULL, "intel_from_planar: subimage out of bounds");
return NULL; return NULL;
} }