Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_extensions.c
| Show All 29 Lines | |||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "GPU_extensions.h" | #include "GPU_extensions.h" | ||||
| #include "GPU_framebuffer.h" | #include "GPU_framebuffer.h" | ||||
| #include "GPU_glew.h" | #include "GPU_glew.h" | ||||
| #include "GPU_texture.h" | #include "GPU_texture.h" | ||||
| #include "GPU_platform.h" | |||||
| #include "intern/gpu_private.h" | #include "intern/gpu_private.h" | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| Show All 17 Lines | static struct GPUGlobal { | ||||
| GLint maxcubemapsize; | GLint maxcubemapsize; | ||||
| GLint maxtextures; | GLint maxtextures; | ||||
| GLint maxtexturesfrag; | GLint maxtexturesfrag; | ||||
| GLint maxtexturesgeom; | GLint maxtexturesgeom; | ||||
| GLint maxtexturesvert; | GLint maxtexturesvert; | ||||
| GLint maxubosize; | GLint maxubosize; | ||||
| GLint maxubobinds; | GLint maxubobinds; | ||||
| int samples_color_texture_max; | int samples_color_texture_max; | ||||
| eGPUDeviceType device; | |||||
| eGPUOSType os; | |||||
| eGPUDriverType driver; | |||||
| float line_width_range[2]; | float line_width_range[2]; | ||||
| /* workaround for different calculation of dfdy factors on GPUs. Some GPUs/drivers | /* workaround for different calculation of dfdy factors on GPUs. Some GPUs/drivers | ||||
| * calculate dfdy in shader differently when drawing to an offscreen buffer. First | * calculate dfdy in shader differently when drawing to an offscreen buffer. First | ||||
| * number is factor on screen and second is off-screen */ | * number is factor on screen and second is off-screen */ | ||||
| float dfdyfactors[2]; | float dfdyfactors[2]; | ||||
| float max_anisotropy; | float max_anisotropy; | ||||
| /* Some Intel drivers have limited support for `GLEW_ARB_base_instance` so in | /* 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 */ | * these cases it is best to indicate that it is not supported. See T67951 */ | ||||
| Show All 39 Lines | static void gpu_detect_mip_render_workaround(void) | ||||
| float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 1); | float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 1); | ||||
| GG.mip_render_workaround = !equals_v4v4(clear_color, data); | GG.mip_render_workaround = !equals_v4v4(clear_color, data); | ||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| GPU_texture_free(tex); | GPU_texture_free(tex); | ||||
| } | } | ||||
| /* GPU Types */ | |||||
| bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver) | |||||
| { | |||||
| return (GG.device & device) && (GG.os & os) && (GG.driver & driver); | |||||
| } | |||||
| /* GPU Extensions */ | /* GPU Extensions */ | ||||
| int GPU_max_texture_size(void) | int GPU_max_texture_size(void) | ||||
| { | { | ||||
| return GG.maxtexsize; | return GG.maxtexsize; | ||||
| } | } | ||||
| int GPU_max_texture_layers(void) | int GPU_max_texture_layers(void) | ||||
| ▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | void gpu_extensions_init(void) | ||||
| glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, GG.line_width_range); | glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, GG.line_width_range); | ||||
| glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &GG.samples_color_texture_max); | glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &GG.samples_color_texture_max); | ||||
| const char *vendor = (const char *)glGetString(GL_VENDOR); | const char *vendor = (const char *)glGetString(GL_VENDOR); | ||||
| const char *renderer = (const char *)glGetString(GL_RENDERER); | const char *renderer = (const char *)glGetString(GL_RENDERER); | ||||
| const char *version = (const char *)glGetString(GL_VERSION); | const char *version = (const char *)glGetString(GL_VERSION); | ||||
| if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) { | if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) { | ||||
| GG.device = GPU_DEVICE_ATI; | |||||
| GG.driver = GPU_DRIVER_OFFICIAL; | |||||
| #ifdef _WIN32 | |||||
| if (strstr(version, "4.5.13399") || strstr(version, "4.5.13417") || | if (strstr(version, "4.5.13399") || strstr(version, "4.5.13417") || | ||||
| strstr(version, "4.5.13422")) { | strstr(version, "4.5.13422")) { | ||||
| /* The renderers include: | /* The renderers include: | ||||
| * Mobility Radeon HD 5000; | * Mobility Radeon HD 5000; | ||||
| * Radeon HD 7500M; | * Radeon HD 7500M; | ||||
| * Radeon HD 7570M; | * Radeon HD 7570M; | ||||
| * Radeon HD 7600M; | * Radeon HD 7600M; | ||||
| * And many others... */ | * And many others... */ | ||||
| GG.unused_fb_slot_workaround = true; | GG.unused_fb_slot_workaround = true; | ||||
| } | } | ||||
| #endif | } | ||||
| #if defined(__APPLE__) | if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { | ||||
| if (strstr(renderer, "AMD Radeon Pro") || strstr(renderer, "AMD Radeon R9") || | if (strstr(renderer, "AMD Radeon Pro") || strstr(renderer, "AMD Radeon R9") || | ||||
| strstr(renderer, "AMD Radeon RX")) { | strstr(renderer, "AMD Radeon RX")) { | ||||
| GG.depth_blitting_workaround = true; | GG.depth_blitting_workaround = true; | ||||
| } | } | ||||
| #endif | |||||
| } | |||||
| else if (strstr(vendor, "NVIDIA")) { | |||||
| GG.device = GPU_DEVICE_NVIDIA; | |||||
| GG.driver = GPU_DRIVER_OFFICIAL; | |||||
| } | |||||
| else if (strstr(vendor, "Intel") || | |||||
| /* src/mesa/drivers/dri/intel/intel_context.c */ | |||||
| strstr(renderer, "Mesa DRI Intel") || strstr(renderer, "Mesa DRI Mobile Intel")) { | |||||
| GG.device = GPU_DEVICE_INTEL; | |||||
| GG.driver = GPU_DRIVER_OFFICIAL; | |||||
| if (strstr(renderer, "UHD Graphics") || | |||||
| /* Not UHD but affected by the same bugs. */ | |||||
| strstr(renderer, "HD Graphics 530") || strstr(renderer, "Kaby Lake GT2")) { | |||||
| GG.device |= GPU_DEVICE_INTEL_UHD; | |||||
| } | |||||
| } | |||||
| else if ((strstr(renderer, "Mesa DRI R")) || | |||||
| (strstr(renderer, "Radeon") && strstr(vendor, "X.Org")) || | |||||
| (strstr(renderer, "AMD") && strstr(vendor, "X.Org")) || | |||||
| (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")) || | |||||
| (strstr(renderer, "Gallium ") && strstr(renderer, " on AMD "))) { | |||||
| GG.device = GPU_DEVICE_ATI; | |||||
| GG.driver = GPU_DRIVER_OPENSOURCE; | |||||
| } | |||||
| else if (strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) { | |||||
| GG.device = GPU_DEVICE_NVIDIA; | |||||
| GG.driver = GPU_DRIVER_OPENSOURCE; | |||||
| } | |||||
| else if (strstr(vendor, "Mesa")) { | |||||
| GG.device = GPU_DEVICE_SOFTWARE; | |||||
| GG.driver = GPU_DRIVER_SOFTWARE; | |||||
| } | |||||
| else if (strstr(vendor, "Microsoft")) { | |||||
| GG.device = GPU_DEVICE_SOFTWARE; | |||||
| GG.driver = GPU_DRIVER_SOFTWARE; | |||||
| } | |||||
| else if (strstr(renderer, "Apple Software Renderer")) { | |||||
| GG.device = GPU_DEVICE_SOFTWARE; | |||||
| GG.driver = GPU_DRIVER_SOFTWARE; | |||||
| } | |||||
| else if (strstr(renderer, "llvmpipe")) { | |||||
| GG.device = GPU_DEVICE_SOFTWARE; | |||||
| GG.driver = GPU_DRIVER_SOFTWARE; | |||||
| } | |||||
| else { | |||||
| printf("Warning: Could not find a matching GPU name. Things may not behave as expected.\n"); | |||||
| printf("Detected OpenGL configuration:\n"); | |||||
| printf("Vendor: %s\n", vendor); | |||||
| printf("Renderer: %s\n", renderer); | |||||
| GG.device = GPU_DEVICE_ANY; | |||||
| GG.driver = GPU_DRIVER_ANY; | |||||
| } | } | ||||
| #ifdef _WIN32 | |||||
| GG.os = GPU_OS_WIN; | |||||
| #elif defined(__APPLE__) | |||||
| GG.os = GPU_OS_MAC; | |||||
| #else | |||||
| GG.os = GPU_OS_UNIX; | |||||
| #endif | |||||
| GG.glew_arb_base_instance_is_supported = GLEW_ARB_base_instance; | GG.glew_arb_base_instance_is_supported = GLEW_ARB_base_instance; | ||||
| gpu_detect_mip_render_workaround(); | gpu_detect_mip_render_workaround(); | ||||
| if (G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS) { | if (G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS) { | ||||
| printf("\n"); | printf("\n"); | ||||
| printf("GPU: Bypassing workaround detection.\n"); | printf("GPU: Bypassing workaround detection.\n"); | ||||
| printf("GPU: OpenGL identification strings\n"); | printf("GPU: OpenGL identification strings\n"); | ||||
| printf("GPU: vendor: %s\n", vendor); | printf("GPU: vendor: %s\n", vendor); | ||||
| printf("GPU: renderer: %s\n", renderer); | printf("GPU: renderer: %s\n", renderer); | ||||
| printf("GPU: version: %s\n\n", version); | printf("GPU: version: %s\n\n", version); | ||||
| GG.mip_render_workaround = true; | GG.mip_render_workaround = true; | ||||
| GG.depth_blitting_workaround = true; | GG.depth_blitting_workaround = true; | ||||
| GG.unused_fb_slot_workaround = true; | GG.unused_fb_slot_workaround = true; | ||||
| GG.context_local_shaders_workaround = GLEW_ARB_get_program_binary; | GG.context_local_shaders_workaround = GLEW_ARB_get_program_binary; | ||||
| } | } | ||||
| /* df/dy calculation factors, those are dependent on driver */ | /* df/dy calculation factors, those are dependent on driver */ | ||||
| GG.dfdyfactors[0] = 1.0; | GG.dfdyfactors[0] = 1.0; | ||||
| GG.dfdyfactors[1] = 1.0; | GG.dfdyfactors[1] = 1.0; | ||||
| if ((strstr(vendor, "ATI") && strstr(version, "3.3.10750"))) { | 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[0] = 1.0; | ||||
| GG.dfdyfactors[1] = -1.0; | GG.dfdyfactors[1] = -1.0; | ||||
| } | } | ||||
| else if ((GG.device == GPU_DEVICE_INTEL) && (GG.os == GPU_OS_WIN)) { | 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") || | 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.3186") || | ||||
| strstr(version, "4.0.0 - Build 9.18.10.3165") || | 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.3347") || | ||||
| strstr(version, "3.1.0 - Build 9.17.10.4101") || | strstr(version, "3.1.0 - Build 9.17.10.4101") || | ||||
| strstr(version, "3.3.0 - Build 8.15.10.2618")) { | strstr(version, "3.3.0 - Build 8.15.10.2618")) { | ||||
| GG.dfdyfactors[0] = -1.0; | GG.dfdyfactors[0] = -1.0; | ||||
| GG.dfdyfactors[1] = 1.0; | GG.dfdyfactors[1] = 1.0; | ||||
| } | } | ||||
| if (strstr(version, "Build 10.18.10.3") || strstr(version, "Build 10.18.10.4") || | 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.10.5") || strstr(version, "Build 10.18.14.4") || | ||||
| strstr(version, "Build 10.18.14.5")) { | strstr(version, "Build 10.18.14.5")) { | ||||
| /* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`. | /* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`. | ||||
| * But it's hard to test each case. */ | * But it's hard to test each case. */ | ||||
| GG.glew_arb_base_instance_is_supported = false; | GG.glew_arb_base_instance_is_supported = false; | ||||
| GG.context_local_shaders_workaround = true; | GG.context_local_shaders_workaround = true; | ||||
| } | } | ||||
| if (strstr(version, "Build 20.19.15.4285")) { | if (strstr(version, "Build 20.19.15.4285")) { | ||||
| /* Somehow fixes armature display issues (see T69743). */ | /* Somehow fixes armature display issues (see T69743). */ | ||||
| GG.context_local_shaders_workaround = true; | GG.context_local_shaders_workaround = true; | ||||
| } | } | ||||
| } | } | ||||
| else if ((GG.device == GPU_DEVICE_ATI) && (GG.os == GPU_OS_UNIX) && | else if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) { | ||||
| (GG.driver == GPU_DRIVER_OPENSOURCE)) { | |||||
| /* See T70187: merging vertices fail. This has been tested from 18.2.2 till 19.3.0~dev of the | /* See T70187: merging vertices fail. This has been tested from 18.2.2 till 19.3.0~dev of the | ||||
| * Mesa driver */ | * Mesa driver */ | ||||
| GG.unused_fb_slot_workaround = true; | GG.unused_fb_slot_workaround = true; | ||||
| } | } | ||||
| GPU_invalid_tex_init(); | GPU_invalid_tex_init(); | ||||
| } | } | ||||
| Show All 32 Lines | |||||