diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 924881c7030..c0a612cd067 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -105,7 +105,8 @@ alloc_layout_array(unsigned num_slices, unsigned width, unsigned height) */ static boolean llvmpipe_texture_layout(struct llvmpipe_screen *screen, - struct llvmpipe_resource *lpr) + struct llvmpipe_resource *lpr, + boolean allocate) { struct pipe_resource *pt = &lpr->base; unsigned level; @@ -163,9 +164,11 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, lpr->num_slices_faces[level] = num_slices; - lpr->layout[level] = alloc_layout_array(num_slices, width, height); - if (!lpr->layout[level]) { - goto fail; + if (allocate) { + lpr->layout[level] = alloc_layout_array(num_slices, width, height); + if (!lpr->layout[level]) { + goto fail; + } } } @@ -191,6 +194,20 @@ fail: } +/** + * Check the size of the texture specified by 'res'. + * \return TRUE if OK, FALSE if too large. + */ +static boolean +llvmpipe_can_create_resource(struct pipe_screen *screen, + const struct pipe_resource *res) +{ + struct llvmpipe_resource lpr; + memset(&lpr, 0, sizeof(lpr)); + lpr.base = *res; + return llvmpipe_texture_layout(llvmpipe_screen(screen), &lpr, FALSE); +} + static boolean llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, @@ -264,7 +281,7 @@ llvmpipe_resource_create(struct pipe_screen *_screen, } else { /* texture map */ - if (!llvmpipe_texture_layout(screen, lpr)) + if (!llvmpipe_texture_layout(screen, lpr, TRUE)) goto fail; assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE); } @@ -1436,6 +1453,7 @@ llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen) screen->resource_destroy = llvmpipe_resource_destroy; screen->resource_from_handle = llvmpipe_resource_from_handle; screen->resource_get_handle = llvmpipe_resource_get_handle; + screen->can_create_resource = llvmpipe_can_create_resource; }