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
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue