Blender V4.5
gl_backend.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cctype>
10#include <cstdint>
11#include <cstdlib>
12#include <string>
13
14#include "BKE_global.hh"
15#if defined(WIN32)
16# include "BLI_winstuff.h"
17#endif
18#include "BLI_array.hh"
19#include "BLI_span.hh"
20#include "BLI_string_ref.hh"
21#include "BLI_subprocess.hh"
22#include "BLI_threads.h"
23#include "BLI_vector.hh"
24
25#include "DNA_userdef_types.h"
26
29
30#include "gl_debug.hh"
31
32#include "gl_backend.hh"
33
34namespace blender::gpu {
35
36/* -------------------------------------------------------------------- */
39
40static bool match_renderer(StringRef renderer, const Vector<std::string> &items)
41{
42 for (const std::string &item : items) {
43 const std::string wrapped = " " + item + " ";
44 if (renderer.endswith(item) || renderer.find(wrapped) != StringRef::not_found) {
45 return true;
46 }
47 }
48 return false;
49}
50
51static bool parse_version(const std::string &version,
52 const std::string &format,
53 Vector<int> &r_version)
54{
55 int f = 0;
56 std::string subversion;
57 for (int v : IndexRange(version.size())) {
58 bool match = false;
59 if (format[f] == '0') {
60 if (std::isdigit(version[v])) {
61 match = true;
62 subversion.push_back(version[v]);
63 }
64 }
65 else {
66 match = version[v] == format[f];
67 if (!subversion.empty()) {
68 r_version.append(std::stoi(subversion));
69 subversion.clear();
70 }
71 }
72
73 if (!match) {
74 f = 0;
75 subversion.clear();
76 r_version.clear();
77 continue;
78 }
79
80 f++;
81
82 if (f == format.size()) {
83 return true;
84 }
85 }
86
87 return false;
88}
89
90/* Try to check if the driver is older than 22.6.1, preferring false positives. */
91static bool is_bad_AMD_driver(const char *version_cstr)
92{
93 std::string version_str = version_cstr;
94 /* Allow matches when the version number is at the string end. */
95 version_str.push_back(' ');
96
97 Vector<int> version;
98
99 if (parse_version(version_str, " 00.00.00.00 ", version) ||
100 parse_version(version_str, " 00.00.00 ", version) ||
101 parse_version(version_str, " 00.00.0 ", version) ||
102 parse_version(version_str, " 00.0.00 ", version) ||
103 parse_version(version_str, " 00.Q0.", version))
104 {
105 return version[0] < 23;
106 }
107 /* Some drivers only expose the Windows version https://gpuopen.com/version-table/ */
108 if (parse_version(version_str, " 00.00.00000.00000 ", version) ||
109 parse_version(version_str, " 00.00.00000.0000 ", version) ||
110 parse_version(version_str, " 00.00.0000.00000 ", version))
111 {
112 return version[0] < 31 || (version[0] == 31 && version[2] < 21001);
113 }
114
115 /* Unknown version, assume it's a bad one. */
116 return true;
117}
118
119void GLBackend::platform_init()
120{
122
123 const char *vendor = (const char *)glGetString(GL_VENDOR);
124 const char *renderer = (const char *)glGetString(GL_RENDERER);
125 const char *version = (const char *)glGetString(GL_VERSION);
130
131#ifdef _WIN32
132 os = GPU_OS_WIN;
133#else
134 os = GPU_OS_UNIX;
135#endif
136
137 if (!vendor) {
138 printf("Warning: No OpenGL vendor detected.\n");
139 device = GPU_DEVICE_UNKNOWN;
140 driver = GPU_DRIVER_ANY;
141 }
142 else if (strstr(renderer, "Mesa DRI R") ||
143 (strstr(renderer, "Radeon") && (strstr(vendor, "X.Org") || strstr(version, "Mesa"))) ||
144 (strstr(renderer, "AMD") && (strstr(vendor, "X.Org") || strstr(version, "Mesa"))) ||
145 (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")) ||
146 (strstr(renderer, "Gallium ") && strstr(renderer, " on AMD ")))
147 {
148 device = GPU_DEVICE_ATI;
149 driver = GPU_DRIVER_OPENSOURCE;
150 }
151 else if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) {
152 device = GPU_DEVICE_ATI;
153 driver = GPU_DRIVER_OFFICIAL;
154 }
155 else if (strstr(vendor, "NVIDIA")) {
156 device = GPU_DEVICE_NVIDIA;
157 driver = GPU_DRIVER_OFFICIAL;
158 }
159 else if (strstr(vendor, "Intel") ||
160 /* src/mesa/drivers/dri/intel/intel_context.c */
161 strstr(renderer, "Mesa DRI Intel") || strstr(renderer, "Mesa DRI Mobile Intel"))
162 {
163 device = GPU_DEVICE_INTEL;
164 driver = GPU_DRIVER_OFFICIAL;
165
166 if (strstr(renderer, "UHD Graphics") ||
167 /* Not UHD but affected by the same bugs. */
168 strstr(renderer, "HD Graphics 530") || strstr(renderer, "Kaby Lake GT2") ||
169 strstr(renderer, "Whiskey Lake"))
170 {
171 device |= GPU_DEVICE_INTEL_UHD;
172 }
173 }
174 else if (strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) {
175 device = GPU_DEVICE_NVIDIA;
176 driver = GPU_DRIVER_OPENSOURCE;
177 }
178 else if (strstr(vendor, "Mesa")) {
179 device = GPU_DEVICE_SOFTWARE;
180 driver = GPU_DRIVER_SOFTWARE;
181 }
182 else if (strstr(vendor, "Microsoft")) {
183 /* Qualcomm devices use Mesa's GLOn12, which claims to be vended by Microsoft */
184 if (strstr(renderer, "Qualcomm")) {
185 device = GPU_DEVICE_QUALCOMM;
186 driver = GPU_DRIVER_OFFICIAL;
187 }
188 else {
189 device = GPU_DEVICE_SOFTWARE;
190 driver = GPU_DRIVER_SOFTWARE;
191 }
192 }
193 else if (strstr(vendor, "Apple")) {
194 /* Apple Silicon. */
195 device = GPU_DEVICE_APPLE;
196 driver = GPU_DRIVER_OFFICIAL;
197 }
198 else if (strstr(renderer, "Apple Software Renderer")) {
199 device = GPU_DEVICE_SOFTWARE;
200 driver = GPU_DRIVER_SOFTWARE;
201 }
202 else if (strstr(renderer, "llvmpipe") || strstr(renderer, "softpipe")) {
203 device = GPU_DEVICE_SOFTWARE;
204 driver = GPU_DRIVER_SOFTWARE;
205 }
206 else {
207 printf("Warning: Could not find a matching GPU name. Things may not behave as expected.\n");
208 printf("Detected OpenGL configuration:\n");
209 printf("Vendor: %s\n", vendor);
210 printf("Renderer: %s\n", renderer);
211 }
212
213 /* Detect support level */
214 if (!(epoxy_gl_version() >= 43)) {
215 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
216 }
217 else {
218#if defined(WIN32)
219 long long driverVersion = 0;
220 if (device & GPU_DEVICE_QUALCOMM) {
221 if (BLI_windows_get_directx_driver_version(L"Qualcomm(R) Adreno(TM)", &driverVersion)) {
222 /* Parse out the driver version in format x.x.x.x */
223 WORD ver0 = (driverVersion >> 48) & 0xffff;
224 WORD ver1 = (driverVersion >> 32) & 0xffff;
225 WORD ver2 = (driverVersion >> 16) & 0xffff;
226
227 /* Any Qualcomm driver older than 30.x.x.x will never capable of running blender >= 4.0
228 * As due to an issue in D3D typed UAV load capabilities, Compute Shaders are not available
229 * 30.0.3820.x and above are capable of running blender >=4.0, but these drivers
230 * are only available on 8cx gen3 devices or newer */
231 if (ver0 < 30 || (ver0 == 30 && ver1 == 0 && ver2 < 3820)) {
232 std::cout
233 << "=====================================\n"
234 << "Qualcomm drivers older than 30.0.3820.x are not capable of running Blender 4.0\n"
235 << "If your device is older than an 8cx Gen3, you must use a 3.x LTS release.\n"
236 << "If you have an 8cx Gen3 or newer device, a driver update may be available.\n"
237 << "=====================================\n";
238 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
239 }
240 }
241 }
242#endif
243 if ((device & GPU_DEVICE_INTEL) && (os & GPU_OS_WIN)) {
244 /* Old Intel drivers with known bugs that cause material properties to crash.
245 * Version Build 10.18.14.5067 is the latest available and appears to be working
246 * ok with our workarounds, so excluded from this list. */
247 if (strstr(version, "Build 7.14") || strstr(version, "Build 7.15") ||
248 strstr(version, "Build 8.15") || strstr(version, "Build 9.17") ||
249 strstr(version, "Build 9.18") || strstr(version, "Build 10.18.10.3") ||
250 strstr(version, "Build 10.18.10.4") || strstr(version, "Build 10.18.10.5") ||
251 strstr(version, "Build 10.18.14.4"))
252 {
253 support_level = GPU_SUPPORT_LEVEL_LIMITED;
254 }
255 /* A rare GPU that has z-fighting issues in edit mode. (see #128179) */
256 if (strstr(renderer, "HD Graphics 405")) {
257 support_level = GPU_SUPPORT_LEVEL_LIMITED;
258 }
259 /* Latest Intel driver have bugs that won't allow Blender to start.
260 * Users must install different version of the driver.
261 * See #113124 for more information. */
262 if (strstr(version, "Build 20.19.15.51")) {
263 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
264 }
265 }
266 if ((device & GPU_DEVICE_ATI) && (os & GPU_OS_UNIX)) {
267 /* Platform seems to work when SB backend is disabled. This can be done
268 * by adding the environment variable `R600_DEBUG=nosb`. */
269 if (strstr(renderer, "AMD CEDAR")) {
270 support_level = GPU_SUPPORT_LEVEL_LIMITED;
271 }
272 }
273
274 /* Check SSBO bindings requirement. */
275 GLint max_ssbo_binds_vertex;
276 GLint max_ssbo_binds_fragment;
277 GLint max_ssbo_binds_compute;
278 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &max_ssbo_binds_vertex);
279 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &max_ssbo_binds_fragment);
280 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &max_ssbo_binds_compute);
281 GLint max_ssbo_binds = min_iii(
282 max_ssbo_binds_vertex, max_ssbo_binds_fragment, max_ssbo_binds_compute);
283 if (max_ssbo_binds < 12) {
284 std::cout << "Warning: Unsupported platform as it supports max " << max_ssbo_binds
285 << " SSBO binding locations\n";
286 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
287 }
288 }
289
290 /* Compute shaders have some issues with those versions (see #94936). */
291 if ((device & GPU_DEVICE_ATI) && (driver & GPU_DRIVER_OFFICIAL) &&
292 (strstr(version, "4.5.14831") || strstr(version, "4.5.14760")))
293 {
294 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
295 }
296
297 GPG.init(device,
298 os,
299 driver,
300 support_level,
302 vendor,
303 renderer,
304 version,
306
310
311 if (epoxy_has_gl_extension("GL_EXT_memory_object")) {
312 GLint number_of_devices = 0;
313 glGetIntegerv(GL_NUM_DEVICE_UUIDS_EXT, &number_of_devices);
314 /* Multiple devices could be used by the context if certain extensions like multi-cast is used.
315 * But this is not used by Blender, so this should always be 1. */
316 BLI_assert(number_of_devices == 1);
317
318 GLubyte device_uuid[GL_UUID_SIZE_EXT] = {0};
319 glGetUnsignedBytei_vEXT(GL_DEVICE_UUID_EXT, 0, device_uuid);
320 GPG.device_uuid = Array<uint8_t, 16>(Span<uint8_t>(device_uuid, GL_UUID_SIZE_EXT));
321
322 /* LUID is only supported on Windows. */
323 if (epoxy_has_gl_extension("GL_EXT_memory_object_win32") && (os & GPU_OS_WIN)) {
324 GLubyte device_luid[GL_LUID_SIZE_EXT] = {0};
325 glGetUnsignedBytevEXT(GL_DEVICE_LUID_EXT, device_luid);
326 GPG.device_luid = Array<uint8_t, 8>(Span<uint8_t>(device_luid, GL_LUID_SIZE_EXT));
327
328 GLint node_mask = 0;
329 glGetIntegerv(GL_DEVICE_NODE_MASK_EXT, &node_mask);
331 }
332 }
333}
334
335void GLBackend::platform_exit()
336{
338 GPG.clear();
339}
340
342
343/* -------------------------------------------------------------------- */
346
348{
349 int cube_size = 2;
350 float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f};
351 float *source_pix = (float *)MEM_callocN(sizeof(float[4]) * cube_size * cube_size * 6, __func__);
352
353 /* NOTE: Debug layers are not yet enabled. Force use of glGetError. */
354 debug::check_gl_error("Cubemap Workaround Start");
355 /* Not using GPU API since it is not yet fully initialized. */
356 GLuint tex, fb;
357 /* Create cubemap with 2 mip level. */
358 glGenTextures(1, &tex);
359 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
360 for (int mip = 0; mip < 2; mip++) {
361 for (int i = 0; i < 6; i++) {
362 const int width = cube_size / (1 << mip);
363 GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
364 glTexImage2D(target, mip, GL_RGBA16F, width, width, 0, GL_RGBA, GL_FLOAT, source_pix);
365 }
366 }
367 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
368 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
369 /* Attach and clear mip 1. */
370 glGenFramebuffers(1, &fb);
371 glBindFramebuffer(GL_FRAMEBUFFER, fb);
372 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1);
373 glDrawBuffer(GL_COLOR_ATTACHMENT0);
374 glClearColor(UNPACK4(clear_color));
375 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
376 glClear(GL_COLOR_BUFFER_BIT);
377 glBindFramebuffer(GL_FRAMEBUFFER, 0);
378
379 /* Read mip 1. If color is not the same as the clear_color, the rendering failed. */
380 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA, GL_FLOAT, source_pix);
381 bool enable_workaround = !equals_v4v4(clear_color, source_pix);
382 MEM_freeN(source_pix);
383
384 glDeleteFramebuffers(1, &fb);
385 glDeleteTextures(1, &tex);
386
387 debug::check_gl_error("Cubemap Workaround End9");
388
389 return enable_workaround;
390}
391
392static const char *gl_extension_get(int i)
393{
394 return (char *)glGetStringi(GL_EXTENSIONS, i);
395}
396
398{
399 const char *vendor = (const char *)glGetString(GL_VENDOR);
400 const char *renderer = (const char *)glGetString(GL_RENDERER);
401 const char *version = (const char *)glGetString(GL_VERSION);
402
403 if (G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS) {
404 printf("\n");
405 printf("GL: Forcing workaround usage and disabling extensions.\n");
406 printf(" OpenGL identification strings\n");
407 printf(" vendor: %s\n", vendor);
408 printf(" renderer: %s\n", renderer);
409 printf(" version: %s\n\n", version);
410 GCaps.depth_blitting_workaround = true;
411 GCaps.mip_render_workaround = true;
412 GCaps.stencil_clasify_buffer_workaround = true;
413 GCaps.node_link_instancing_workaround = true;
414 GCaps.line_directive_workaround = true;
416 /* Turn off Blender features. */
417 GCaps.hdr_viewport_support = false;
418 /* Turn off OpenGL 4.4 features. */
421 /* Turn off OpenGL 4.5 features. */
424 /* Turn off OpenGL 4.6 features. */
426 GCaps.shader_draw_parameters_support = false;
428 /* Although an OpenGL 4.3 feature, our implementation requires shader_draw_parameters_support.
429 * NOTE: we should untangle this by checking both features for clarity. */
431 /* Turn off extensions. */
433 /* Turn off vendor specific extensions. */
437 GCaps.stencil_export_support = false;
438 GCaps.clip_control_support = false;
439
440#if 0
441 /* Do not alter OpenGL 4.3 features.
442 * These code paths should be removed. */
444#endif
445
446 return;
447 }
448
450 (strstr(version, "4.5.13399") || strstr(version, "4.5.13417") ||
451 strstr(version, "4.5.13422") || strstr(version, "4.5.13467")))
452 {
453 /* The renderers include:
454 * Radeon HD 5000;
455 * Radeon HD 7500M;
456 * Radeon HD 7570M;
457 * Radeon HD 7600M;
458 * Radeon R5 Graphics;
459 * And others... */
461 GCaps.mip_render_workaround = true;
462 GCaps.shader_draw_parameters_support = false;
463 GCaps.broken_amd_driver = true;
464 }
465 /* We have issues with this specific renderer. (see #74024) */
467 (strstr(renderer, "AMD VERDE") || strstr(renderer, "AMD KAVERI") ||
468 strstr(renderer, "AMD TAHITI")))
469 {
471 GCaps.shader_draw_parameters_support = false;
472 GCaps.broken_amd_driver = true;
473 }
474 /* Fix slowdown on this particular driver. (see #77641) */
476 strstr(version, "Mesa 19.3.4"))
477 {
478 GCaps.shader_draw_parameters_support = false;
479 GCaps.broken_amd_driver = true;
480 }
481 /* See #82856: AMD drivers since 20.11 running on a polaris architecture doesn't support the
482 * `GL_INT_2_10_10_10_REV` data type correctly. This data type is used to pack normals and flags.
483 * The work around uses `GPU_RGBA16I`. In 22.?.? drivers this has been fixed for
484 * polaris platform. Keeping legacy platforms around just in case.
485 */
487 /* Check for AMD legacy driver. Assuming that when these drivers are used this bug is present.
488 */
489 if (is_bad_AMD_driver(version)) {
490 GCaps.use_hq_normals_workaround = true;
491 }
492 const Vector<std::string> matches = {
493 "RX550/550", "(TM) 520", "(TM) 530", "(TM) 535", "R5", "R7", "R9", "HD"};
494
495 if (match_renderer(renderer, matches)) {
496 GCaps.use_hq_normals_workaround = true;
497 }
498 }
499 /* See #132968: Legacy AMD drivers do not accept a hash after the line number and results into
500 * undefined behavior. Users have reported that the issue can go away after doing a clean
501 * install of the driver.
502 */
504 if (is_bad_AMD_driver(version)) {
505 GCaps.line_directive_workaround = true;
506 }
507 }
508
509 /* Special fix for these specific GPUs.
510 * Without this workaround, blender crashes on startup. (see #72098) */
512 (strstr(renderer, "HD Graphics 620") || strstr(renderer, "HD Graphics 630")))
513 {
514 GCaps.mip_render_workaround = true;
515 }
516 /* Maybe not all of these drivers have problems with `GL_ARB_base_instance`.
517 * But it's hard to test each case.
518 * We get crashes from some crappy Intel drivers don't work well with shaders created in
519 * different rendering contexts. */
521 (strstr(version, "Build 10.18.10.3") || strstr(version, "Build 10.18.10.4") ||
522 strstr(version, "Build 10.18.10.5") || strstr(version, "Build 10.18.14.4") ||
523 strstr(version, "Build 10.18.14.5")))
524 {
525 GCaps.use_main_context_workaround = true;
526 }
527 /* Somehow fixes armature display issues (see #69743). */
529 strstr(version, "Build 20.19.15.4285"))
530 {
531 GCaps.use_main_context_workaround = true;
532 }
533 /* Needed to avoid driver hangs on legacy AMD drivers (see #139939). */
535 is_bad_AMD_driver(version))
536 {
537 GCaps.use_main_context_workaround = true;
538 }
539 /* See #70187: merging vertices fail. This has been tested from `18.2.2` till `19.3.0~dev`
540 * of the Mesa driver */
542 (strstr(version, "Mesa 18.") || strstr(version, "Mesa 19.0") ||
543 strstr(version, "Mesa 19.1") || strstr(version, "Mesa 19.2")))
544 {
546 }
547
548 /* Draw shader parameters are broken on Qualcomm Windows ARM64 devices
549 * on Mesa version < 24.0.0 */
551 if (strstr(version, "Mesa 20.") || strstr(version, "Mesa 21.") ||
552 strstr(version, "Mesa 22.") || strstr(version, "Mesa 23."))
553 {
554 GCaps.shader_draw_parameters_support = false;
556 }
557 }
558
559/* Snapdragon X Elite devices currently have a driver bug that results in
560 * eevee rendering a black cube with anything except an emission shader
561 * if shader draw parameters are enabled (#122837) */
562#if defined(WIN32)
563 long long driverVersion = 0;
565 if (BLI_windows_get_directx_driver_version(L"Qualcomm(R) Adreno(TM)", &driverVersion)) {
566 /* Parse out the driver version */
567 WORD ver0 = (driverVersion >> 48) & 0xffff;
568
569 /* X Elite devices have GPU driver version 31, and currently no known release version of the
570 * GPU driver renders the cube correctly. This will be changed when a working driver version
571 * is released to commercial devices to only enable this flags on older drivers. */
572 if (ver0 == 31) {
573 GCaps.stencil_clasify_buffer_workaround = true;
574 }
575 }
576 }
577#endif
578
579 /* Some Intel drivers have issues with using mips as frame-buffer targets if
580 * GL_TEXTURE_MAX_LEVEL is higher than the target MIP.
581 * Only check at the end after all other workarounds because this uses the drawing code.
582 * Also after device/driver flags to avoid the check that causes pre GCN Radeon to crash. */
583 if (GCaps.mip_render_workaround == false) {
584 GCaps.mip_render_workaround = detect_mip_render_workaround();
585 }
586 /* Disable multi-draw if the base instance cannot be read. */
589 }
590 /* Enable our own incomplete debug layer if no other is available. */
591 if (GLContext::debug_layer_support == false) {
593 }
594
595 /* There is an issue in AMD official driver where we cannot use multi bind when using images. AMD
596 * is aware of the issue, but hasn't released a fix. */
599 }
600
601 /* #107642, #120273 Windows Intel iGPU (multiple generations) incorrectly report that
602 * they support image binding. But when used it results into `GL_INVALID_OPERATION` with
603 * `internal format of texture N is not supported`. */
606 }
607
608 /* #134509 Intel ARC GPU have a driver bug that break the display of batched node-links.
609 * Disabling batching fixes the issue. */
611 GCaps.node_link_instancing_workaround = true;
612 }
613
614 /* Metal-related Workarounds. */
615
616 /* Minimum Per-Vertex stride is 1 byte for OpenGL. */
617 GCaps.minimum_per_vertex_stride = 1;
618}
619
621
626
628
643
645
649
650void GLBackend::capabilities_init()
651{
652 BLI_assert(epoxy_gl_version() >= 33);
653 /* Common Capabilities. */
654 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GCaps.max_texture_size);
655 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &GCaps.max_texture_layers);
656 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_frag);
657 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_vert);
658 glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_geom);
659 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &GCaps.max_textures);
660 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &GCaps.max_uniforms_vert);
661 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &GCaps.max_uniforms_frag);
662 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &GCaps.max_batch_indices);
663 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &GCaps.max_batch_vertices);
664 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &GCaps.max_vertex_attribs);
665 glGetIntegerv(GL_MAX_VARYING_FLOATS, &GCaps.max_varying_floats);
666 glGetIntegerv(GL_MAX_IMAGE_UNITS, &GCaps.max_images);
667
668 glGetIntegerv(GL_NUM_EXTENSIONS, &GCaps.extensions_len);
670
672 GCaps.mem_stats_support = epoxy_has_gl_extension("GL_NVX_gpu_memory_info") ||
673 epoxy_has_gl_extension("GL_ATI_meminfo");
674 GCaps.shader_draw_parameters_support = epoxy_has_gl_extension("GL_ARB_shader_draw_parameters");
678
679 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &GCaps.max_work_group_count[0]);
680 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &GCaps.max_work_group_count[1]);
681 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &GCaps.max_work_group_count[2]);
682 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &GCaps.max_work_group_size[0]);
683 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &GCaps.max_work_group_size[1]);
684 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &GCaps.max_work_group_size[2]);
685 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &GCaps.max_shader_storage_buffer_bindings);
686 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &GCaps.max_compute_shader_storage_blocks);
687 int64_t max_ssbo_size;
688 glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_ssbo_size);
689 GCaps.max_storage_buffer_size = size_t(max_ssbo_size);
690 GLint ssbo_alignment;
691 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_alignment);
692 GCaps.storage_buffer_alignment = size_t(ssbo_alignment);
693
694 GCaps.stencil_export_support = epoxy_has_gl_extension("GL_ARB_shader_stencil_export");
695
696 /* GL specific capabilities. */
697 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GCaps.max_texture_3d_size);
698 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size);
699 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &GLContext::max_ubo_binds);
700 glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GLContext::max_ubo_size);
701 GLint max_ssbo_binds;
703 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &max_ssbo_binds);
705 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &max_ssbo_binds);
707 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &max_ssbo_binds);
709 GLContext::debug_layer_support = epoxy_gl_version() >= 43 ||
710 epoxy_has_gl_extension("GL_KHR_debug") ||
711 epoxy_has_gl_extension("GL_ARB_debug_output");
712 GLContext::direct_state_access_support = epoxy_has_gl_extension("GL_ARB_direct_state_access");
713 GLContext::explicit_location_support = epoxy_gl_version() >= 43;
714 GLContext::framebuffer_fetch_support = epoxy_has_gl_extension("GL_EXT_shader_framebuffer_fetch");
715 GLContext::texture_barrier_support = epoxy_has_gl_extension("GL_ARB_texture_barrier");
716 GLContext::layered_rendering_support = epoxy_has_gl_extension(
717 "GL_ARB_shader_viewport_layer_array");
718 GLContext::native_barycentric_support = epoxy_has_gl_extension(
719 "GL_AMD_shader_explicit_vertex_parameter");
721 "GL_ARB_multi_bind");
722 GLContext::multi_draw_indirect_support = epoxy_has_gl_extension("GL_ARB_multi_draw_indirect");
723 GLContext::shader_draw_parameters_support = epoxy_has_gl_extension(
724 "GL_ARB_shader_draw_parameters");
725 GLContext::stencil_texturing_support = epoxy_gl_version() >= 43;
726 GLContext::texture_filter_anisotropic_support = epoxy_has_gl_extension(
727 "GL_EXT_texture_filter_anisotropic");
728 GLContext::clip_control_support = epoxy_has_gl_extension("GL_ARB_clip_control");
729
731
732 /* Disabled until it is proven to work. */
734
736
737#if BLI_SUBPROCESS_SUPPORT
738 GCaps.use_subprocess_shader_compilations = U.shader_compilation_method ==
740#else
742#endif
743 if (G.debug & G_DEBUG_GPU_RENDERDOC) {
744 /* Avoid crashes on RenderDoc sessions. */
746 }
747
748 int thread_count = U.gpu_shader_workers;
749
750 if (thread_count == 0) {
751 /* Good default based on measurements. */
752
753 /* Always have at least 1 worker. */
754 thread_count = 1;
755
757 /* Use reasonable number of worker by default when there are known gains. */
761 {
762 /* Subprocess is too costly in memory (>150MB per worker) to have better defaults. */
763 thread_count = std::max(1, std::min(4, BLI_system_thread_count() / 2));
764 }
765 }
767 /* Best middle ground between memory usage and speedup as Nvidia context memory footprint
768 * is quite heavy (~25MB). Moreover we have diminishing return after this because of PSO
769 * compilation blocking the main thread.
770 * Can be revisited if we find a way to delete the worker thread context after finishing
771 * compilation, and fix the scheduling bubbles (#139775). */
772 thread_count = 4;
773 }
776 {
777 /* Mesa has very good compilation time and doesn't block the main thread.
778 * The memory footprint of the worker context is rather small (<10MB).
779 * Shader compilation gets much slower as the number of threads increases. */
780 thread_count = 8;
781 }
783 /* AMD proprietary driver's context have huge memory footprint (~45MB).
784 * There is also not much gain from parallelization. */
785 thread_count = 1;
786 }
788 /* Intel windows driver offer almost no speedup with parallel compilation. */
789 thread_count = 1;
790 }
791 }
792
793 /* Allow thread count override option to limit the number of workers and avoid allocating more
794 * workers than needed. Also ensures that there is always 1 thread available for the UI. */
795 int max_thread_count = std::max(1, BLI_system_thread_count() - 1);
796
797 GCaps.max_parallel_compilations = std::min(thread_count, max_thread_count);
798
799 /* Disable this feature entirely when not debugging. */
800 if ((G.debug & G_DEBUG_GPU) == 0) {
803 }
804}
805
807
808} // namespace blender::gpu
@ G_DEBUG_GPU
@ G_DEBUG_GPU_FORCE_WORKAROUNDS
@ G_DEBUG_GPU_RENDERDOC
#define BLI_assert(a)
Definition BLI_assert.h:46
MINLINE int min_ii(int a, int b)
MINLINE int min_iii(int a, int b, int c)
MINLINE bool equals_v4v4(const float v1[4], const float v2[4]) ATTR_WARN_UNUSED_RESULT
int BLI_system_thread_count(void)
Definition threads.cc:253
#define UNPACK4(a)
Compatibility-like things for windows.
bool BLI_windows_get_directx_driver_version(const wchar_t *deviceSubString, long long *r_driverVersion)
@ USER_SHADER_COMPILE_SUBPROCESS
eGPUDriverType
@ GPU_DRIVER_ANY
@ GPU_DRIVER_OFFICIAL
@ GPU_DRIVER_OPENSOURCE
@ GPU_DRIVER_SOFTWARE
@ GPU_ARCHITECTURE_IMR
eGPUSupportLevel
@ GPU_SUPPORT_LEVEL_LIMITED
@ GPU_SUPPORT_LEVEL_SUPPORTED
@ GPU_SUPPORT_LEVEL_UNSUPPORTED
eGPUOSType
@ GPU_OS_WIN
@ GPU_OS_UNIX
@ GPU_OS_ANY
eGPUDeviceType
@ GPU_DEVICE_UNKNOWN
@ GPU_DEVICE_ATI
@ GPU_DEVICE_INTEL_UHD
@ GPU_DEVICE_QUALCOMM
@ GPU_DEVICE_SOFTWARE
@ GPU_DEVICE_NVIDIA
@ GPU_DEVICE_ANY
@ GPU_DEVICE_APPLE
@ GPU_DEVICE_INTEL
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
#define U
ATTR_WARN_UNUSED_RESULT const BMVert * v
long long int int64_t
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:398
static constexpr int64_t not_found
constexpr int64_t find(char c, int64_t pos=0) const
constexpr bool endswith(StringRef suffix) const
void append(const T &value)
static bool stencil_texturing_support
Definition gl_context.hh:62
static bool layered_rendering_support
Definition gl_context.hh:56
static bool debug_layer_support
Definition gl_context.hh:52
static bool framebuffer_fetch_support
Definition gl_context.hh:55
static bool shader_draw_parameters_support
Definition gl_context.hh:61
static bool explicit_location_support
Definition gl_context.hh:54
static GLint max_ssbo_binds
Definition gl_context.hh:47
static bool debug_layer_workaround
Definition gl_context.hh:68
static GLint max_ubo_binds
Definition gl_context.hh:46
static GLint max_ubo_size
Definition gl_context.hh:45
static bool direct_state_access_support
Definition gl_context.hh:53
static bool texture_filter_anisotropic_support
Definition gl_context.hh:64
static bool unused_fb_slot_workaround
Definition gl_context.hh:69
static bool multi_bind_support
Definition gl_context.hh:58
static bool clip_control_support
Definition gl_context.hh:51
static GLint max_cubemap_size
Definition gl_context.hh:44
static bool texture_barrier_support
Definition gl_context.hh:63
static bool native_barycentric_support
Definition gl_context.hh:57
static bool multi_bind_image_support
Definition gl_context.hh:59
static bool generate_mipmap_workaround
Definition gl_context.hh:70
static bool multi_draw_indirect_support
Definition gl_context.hh:60
void init(eGPUDeviceType gpu_device, eGPUOSType os_type, eGPUDriverType driver_type, eGPUSupportLevel gpu_support_level, eGPUBackendType backend, const char *vendor_str, const char *renderer_str, const char *version_str, GPUArchitectureType arch_type)
#define printf(...)
BLI_INLINE float fb(float length, float L)
format
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define L
#define G(x, y, z)
void check_gl_error(const char *info)
Definition gl_debug.cc:159
GPUPlatformGlobal GPG
static bool parse_version(const std::string &version, const std::string &format, Vector< int > &r_version)
Definition gl_backend.cc:51
static void detect_workarounds()
static bool is_bad_AMD_driver(const char *version_cstr)
Definition gl_backend.cc:91
GPUCapabilities GCaps
static const char * gl_extension_get(int i)
static bool detect_mip_render_workaround()
static bool match_renderer(StringRef renderer, const Vector< std::string > &items)
Definition gl_backend.cc:40
i
Definition text_draw.cc:230