llvmpipe: allow calculating size of overly large texture

We need this for Lavapipe; we shouldn't fail to create an vkImage that
is too large, we should instead fail to allocate memory for it.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10689>
This commit is contained in:
Erik Faye-Lund 2021-05-07 13:04:00 +02:00 committed by Marge Bot
parent e10618f6f5
commit 1a099cb90b
2 changed files with 13 additions and 22 deletions

View File

@ -126,13 +126,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
else
lpr->row_stride[level] = align(nblocksx * block_size, util_get_cpu_caps()->cacheline);
/* if row_stride * height > LP_MAX_TEXTURE_SIZE */
if ((uint64_t)lpr->row_stride[level] * nblocksy > LP_MAX_TEXTURE_SIZE) {
/* image too large */
goto fail;
}
lpr->img_stride[level] = lpr->row_stride[level] * nblocksy;
lpr->img_stride[level] = (uint64_t)lpr->row_stride[level] * nblocksy;
/* Number of 3D image slices, cube faces or texture array layers */
if (lpr->base.target == PIPE_TEXTURE_CUBE) {
@ -149,19 +143,10 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
else
num_slices = 1;
/* if img_stride * num_slices_faces > LP_MAX_TEXTURE_SIZE */
mipsize = (uint64_t)lpr->img_stride[level] * num_slices;
if (mipsize > LP_MAX_TEXTURE_SIZE) {
/* volume too large */
goto fail;
}
mipsize = lpr->img_stride[level] * num_slices;
lpr->mip_offsets[level] = total_size;
total_size += align((unsigned)mipsize, mip_align);
if (total_size > LP_MAX_TEXTURE_SIZE) {
goto fail;
}
total_size += align64(mipsize, mip_align);
/* Compute size of next mipmap level */
width = u_minify(width, 1);
@ -174,6 +159,9 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
lpr->size_required = total_size;
if (allocate) {
if (total_size > LP_MAX_TEXTURE_SIZE)
goto fail;
lpr->tex_data = align_malloc(total_size, mip_align);
if (!lpr->tex_data) {
return FALSE;
@ -201,7 +189,10 @@ llvmpipe_can_create_resource(struct pipe_screen *screen,
struct llvmpipe_resource lpr;
memset(&lpr, 0, sizeof(lpr));
lpr.base = *res;
return llvmpipe_texture_layout(llvmpipe_screen(screen), &lpr, false);
if (!llvmpipe_texture_layout(llvmpipe_screen(screen), &lpr, false))
return false;
return lpr.size_required <= LP_MAX_TEXTURE_SIZE;
}

View File

@ -63,11 +63,11 @@ struct llvmpipe_resource
/** Row stride in bytes */
unsigned row_stride[LP_MAX_TEXTURE_LEVELS];
/** Image stride (for cube maps, array or 3D textures) in bytes */
unsigned img_stride[LP_MAX_TEXTURE_LEVELS];
uint64_t img_stride[LP_MAX_TEXTURE_LEVELS];
/** Offset to start of mipmap level, in bytes */
unsigned mip_offsets[LP_MAX_TEXTURE_LEVELS];
uint64_t mip_offsets[LP_MAX_TEXTURE_LEVELS];
/** allocated total size (for non-display target texture resources only) */
unsigned total_alloc_size;
uint64_t total_alloc_size;
/**
* Display target, for textures with the PIPE_BIND_DISPLAY_TARGET