diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_extensions.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_extensions.c | 42 |
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"))) { |