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:
parent
e10618f6f5
commit
1a099cb90b
|
@ -126,13 +126,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
|
||||||
else
|
else
|
||||||
lpr->row_stride[level] = align(nblocksx * block_size, util_get_cpu_caps()->cacheline);
|
lpr->row_stride[level] = align(nblocksx * block_size, util_get_cpu_caps()->cacheline);
|
||||||
|
|
||||||
/* if row_stride * height > LP_MAX_TEXTURE_SIZE */
|
lpr->img_stride[level] = (uint64_t)lpr->row_stride[level] * nblocksy;
|
||||||
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;
|
|
||||||
|
|
||||||
/* Number of 3D image slices, cube faces or texture array layers */
|
/* Number of 3D image slices, cube faces or texture array layers */
|
||||||
if (lpr->base.target == PIPE_TEXTURE_CUBE) {
|
if (lpr->base.target == PIPE_TEXTURE_CUBE) {
|
||||||
|
@ -149,19 +143,10 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
|
||||||
else
|
else
|
||||||
num_slices = 1;
|
num_slices = 1;
|
||||||
|
|
||||||
/* if img_stride * num_slices_faces > LP_MAX_TEXTURE_SIZE */
|
mipsize = lpr->img_stride[level] * num_slices;
|
||||||
mipsize = (uint64_t)lpr->img_stride[level] * num_slices;
|
|
||||||
if (mipsize > LP_MAX_TEXTURE_SIZE) {
|
|
||||||
/* volume too large */
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
lpr->mip_offsets[level] = total_size;
|
lpr->mip_offsets[level] = total_size;
|
||||||
|
|
||||||
total_size += align((unsigned)mipsize, mip_align);
|
total_size += align64(mipsize, mip_align);
|
||||||
if (total_size > LP_MAX_TEXTURE_SIZE) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute size of next mipmap level */
|
/* Compute size of next mipmap level */
|
||||||
width = u_minify(width, 1);
|
width = u_minify(width, 1);
|
||||||
|
@ -174,6 +159,9 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
|
||||||
|
|
||||||
lpr->size_required = total_size;
|
lpr->size_required = total_size;
|
||||||
if (allocate) {
|
if (allocate) {
|
||||||
|
if (total_size > LP_MAX_TEXTURE_SIZE)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
lpr->tex_data = align_malloc(total_size, mip_align);
|
lpr->tex_data = align_malloc(total_size, mip_align);
|
||||||
if (!lpr->tex_data) {
|
if (!lpr->tex_data) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -201,7 +189,10 @@ llvmpipe_can_create_resource(struct pipe_screen *screen,
|
||||||
struct llvmpipe_resource lpr;
|
struct llvmpipe_resource lpr;
|
||||||
memset(&lpr, 0, sizeof(lpr));
|
memset(&lpr, 0, sizeof(lpr));
|
||||||
lpr.base = *res;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,11 +63,11 @@ struct llvmpipe_resource
|
||||||
/** Row stride in bytes */
|
/** Row stride in bytes */
|
||||||
unsigned row_stride[LP_MAX_TEXTURE_LEVELS];
|
unsigned row_stride[LP_MAX_TEXTURE_LEVELS];
|
||||||
/** Image stride (for cube maps, array or 3D textures) in bytes */
|
/** 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 */
|
/** 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) */
|
/** 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
|
* Display target, for textures with the PIPE_BIND_DISPLAY_TARGET
|
||||||
|
|
Loading…
Reference in New Issue