diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_extensions.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_extensions.c | 448 |
1 files changed, 0 insertions, 448 deletions
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c deleted file mode 100644 index 9aa3becef1d..00000000000 --- a/source/blender/gpu/intern/gpu_extensions.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2005 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup gpu - * - * Wrap OpenGL features such as textures, shaders and GLSL - * with checks for drivers and GPU support. - */ - -#include "BLI_math_base.h" -#include "BLI_math_vector.h" -#include "BLI_utildefines.h" - -#include "BKE_global.h" -#include "MEM_guardedalloc.h" - -#include "GPU_extensions.h" -#include "GPU_framebuffer.h" -#include "GPU_glew.h" -#include "GPU_platform.h" -#include "GPU_texture.h" - -#include "intern/gpu_private.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef WIN32 -# include "BLI_winstuff.h" -#endif - -/* Extensions support */ - -/* -- extension: version of GL that absorbs it - * EXT_gpu_shader4: 3.0 - * ARB_framebuffer object: 3.0 - * EXT_framebuffer_multisample_blit_scaled: ??? - * ARB_draw_instanced: 3.1 - * ARB_texture_multisample: 3.2 - * ARB_texture_query_lod: 4.0 - */ - -static struct GPUGlobal { - GLint maxtexsize; - GLint maxtexlayers; - GLint maxcubemapsize; - GLint maxtextures; - GLint maxtexturesfrag; - GLint maxtexturesgeom; - GLint maxtexturesvert; - GLint maxubosize; - GLint maxubobinds; - int samples_color_texture_max; - float line_width_range[2]; - /* workaround for different calculation of dfdy factors on GPUs. Some GPUs/drivers - * calculate dfdy in shader differently when drawing to an off-screen buffer. First - * number is factor on screen and second is off-screen */ - float dfdyfactors[2]; - float max_anisotropy; - /* Some Intel drivers have limited support for `GLEW_ARB_base_instance` so in - * these cases it is best to indicate that it is not supported. See T67951 */ - bool glew_arb_base_instance_is_supported; - /* Cubemap Array support. */ - bool glew_arb_texture_cube_map_array_is_supported; - /* 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; - /* There is an issue with the #glBlitFramebuffer on MacOS with radeon pro graphics. - * Blitting depth with#GL_DEPTH24_STENCIL8 is buggy so the workaround is to use - * #GPU_DEPTH32F_STENCIL8. Then Blitting depth will work but blitting stencil will - * still be broken. */ - bool depth_blitting_workaround; - /* Crappy driver don't know how to map framebuffer slot to output vars... - * We need to have no "holes" in the output buffer slots. */ - bool unused_fb_slot_workaround; - bool broken_amd_driver; - /* Some crappy Intel drivers don't work well with shaders created in different - * rendering contexts. */ - bool context_local_shaders_workaround; - /* Intel drivers exhibit artifacts when using #glCopyImageSubData & workbench anti-aliasing. - * (see T76273) */ - bool texture_copy_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 Extensions */ - -int GPU_max_texture_size(void) -{ - return GG.maxtexsize; -} - -int GPU_max_texture_layers(void) -{ - return GG.maxtexlayers; -} - -int GPU_max_textures(void) -{ - return GG.maxtextures; -} - -int GPU_max_textures_frag(void) -{ - return GG.maxtexturesfrag; -} - -int GPU_max_textures_geom(void) -{ - return GG.maxtexturesgeom; -} - -int GPU_max_textures_vert(void) -{ - return GG.maxtexturesvert; -} - -float GPU_max_texture_anisotropy(void) -{ - return GG.max_anisotropy; -} - -int GPU_max_color_texture_samples(void) -{ - return GG.samples_color_texture_max; -} - -int GPU_max_cube_map_size(void) -{ - return GG.maxcubemapsize; -} - -int GPU_max_ubo_binds(void) -{ - return GG.maxubobinds; -} - -int GPU_max_ubo_size(void) -{ - return GG.maxubosize; -} - -float GPU_max_line_width(void) -{ - return GG.line_width_range[1]; -} - -void GPU_get_dfdy_factors(float fac[2]) -{ - copy_v2_v2(fac, GG.dfdyfactors); -} - -bool GPU_arb_base_instance_is_supported(void) -{ - return GG.glew_arb_base_instance_is_supported; -} - -bool GPU_arb_texture_cube_map_array_is_supported(void) -{ - return GG.glew_arb_texture_cube_map_array_is_supported; -} - -bool GPU_mip_render_workaround(void) -{ - return GG.mip_render_workaround; -} - -bool GPU_depth_blitting_workaround(void) -{ - return GG.depth_blitting_workaround; -} - -bool GPU_unused_fb_slot_workaround(void) -{ - return GG.unused_fb_slot_workaround; -} - -bool GPU_context_local_shaders_workaround(void) -{ - return GG.context_local_shaders_workaround; -} - -bool GPU_texture_copy_workaround(void) -{ - return GG.texture_copy_workaround; -} - -bool GPU_crappy_amd_driver(void) -{ - /* Currently are the same drivers with the `unused_fb_slot` problem. */ - return GG.broken_amd_driver; -} - -void gpu_extensions_init(void) -{ - /* during 2.8 development each platform has its own OpenGL minimum requirements - * final 2.8 release will be unified on OpenGL 3.3 core profile, no required extensions - * see developer.blender.org/T49012 for details - */ - BLI_assert(GLEW_VERSION_3_3); - - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GG.maxtexturesfrag); - glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &GG.maxtexturesvert); - glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &GG.maxtexturesgeom); - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &GG.maxtextures); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GG.maxtexsize); - glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &GG.maxtexlayers); - glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GG.maxcubemapsize); - - if (GLEW_EXT_texture_filter_anisotropic) { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &GG.max_anisotropy); - } - else { - GG.max_anisotropy = 1.0f; - } - - glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &GG.maxubobinds); - glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GG.maxubosize); - - glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, GG.line_width_range); - - glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &GG.samples_color_texture_max); - - const char *vendor = (const char *)glGetString(GL_VENDOR); - const char *renderer = (const char *)glGetString(GL_RENDERER); - const char *version = (const char *)glGetString(GL_VERSION); - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) { - if (strstr(version, "4.5.13399") || strstr(version, "4.5.13417") || - strstr(version, "4.5.13422")) { - /* The renderers include: - * Mobility Radeon HD 5000; - * Radeon HD 7500M; - * Radeon HD 7570M; - * Radeon HD 7600M; - * And many others... */ - - GG.unused_fb_slot_workaround = true; - GG.broken_amd_driver = true; - } - } - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && - strstr(renderer, "AMD VERDE")) { - /* We have issues with this specific renderer. (see T74024) */ - GG.unused_fb_slot_workaround = true; - GG.broken_amd_driver = true; - } - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && - strstr(version, "Mesa 19.3.4")) { - /* Fix slowdown on this particular driver. (see T77641) */ - GG.broken_amd_driver = true; - } - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { - if (strstr(renderer, "AMD Radeon Pro") || strstr(renderer, "AMD Radeon R9") || - strstr(renderer, "AMD Radeon RX")) { - GG.depth_blitting_workaround = true; - } - } - - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) { - /* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are - * covered since they only support GL 4.4 on windows. - * This fixes some issues with workbench antialiasing on Win + Intel GPU. (see T76273) */ - if (!GLEW_VERSION_4_5) { - GG.texture_copy_workaround = true; - } - } - - /* Limit support for GLEW_ARB_base_instance to OpenGL 4.0 and higher. NVIDIA Quadro FX 4800 - * (TeraScale) report that they support GLEW_ARB_base_instance, but the driver does not support - * GLEW_ARB_draw_indirect as it has an OpenGL3 context what also matches the minimum needed - * requirements. - * - * We use it as a target for glMapBuffer(Range) what is part of the OpenGL 4 API. So better - * disable it when we don't have an OpenGL4 context (See T77657) */ - GG.glew_arb_base_instance_is_supported = GLEW_ARB_base_instance && GLEW_VERSION_4_0; - GG.glew_arb_texture_cube_map_array_is_supported = GLEW_ARB_texture_cube_map_array; - gpu_detect_mip_render_workaround(); - - if (G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS) { - printf("\n"); - printf("GPU: Bypassing workaround detection.\n"); - printf("GPU: OpenGL identification strings\n"); - printf("GPU: vendor: %s\n", vendor); - printf("GPU: renderer: %s\n", renderer); - printf("GPU: version: %s\n\n", version); - GG.mip_render_workaround = true; - GG.depth_blitting_workaround = true; - GG.unused_fb_slot_workaround = true; - GG.texture_copy_workaround = true; - } - - /* Special fix for theses specific GPUs. - * Without this workaround, blender crashes on startup. (see T72098) */ - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && - (strstr(renderer, "HD Graphics 620") || strstr(renderer, "HD Graphics 630"))) { - GG.mip_render_workaround = true; - } - - /* Intel Ivy Bridge GPU's seems to have buggy cube-map array support. (see T75943) */ - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && - (strstr(renderer, "HD Graphics 4000") || strstr(renderer, "HD Graphics 4400") || - strstr(renderer, "HD Graphics 2500"))) { - GG.glew_arb_texture_cube_map_array_is_supported = false; - } - - /* df/dy calculation factors, those are dependent on driver */ - GG.dfdyfactors[0] = 1.0; - GG.dfdyfactors[1] = 1.0; - - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY) && - strstr(version, "3.3.10750")) { - GG.dfdyfactors[0] = 1.0; - GG.dfdyfactors[1] = -1.0; - } - else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY)) { - if (strstr(version, "4.0.0 - Build 10.18.10.3308") || - strstr(version, "4.0.0 - Build 9.18.10.3186") || - strstr(version, "4.0.0 - Build 9.18.10.3165") || - strstr(version, "3.1.0 - Build 9.17.10.3347") || - strstr(version, "3.1.0 - Build 9.17.10.4101") || - strstr(version, "3.3.0 - Build 8.15.10.2618")) { - GG.dfdyfactors[0] = -1.0; - GG.dfdyfactors[1] = 1.0; - } - - if (strstr(version, "Build 10.18.10.3") || strstr(version, "Build 10.18.10.4") || - strstr(version, "Build 10.18.10.5") || strstr(version, "Build 10.18.14.4") || - strstr(version, "Build 10.18.14.5")) { - /* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`. - * But it's hard to test each case. */ - GG.glew_arb_base_instance_is_supported = false; - GG.context_local_shaders_workaround = true; - } - - if (strstr(version, "Build 20.19.15.4285")) { - /* Somehow fixes armature display issues (see T69743). */ - GG.context_local_shaders_workaround = true; - } - } - else if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && - (strstr(version, "Mesa 18.") || strstr(version, "Mesa 19.0") || - strstr(version, "Mesa 19.1") || strstr(version, "Mesa 19.2"))) { - /* See T70187: merging vertices fail. This has been tested from 18.2.2 till 19.3.0~dev of the - * Mesa driver */ - GG.unused_fb_slot_workaround = true; - } - - GPU_invalid_tex_init(); - GPU_samplers_init(); -} - -void gpu_extensions_exit(void) -{ - GPU_invalid_tex_free(); - GPU_samplers_free(); -} - -bool GPU_mem_stats_supported(void) -{ -#ifndef GPU_STANDALONE - return (GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo); -#else - return false; -#endif -} - -void GPU_mem_stats_get(int *totalmem, int *freemem) -{ - /* TODO(merwin): use Apple's platform API to get this info */ - - if (GLEW_NVX_gpu_memory_info) { - /* returned value in Kb */ - glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, totalmem); - - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, freemem); - } - else if (GLEW_ATI_meminfo) { - int stats[4]; - - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats); - *freemem = stats[0]; - *totalmem = 0; - } - else { - *totalmem = 0; - *freemem = 0; - } -} - -/* Return support for the active context + window. */ -bool GPU_stereo_quadbuffer_support(void) -{ - GLboolean stereo = GL_FALSE; - glGetBooleanv(GL_STEREO, &stereo); - return stereo == GL_TRUE; -} |