diff options
author | mano-wii <germano.costa@ig.com.br> | 2018-12-15 02:30:50 +0300 |
---|---|---|
committer | mano-wii <germano.costa@ig.com.br> | 2018-12-15 02:33:31 +0300 |
commit | ba1f178c1c85fcc2140c11cd48ccbacb60827ae4 (patch) | |
tree | 8c6b7a5c2fc3016b72b478af8399b40993516ffe /source/blender/gpu/intern | |
parent | 9fbada4a3bc66b3d5b60070da685fb5c741a56b0 (diff) |
Fix T56185, T59351: bypass GL_PROXY_TEXTURE.. test on AMD GPU + windows
This replaces the test of consistency and capacity made with `GL_PROXY_TEXTURE_..` on AMD GPUs with one that checks only if the texture fits the limits of size and layer.
Differential Revision: https://developer.blender.org/D4081
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 107 |
1 files changed, 73 insertions, 34 deletions
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index d3642c8f31b..6d9f009a80c 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -480,40 +480,86 @@ static float *GPU_texture_3D_rescale(GPUTexture *tex, int w, int h, int d, int c return nfpixels; } +static bool gpu_texture_check_capacity( + GPUTexture *tex, GLenum proxy, GLenum internalformat, + GLenum data_format, GLenum data_type) +{ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_ANY)) { + /* Some AMD drivers have a faulty `GL_PROXY_TEXTURE_..` check. + * (see T55888, T56185, T59351). + * Checking with `GL_PROXY_TEXTURE_..` doesn't prevent `Out Of Memory` issue, + * it just states that the OGL implementation can support the texture. + * So manually check the maximum size and maximum number of layers. */ + switch (proxy) { + case GL_PROXY_TEXTURE_2D_ARRAY: + if ((tex->d < 0) || (tex->d > GPU_max_texture_layers())) + return false; + break; + + case GL_PROXY_TEXTURE_1D_ARRAY: + if ((tex->h < 0) || (tex->h > GPU_max_texture_layers())) + return false; + break; + } + + switch (proxy) { + case GL_PROXY_TEXTURE_3D: + if ((tex->d < 0) || (tex->d > GPU_max_texture_size())) + return false; + ATTR_FALLTHROUGH; + + case GL_PROXY_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D_ARRAY: + if ((tex->h < 0) || (tex->h > GPU_max_texture_size())) + return false; + ATTR_FALLTHROUGH; + + case GL_PROXY_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D_ARRAY: + if ((tex->w < 0) || (tex->w > GPU_max_texture_size())) + return false; + ATTR_FALLTHROUGH; + } + + return true; + } + else { + switch (proxy) { + case GL_PROXY_TEXTURE_1D: + glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL); + break; + case GL_PROXY_TEXTURE_1D_ARRAY: + case GL_PROXY_TEXTURE_2D: + glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL); + break; + case GL_PROXY_TEXTURE_2D_ARRAY: + case GL_PROXY_TEXTURE_3D: + glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL); + break; + } + int width = 0; + glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &width); + + return (width > 0); + } +} + /* This tries to allocate video memory for a given texture * If alloc fails, lower the resolution until it fits. */ static bool gpu_texture_try_alloc( GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum data_format, GLenum data_type, int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels) { - int r_width; + bool ret; + ret = gpu_texture_check_capacity(tex, proxy, internalformat, data_format, data_type); - switch (proxy) { - case GL_PROXY_TEXTURE_1D: - glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL); - break; - case GL_PROXY_TEXTURE_1D_ARRAY: - case GL_PROXY_TEXTURE_2D: - glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL); - break; - case GL_PROXY_TEXTURE_2D_ARRAY: - /* HACK: Some driver wrongly check GL_PROXY_TEXTURE_2D_ARRAY as a GL_PROXY_TEXTURE_3D - * checking all dimensions against GPU_max_texture_layers (see T55888). */ - return (tex->w > 0) && (tex->w <= GPU_max_texture_size()) && - (tex->h > 0) && (tex->h <= GPU_max_texture_size()) && - (tex->d > 0) && (tex->d <= GPU_max_texture_layers()); - case GL_PROXY_TEXTURE_3D: - glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL); - break; - } + if (!ret && try_rescale) { + BLI_assert(!ELEM(proxy, GL_PROXY_TEXTURE_1D_ARRAY, GL_PROXY_TEXTURE_2D_ARRAY)); // not implemented - glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &r_width); - - if (r_width == 0 && try_rescale) { const int w = tex->w, h = tex->h, d = tex->d; /* Find largest texture possible */ - while (r_width == 0) { + do { tex->w /= 2; tex->h /= 2; tex->d /= 2; @@ -523,18 +569,11 @@ static bool gpu_texture_try_alloc( if (tex->h == 0 && proxy != GL_PROXY_TEXTURE_1D) break; if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break; - if (proxy == GL_PROXY_TEXTURE_1D) - glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL); - else if (proxy == GL_PROXY_TEXTURE_2D) - glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL); - else if (proxy == GL_PROXY_TEXTURE_3D) - glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL); - - glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width); - } + ret = gpu_texture_check_capacity(tex, proxy, internalformat, data_format, data_type); + } while (ret == false); /* Rescale */ - if (r_width > 0) { + if (ret) { switch (proxy) { case GL_PROXY_TEXTURE_1D: case GL_PROXY_TEXTURE_2D: @@ -548,7 +587,7 @@ static bool gpu_texture_try_alloc( } } - return (r_width > 0); + return ret; } GPUTexture *GPU_texture_create_nD( |