Blender V5.0
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
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.000000 ", version) ||
101 parse_version(version_str, " 00.00.00 ", version) ||
102 parse_version(version_str, " 00.00.0 ", version) ||
103 parse_version(version_str, " 00.0.00 ", version) ||
104 parse_version(version_str, " 00.Q0.", version))
105 {
106 return version[0] < 23;
107 }
108 /* Some drivers only expose the Windows version https://gpuopen.com/version-table/ */
109 if (parse_version(version_str, " 00.00.00000.00000 ", version) ||
110 parse_version(version_str, " 00.00.00000.0000 ", version) ||
111 parse_version(version_str, " 00.00.0000.00000 ", version))
112 {
113 return version[0] < 31 || (version[0] == 31 && version[2] < 21001);
114 }
115
116 /* Unknown version, assume it's a bad one. */
117 return true;
118}
119
120void GLBackend::platform_init()
121{
123
124 const char *vendor = (const char *)glGetString(GL_VENDOR);
125 const char *renderer = (const char *)glGetString(GL_RENDERER);
126 const char *version = (const char *)glGetString(GL_VERSION);
131
132#ifdef _WIN32
133 os = GPU_OS_WIN;
134#else
135 os = GPU_OS_UNIX;
136#endif
137
138 if (!vendor) {
139 printf("Warning: No OpenGL vendor detected.\n");
140 device = GPU_DEVICE_UNKNOWN;
141 driver = GPU_DRIVER_ANY;
142 }
143 else if (strstr(renderer, "Mesa DRI R") ||
144 (strstr(renderer, "Radeon") && (strstr(vendor, "X.Org") || strstr(version, "Mesa"))) ||
145 (strstr(renderer, "AMD") && (strstr(vendor, "X.Org") || strstr(version, "Mesa"))) ||
146 (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")) ||
147 (strstr(renderer, "Gallium ") && strstr(renderer, " on AMD ")))
148 {
149 device = GPU_DEVICE_ATI;
150 driver = GPU_DRIVER_OPENSOURCE;
151 }
152 else if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) {
153 device = GPU_DEVICE_ATI;
154 driver = GPU_DRIVER_OFFICIAL;
155 }
156 else if (strstr(vendor, "NVIDIA")) {
157 device = GPU_DEVICE_NVIDIA;
158 driver = GPU_DRIVER_OFFICIAL;
159 }
160 else if (strstr(vendor, "Intel") ||
161 /* src/mesa/drivers/dri/intel/intel_context.c */
162 strstr(renderer, "Mesa DRI Intel") || strstr(renderer, "Mesa DRI Mobile Intel"))
163 {
164 device = GPU_DEVICE_INTEL;
165 driver = GPU_DRIVER_OFFICIAL;
166
167 if (strstr(renderer, "UHD Graphics") ||
168 /* Not UHD but affected by the same bugs. */
169 strstr(renderer, "HD Graphics 530") || strstr(renderer, "Kaby Lake GT2") ||
170 strstr(renderer, "Whiskey Lake"))
171 {
172 device |= GPU_DEVICE_INTEL_UHD;
173 }
174 }
175 else if (strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) {
176 device = GPU_DEVICE_NVIDIA;
177 driver = GPU_DRIVER_OPENSOURCE;
178 }
179 else if (strstr(vendor, "Mesa")) {
180 device = GPU_DEVICE_SOFTWARE;
181 driver = GPU_DRIVER_SOFTWARE;
182 }
183 else if (strstr(vendor, "Microsoft")) {
184 /* Qualcomm devices use Mesa's GLOn12, which claims to be vended by Microsoft */
185 if (strstr(renderer, "Qualcomm")) {
186 device = GPU_DEVICE_QUALCOMM;
187 driver = GPU_DRIVER_OFFICIAL;
188 }
189 else {
190 device = GPU_DEVICE_SOFTWARE;
191 driver = GPU_DRIVER_SOFTWARE;
192 }
193 }
194 else if (strstr(vendor, "Apple")) {
195 /* Apple Silicon. */
196 device = GPU_DEVICE_APPLE;
197 driver = GPU_DRIVER_OFFICIAL;
198 }
199 else if (strstr(renderer, "Apple Software Renderer")) {
200 device = GPU_DEVICE_SOFTWARE;
201 driver = GPU_DRIVER_SOFTWARE;
202 }
203 else if (strstr(renderer, "llvmpipe") || strstr(renderer, "softpipe")) {
204 device = GPU_DEVICE_SOFTWARE;
205 driver = GPU_DRIVER_SOFTWARE;
206 }
207 else {
208 printf("Warning: Could not find a matching GPU name. Things may not behave as expected.\n");
209 printf("Detected OpenGL configuration:\n");
210 printf("Vendor: %s\n", vendor);
211 printf("Renderer: %s\n", renderer);
212 }
213
214 /* Detect support level */
215 if (!(epoxy_gl_version() >= 43)) {
216 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
217 }
218 else {
219#if defined(WIN32)
220 long long driverVersion = 0;
221 if (device & GPU_DEVICE_QUALCOMM) {
222 if (BLI_windows_get_directx_driver_version(L"Qualcomm(R) Adreno(TM)", &driverVersion)) {
223 /* Parse out the driver version in format x.x.x.x */
224 WORD ver0 = (driverVersion >> 48) & 0xffff;
225 WORD ver1 = (driverVersion >> 32) & 0xffff;
226 WORD ver2 = (driverVersion >> 16) & 0xffff;
227
228 /* Any Qualcomm driver older than 30.x.x.x will never capable of running blender >= 4.0
229 * As due to an issue in D3D typed UAV load capabilities, Compute Shaders are not available
230 * 30.0.3820.x and above are capable of running blender >=4.0, but these drivers
231 * are only available on 8cx gen3 devices or newer */
232 if (ver0 < 30 || (ver0 == 30 && ver1 == 0 && ver2 < 3820)) {
233 std::cout
234 << "=====================================\n"
235 << "Qualcomm drivers older than 30.0.3820.x cannot run Blender 4.0 or later.\n"
236 << "If your device is older than an 8cx Gen3, you must use a 3.x LTS release.\n"
237 << "If you have an 8cx Gen3 or newer device, a driver update may be available.\n"
238 << "=====================================\n";
239 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
240 }
241 }
242 }
243#endif
244 if ((device & GPU_DEVICE_INTEL) && (os & GPU_OS_WIN)) {
245 /* Old Intel drivers with known bugs that cause material properties to crash.
246 * Version Build 10.18.14.5067 is the latest available and appears to be working
247 * ok with our workarounds, so excluded from this list. */
248 if (strstr(version, "Build 7.14") || strstr(version, "Build 7.15") ||
249 strstr(version, "Build 8.15") || strstr(version, "Build 9.17") ||
250 strstr(version, "Build 9.18") || strstr(version, "Build 10.18.10.3") ||
251 strstr(version, "Build 10.18.10.4") || strstr(version, "Build 10.18.10.5") ||
252 strstr(version, "Build 10.18.14.4"))
253 {
254 support_level = GPU_SUPPORT_LEVEL_LIMITED;
255 }
256 /* A rare GPU that has z-fighting issues in edit mode. (see #128179) */
257 if (strstr(renderer, "HD Graphics 405")) {
258 support_level = GPU_SUPPORT_LEVEL_LIMITED;
259 }
260 /* Latest Intel driver have bugs that won't allow Blender to start.
261 * Users must install different version of the driver.
262 * See #113124 for more information. */
263 if (strstr(version, "Build 20.19.15.51")) {
264 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
265 }
266 }
267 if ((device & GPU_DEVICE_ATI) && (os & GPU_OS_UNIX)) {
268 /* Platform seems to work when SB backend is disabled. This can be done
269 * by adding the environment variable `R600_DEBUG=nosb`. */
270 if (strstr(renderer, "AMD CEDAR")) {
271 support_level = GPU_SUPPORT_LEVEL_LIMITED;
272 }
273 }
274 if ((device & GPU_DEVICE_QUALCOMM) && (os & GPU_OS_WIN)) {
275 if (strstr(version, "Mesa 20.") || strstr(version, "Mesa 21.") ||
276 strstr(version, "Mesa 22.") || strstr(version, "Mesa 23."))
277 {
278 std::cerr << "Unsupported driver. Requires at least Mesa 24.0.0." << std::endl;
279 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
280 }
281 }
282
283 /* Check SSBO bindings requirement. */
284 GLint max_ssbo_binds_vertex;
285 GLint max_ssbo_binds_fragment;
286 GLint max_ssbo_binds_compute;
287 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &max_ssbo_binds_vertex);
288 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &max_ssbo_binds_fragment);
289 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &max_ssbo_binds_compute);
290 GLint max_ssbo_binds = min_iii(
291 max_ssbo_binds_vertex, max_ssbo_binds_fragment, max_ssbo_binds_compute);
292 if (max_ssbo_binds < 12) {
293 std::cout << "Warning: Unsupported platform as it supports max " << max_ssbo_binds
294 << " SSBO binding locations\n";
295 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
296 }
297
298 if (!epoxy_has_gl_extension("GL_ARB_shader_draw_parameters")) {
299 std::cout << "Error: The OpenGL implementation doesn't support ARB_shader_draw_parameters\n";
300 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
301 }
302
303 if (!epoxy_has_gl_extension("GL_ARB_clip_control")) {
304 std::cout << "Error: The OpenGL implementation doesn't support ARB_clip_control\n";
305 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
306 }
307 }
308
309 /* Compute shaders have some issues with those versions (see #94936). */
310 if ((device & GPU_DEVICE_ATI) && (driver & GPU_DRIVER_OFFICIAL) &&
311 (strstr(version, "4.5.14831") || strstr(version, "4.5.14760")))
312 {
313 support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
314 }
315
316 GPG.init(device,
317 os,
318 driver,
319 support_level,
321 vendor,
322 renderer,
323 version,
325
329
330 if (epoxy_has_gl_extension("GL_EXT_memory_object")) {
331 GLint number_of_devices = 0;
332 glGetIntegerv(GL_NUM_DEVICE_UUIDS_EXT, &number_of_devices);
333 /* Multiple devices could be used by the context if certain extensions like multi-cast is used.
334 * But this is not used by Blender, so this should always be 1. */
335 BLI_assert(number_of_devices == 1);
336
337 GLubyte device_uuid[GL_UUID_SIZE_EXT] = {0};
338 glGetUnsignedBytei_vEXT(GL_DEVICE_UUID_EXT, 0, device_uuid);
339 GPG.device_uuid = Array<uint8_t, 16>(Span<uint8_t>(device_uuid, GL_UUID_SIZE_EXT));
340
341 /* LUID is only supported on Windows. */
342 if (epoxy_has_gl_extension("GL_EXT_memory_object_win32") && (os & GPU_OS_WIN)) {
343 GLubyte device_luid[GL_LUID_SIZE_EXT] = {0};
344 glGetUnsignedBytevEXT(GL_DEVICE_LUID_EXT, device_luid);
345 GPG.device_luid = Array<uint8_t, 8>(Span<uint8_t>(device_luid, GL_LUID_SIZE_EXT));
346
347 GLint node_mask = 0;
348 glGetIntegerv(GL_DEVICE_NODE_MASK_EXT, &node_mask);
350 }
351 }
352}
353
354void GLBackend::platform_exit()
355{
357 GPG.clear();
358}
359
361
362/* -------------------------------------------------------------------- */
365
366static const char *gl_extension_get(int i)
367{
368 return (char *)glGetStringi(GL_EXTENSIONS, i);
369}
370
372{
373 const char *vendor = (const char *)glGetString(GL_VENDOR);
374 const char *renderer = (const char *)glGetString(GL_RENDERER);
375 const char *version = (const char *)glGetString(GL_VERSION);
376
377 if (G.debug & G_DEBUG_GPU_FORCE_WORKAROUNDS) {
378 printf("\n");
379 printf("GL: Forcing workaround usage and disabling extensions.\n");
380 printf(" OpenGL identification strings\n");
381 printf(" vendor: %s\n", vendor);
382 printf(" renderer: %s\n", renderer);
383 printf(" version: %s\n\n", version);
384 GCaps.depth_blitting_workaround = true;
385 GCaps.stencil_clasify_buffer_workaround = true;
387 /* Turn off Blender features. */
388 GCaps.hdr_viewport_support = false;
389 /* Turn off OpenGL 4.4 features. */
392 /* Turn off OpenGL 4.5 features. */
394 /* Turn off OpenGL 4.6 features. */
396 /* Turn off extensions. */
398 /* Turn off vendor specific extensions. */
402 GCaps.stencil_export_support = false;
403
404#if 0
405 /* Do not alter OpenGL 4.3 features.
406 * These code paths should be removed. */
408#endif
409
410 return;
411 }
412
414 (strstr(version, "4.5.13399") || strstr(version, "4.5.13417") ||
415 strstr(version, "4.5.13422") || strstr(version, "4.5.13467")))
416 {
417 /* The renderers include:
418 * Radeon HD 5000;
419 * Radeon HD 7500M;
420 * Radeon HD 7570M;
421 * Radeon HD 7600M;
422 * Radeon R5 Graphics;
423 * And others... */
425 }
426 /* We have issues with this specific renderer. (see #74024) */
428 (strstr(renderer, "AMD VERDE") || strstr(renderer, "AMD KAVERI") ||
429 strstr(renderer, "AMD TAHITI")))
430 {
432 }
433 /* See #82856: AMD drivers since 20.11 running on a polaris architecture doesn't support the
434 * `GL_INT_2_10_10_10_REV` data type correctly. This data type is used to pack normals and flags.
435 * The work around uses `TextureFormat::SINT_16_16_16_16`. In 22.?.? drivers this
436 * has been fixed for polaris platform. Keeping legacy platforms around just in case.
437 */
439 /* Check for AMD legacy driver. Assuming that when these drivers are used this bug is present.
440 */
441 if (is_bad_AMD_driver(version)) {
442 GCaps.use_hq_normals_workaround = true;
443 }
444 const Vector<std::string> matches = {
445 "RX550/550", "(TM) 520", "(TM) 530", "(TM) 535", "R5", "R7", "R9", "HD"};
446
447 if (match_renderer(renderer, matches)) {
448 GCaps.use_hq_normals_workaround = true;
449 }
450 }
451
452 /* Maybe not all of these drivers have problems with `GL_ARB_base_instance`.
453 * But it's hard to test each case.
454 * We get crashes from some crappy Intel drivers don't work well with shaders created in
455 * different rendering contexts. */
457 (strstr(version, "Build 10.18.10.3") || strstr(version, "Build 10.18.10.4") ||
458 strstr(version, "Build 10.18.10.5") || strstr(version, "Build 10.18.14.4") ||
459 strstr(version, "Build 10.18.14.5")))
460 {
461 GCaps.use_main_context_workaround = true;
462 }
463 /* Somehow fixes armature display issues (see #69743). */
465 strstr(version, "Build 20.19.15.4285"))
466 {
467 GCaps.use_main_context_workaround = true;
468 }
469 /* Needed to avoid driver hangs on legacy AMD drivers (see #139939). */
471 is_bad_AMD_driver(version))
472 {
473 GCaps.use_main_context_workaround = true;
474 }
475 /* See #70187: merging vertices fail. This has been tested from `18.2.2` till `19.3.0~dev`
476 * of the Mesa driver */
478 (strstr(version, "Mesa 18.") || strstr(version, "Mesa 19.0") ||
479 strstr(version, "Mesa 19.1") || strstr(version, "Mesa 19.2")))
480 {
482 }
483
484/* Snapdragon X Elite devices currently have a driver bug that results in
485 * eevee rendering a black cube with anything except an emission shader
486 * if shader draw parameters are enabled (#122837) */
487#if defined(WIN32)
488 long long driverVersion = 0;
490 if (BLI_windows_get_directx_driver_version(L"Qualcomm(R) Adreno(TM)", &driverVersion)) {
491 /* Parse out the driver version */
492 WORD ver0 = (driverVersion >> 48) & 0xffff;
493
494 /* X Elite devices have GPU driver version 31, and currently no known release version of the
495 * GPU driver renders the cube correctly. This will be changed when a working driver version
496 * is released to commercial devices to only enable this flags on older drivers. */
497 if (ver0 == 31) {
498 GCaps.stencil_clasify_buffer_workaround = true;
499 }
500 }
501 }
502#endif
503
504 /* Enable our own incomplete debug layer if no other is available. */
505 if (GLContext::debug_layer_support == false) {
507 }
508
509 /* There is an issue in AMD official driver where we cannot use multi bind when using images. AMD
510 * is aware of the issue, but hasn't released a fix. */
513 }
514
515 /* #107642, #120273 Windows Intel iGPU (multiple generations) incorrectly report that
516 * they support image binding. But when used it results into `GL_INVALID_OPERATION` with
517 * `internal format of texture N is not supported`. */
520 }
521
522 /* Metal-related Workarounds. */
523
524 /* Minimum Per-Vertex stride is 1 byte for OpenGL. */
525 GCaps.minimum_per_vertex_stride = 1;
526}
527
529
533
535
547
549
553
554void GLBackend::capabilities_init()
555{
556 BLI_assert(epoxy_gl_version() >= 33);
557 /* Common Capabilities. */
558 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GCaps.max_texture_size);
559 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &GCaps.max_texture_layers);
560 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_frag);
561 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_vert);
562 glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_geom);
563 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &GCaps.max_textures);
564 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &GCaps.max_uniforms_vert);
565 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &GCaps.max_uniforms_frag);
566 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &GCaps.max_batch_indices);
567 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &GCaps.max_batch_vertices);
568 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &GCaps.max_vertex_attribs);
569 glGetIntegerv(GL_MAX_VARYING_FLOATS, &GCaps.max_varying_floats);
570 glGetIntegerv(GL_MAX_IMAGE_UNITS, &GCaps.max_images);
571
572 glGetIntegerv(GL_NUM_EXTENSIONS, &GCaps.extensions_len);
574
576 GCaps.mem_stats_support = epoxy_has_gl_extension("GL_NVX_gpu_memory_info") ||
577 epoxy_has_gl_extension("GL_ATI_meminfo");
581
582 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &GCaps.max_work_group_count[0]);
583 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &GCaps.max_work_group_count[1]);
584 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &GCaps.max_work_group_count[2]);
585 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &GCaps.max_work_group_size[0]);
586 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &GCaps.max_work_group_size[1]);
587 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &GCaps.max_work_group_size[2]);
588 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &GCaps.max_shader_storage_buffer_bindings);
589 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &GCaps.max_compute_shader_storage_blocks);
590 int64_t max_ssbo_size, max_ubo_size;
591 glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &max_ubo_size);
592 GCaps.max_uniform_buffer_size = size_t(max_ubo_size);
593 glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_ssbo_size);
594 GCaps.max_storage_buffer_size = size_t(max_ssbo_size);
595 GLint ssbo_alignment;
596 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_alignment);
597 GCaps.storage_buffer_alignment = size_t(ssbo_alignment);
598
599 GCaps.stencil_export_support = epoxy_has_gl_extension("GL_ARB_shader_stencil_export");
600
601 /* GL specific capabilities. */
602 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GCaps.max_texture_3d_size);
603 glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE,
604 reinterpret_cast<int *>(&GCaps.max_buffer_texture_size));
605 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size);
606 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &GLContext::max_ubo_binds);
607 GLint max_ssbo_binds;
609 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &max_ssbo_binds);
611 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &max_ssbo_binds);
613 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &max_ssbo_binds);
615 GLContext::debug_layer_support = epoxy_gl_version() >= 43 ||
616 epoxy_has_gl_extension("GL_KHR_debug") ||
617 epoxy_has_gl_extension("GL_ARB_debug_output");
618 GLContext::direct_state_access_support = epoxy_has_gl_extension("GL_ARB_direct_state_access");
619 GLContext::explicit_location_support = epoxy_gl_version() >= 43;
620 GLContext::framebuffer_fetch_support = epoxy_has_gl_extension("GL_EXT_shader_framebuffer_fetch");
621 GLContext::texture_barrier_support = epoxy_has_gl_extension("GL_ARB_texture_barrier");
622 GLContext::layered_rendering_support = epoxy_has_gl_extension(
623 "GL_ARB_shader_viewport_layer_array");
624 GLContext::native_barycentric_support = epoxy_has_gl_extension(
625 "GL_AMD_shader_explicit_vertex_parameter");
627 "GL_ARB_multi_bind");
628 GLContext::stencil_texturing_support = epoxy_gl_version() >= 43;
629 GLContext::texture_filter_anisotropic_support = epoxy_has_gl_extension(
630 "GL_EXT_texture_filter_anisotropic");
631
632 /* Disabled until it is proven to work. */
634
636
637#if BLI_SUBPROCESS_SUPPORT
638 GCaps.use_subprocess_shader_compilations = U.shader_compilation_method ==
640#else
642#endif
643 if (G.debug & G_DEBUG_GPU_RENDERDOC) {
644 /* Avoid crashes on RenderDoc sessions. */
646 }
647
648 int thread_count = U.gpu_shader_workers;
649
650 if (thread_count == 0) {
651 /* Good default based on measurements. */
652
653 /* Always have at least 1 worker. */
654 thread_count = 1;
655
657 /* Use reasonable number of worker by default when there are known gains. */
661 {
662 /* Subprocess is too costly in memory (>150MB per worker) to have better defaults. */
663 thread_count = std::max(1, std::min(4, BLI_system_thread_count() / 2));
664 }
665 }
667 /* Best middle ground between memory usage and speedup as Nvidia context memory footprint
668 * is quite heavy (~25MB). Moreover we have diminishing return after this because of PSO
669 * compilation blocking the main thread.
670 * Can be revisited if we find a way to delete the worker thread context after finishing
671 * compilation, and fix the scheduling bubbles (#139775). */
672 thread_count = 4;
673 }
676 {
677 /* Mesa has very good compilation time and doesn't block the main thread.
678 * The memory footprint of the worker context is rather small (<10MB).
679 * Shader compilation gets much slower as the number of threads increases. */
680 thread_count = 8;
681 }
683 /* AMD proprietary driver's context have huge memory footprint (~45MB).
684 * There is also not much gain from parallelization. */
685 thread_count = 1;
686 }
688 /* Intel windows driver offer almost no speedup with parallel compilation. */
689 thread_count = 1;
690 }
691 }
692
693 /* Allow thread count override option to limit the number of workers and avoid allocating more
694 * workers than needed. Also ensures that there is always 1 thread available for the UI. */
695 int max_thread_count = std::max(1, BLI_system_thread_count() - 1);
696
697 GCaps.max_parallel_compilations = std::min(thread_count, max_thread_count);
698
699 /* Disable this feature entirely when not debugging. */
700 if ((G.debug & G_DEBUG_GPU) == 0) {
703 }
704}
705
707
708} // 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)
int BLI_system_thread_count(void)
Definition threads.cc:253
Compatibility-like things for windows.
bool BLI_windows_get_directx_driver_version(const wchar_t *deviceSubString, long long *r_driverVersion)
@ USER_SHADER_COMPILE_SUBPROCESS
GPUDeviceType
@ 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
@ GPU_ARCHITECTURE_IMR
bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
GPUSupportLevel
@ GPU_SUPPORT_LEVEL_LIMITED
@ GPU_SUPPORT_LEVEL_SUPPORTED
@ GPU_SUPPORT_LEVEL_UNSUPPORTED
GPUDriverType
@ GPU_DRIVER_ANY
@ GPU_DRIVER_OFFICIAL
@ GPU_DRIVER_OPENSOURCE
@ GPU_DRIVER_SOFTWARE
GPUOSType
@ GPU_OS_WIN
@ GPU_OS_UNIX
@ GPU_OS_ANY
#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:419
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:68
static bool layered_rendering_support
Definition gl_context.hh:64
static bool debug_layer_support
Definition gl_context.hh:60
static bool framebuffer_fetch_support
Definition gl_context.hh:63
static bool explicit_location_support
Definition gl_context.hh:62
static GLint max_ssbo_binds
Definition gl_context.hh:56
static bool debug_layer_workaround
Definition gl_context.hh:74
static GLint max_ubo_binds
Definition gl_context.hh:55
static bool direct_state_access_support
Definition gl_context.hh:61
static bool texture_filter_anisotropic_support
Definition gl_context.hh:70
static bool unused_fb_slot_workaround
Definition gl_context.hh:75
static bool multi_bind_support
Definition gl_context.hh:66
static GLint max_cubemap_size
Definition gl_context.hh:54
static bool texture_barrier_support
Definition gl_context.hh:69
static bool native_barycentric_support
Definition gl_context.hh:65
static bool multi_bind_image_support
Definition gl_context.hh:67
static bool generate_mipmap_workaround
Definition gl_context.hh:76
void init(GPUDeviceType gpu_device, GPUOSType os_type, GPUDriverType driver_type, GPUSupportLevel gpu_support_level, GPUBackendType backend, const char *vendor_str, const char *renderer_str, const char *version_str, GPUArchitectureType arch_type)
#define printf(...)
format
#define L
#define G(x, y, z)
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 match_renderer(StringRef renderer, const Vector< std::string > &items)
Definition gl_backend.cc:40
i
Definition text_draw.cc:230