mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 17:58:26 +02:00
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:8f6e54c929Signed-off-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> (cherry picked from commitc2c4e5bae3) Squashed with: 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> (cherry picked from commit9d21dbeb88)
This commit is contained in:
parent
7325939b66
commit
5896feec02
2 changed files with 38 additions and 27 deletions
|
|
@ -98,6 +98,9 @@ struct __DRIimageRec {
|
|||
/** Pitch of the auxiliary compression surface. */
|
||||
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.
|
||||
* \{
|
||||
|
|
|
|||
|
|
@ -741,6 +741,7 @@ intel_create_image_common(__DRIscreen *dri_screen,
|
|||
if (aux_surf.size) {
|
||||
image->aux_offset = surf.size;
|
||||
image->aux_pitch = aux_surf.row_pitch;
|
||||
image->aux_size = aux_surf.size;
|
||||
}
|
||||
|
||||
return image;
|
||||
|
|
@ -1067,6 +1068,8 @@ intel_create_image_from_fds_common(__DRIscreen *dri_screen,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
image->aux_size = aux_surf.size;
|
||||
|
||||
const int end = image->aux_offset + aux_surf.size;
|
||||
if (size < end)
|
||||
size = end;
|
||||
|
|
@ -1242,42 +1245,47 @@ 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, size, 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];
|
||||
size = height * stride;
|
||||
} 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;
|
||||
size = height * stride;
|
||||
} 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;
|
||||
size = parent->aux_size;
|
||||
} 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 + size > parent->bo->size) {
|
||||
_mesa_warning(NULL, "intel_from_planar: subimage out of bounds");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image = intel_allocate_image(parent->screen, dri_format, loaderPrivate);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue