Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-10-22 13:58:11 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-10-22 14:00:40 +0300
commit2d084d4ec430ec8b280a52286eeeca770f2221bc (patch)
tree2436fda8529effee889b423fabb065826a791307 /source/blender/gpu/intern/gpu_extensions.c
parent0e70feab22fd0871d61a03b43c591fb300990de7 (diff)
GPU: Fix Issue with recursive downsample and Intel HDXXX
This is caused by a driver bug that prevent us from rendering to (or even binding) a texture mip level that is below GL_TEXTURE_MAX_LEVEL of the target texture. This is fine in most drivers (and legal AFAIK) but not on thoses Intels HDXXX + Windows. As a fix we just put GL_TEXTURE_MAX_LEVEL lower (which is illegal because it is undefined behaviour), but in practice it works ok and does not trigger any warnings or errors. This commit fixes most of the problems encountered on these GPUs (T56668).
Diffstat (limited to 'source/blender/gpu/intern/gpu_extensions.c')
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 198f986d06e..c95f5e5e252 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -37,8 +37,10 @@
#include "BLI_math_vector.h"
#include "BKE_global.h"
+#include "MEM_guardedalloc.h"
#include "GPU_extensions.h"
+#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_texture.h"
@@ -83,8 +85,42 @@ static struct GPUGlobal {
* number is factor on screen and second is off-screen */
float dfdyfactors[2];
float max_anisotropy;
+ /* Some Intel drivers have issues with using mips as framebuffer targets if
+ * GL_TEXTURE_MAX_LEVEL is higher than the target mip.
+ * We need a workaround in this cases. */
+ bool mip_render_workaround;
} GG = {1, 0};
+
+static void gpu_detect_mip_render_workaround(void)
+{
+ int cube_size = 2;
+ float *source_pix = MEM_callocN(sizeof(float) * 4 * 6 * cube_size * cube_size, __func__);
+ float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f};
+
+ GPUTexture *tex = GPU_texture_create_cube(cube_size, GPU_RGBA16F, source_pix, NULL);
+ MEM_freeN(source_pix);
+
+ GPU_texture_bind(tex, 0);
+ GPU_texture_generate_mipmap(tex);
+ glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, 0);
+ GPU_texture_unbind(tex);
+
+ GPUFrameBuffer *fb = GPU_framebuffer_create();
+ GPU_framebuffer_texture_attach(fb, tex, 0, 1);
+ GPU_framebuffer_bind(fb);
+ GPU_framebuffer_clear_color(fb, clear_color);
+ GPU_framebuffer_restore();
+ GPU_framebuffer_free(fb);
+
+ float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 1);
+ GG.mip_render_workaround = !equals_v4v4(clear_color, data);
+
+ MEM_freeN(data);
+ GPU_texture_free(tex);
+}
+
/* GPU Types */
bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
@@ -154,6 +190,11 @@ void GPU_get_dfdy_factors(float fac[2])
copy_v2_v2(fac, GG.dfdyfactors);
}
+bool GPU_mip_render_workaround(void)
+{
+ return GG.mip_render_workaround;
+}
+
void gpu_extensions_init(void)
{
/* during 2.8 development each platform has its own OpenGL minimum requirements
@@ -253,6 +294,7 @@ void gpu_extensions_init(void)
GG.os = GPU_OS_UNIX;
#endif
+ gpu_detect_mip_render_workaround();
/* df/dy calculation factors, those are dependent on driver */
if ((strstr(vendor, "ATI") && strstr(version, "3.3.10750"))) {