From 2e1498ff16198742ba543004fd9c2c49083a6095 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 16 Nov 2020 09:44:41 +0100 Subject: Fix T82042: Crash when rendering huge images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Crash is related to the definition of the GL_MAX_TEXTURE_SIZE. OpenGL does not clearly defined `GL_MAX_TEXTURE_SIZE` exactly means. Both on AMD and NVIDIA we have issues with huge textures that they don't get created even if they are smaller. (See {D9530} for research). This patch will try to create the texture in a smaller size when the texture creation failed. Final implementation by: Clément Foucault We should create a solution that doesn't need downscaling. For this specific case ARB_sparse_texture might help to create cleaner code, but you still have to commit the whole image what introduces several draw calls. Other improvement is to optimize the scaling; current implementation isn't optimized for performance. Reviewed By: Clément Foucault Differential Revision: https://developer.blender.org/D9524 --- source/blender/imbuf/intern/util_gpu.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source/blender/imbuf') diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 607ab95f0b4..3dd7e52a638 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -222,7 +222,7 @@ GPUTexture *IMB_create_gpu_texture(const char *name, bool use_premult) { GPUTexture *tex = NULL; - const int size[2] = {GPU_texture_size_with_limit(ibuf->x), GPU_texture_size_with_limit(ibuf->y)}; + int size[2] = {GPU_texture_size_with_limit(ibuf->x), GPU_texture_size_with_limit(ibuf->y)}; bool do_rescale = (ibuf->x != size[0]) || (ibuf->y != size[1]); #ifdef WITH_DDS @@ -263,10 +263,16 @@ GPUTexture *IMB_create_gpu_texture(const char *name, const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8); bool freebuf = false; - void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf); - /* Create Texture. */ tex = GPU_texture_create_2d(name, UNPACK2(size), 9999, tex_format, NULL); + if (tex == NULL) { + size[0] = max_ii(1, size[0] / 2); + size[1] = max_ii(1, size[1] / 2); + tex = GPU_texture_create_2d(name, UNPACK2(size), 9999, tex_format, NULL); + do_rescale = true; + } + BLI_assert(tex != NULL); + void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf); GPU_texture_update(tex, data_format, data); GPU_texture_anisotropic_filter(tex, true); -- cgit v1.2.3