42 for (
const std::string &item : items) {
43 const std::string wrapped =
" " + item +
" ";
56 std::string subversion;
60 if (std::isdigit(version[
v])) {
62 subversion.push_back(version[
v]);
66 match = version[
v] ==
format[f];
67 if (!subversion.empty()) {
68 r_version.
append(std::stoi(subversion));
93 std::string version_str = version_cstr;
95 version_str.push_back(
' ');
105 return version[0] < 23;
108 if (
parse_version(version_str,
" 00.00.00000.00000 ", version) ||
112 return version[0] < 31 || (version[0] == 31 && version[2] < 21001);
119void GLBackend::platform_init()
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);
138 printf(
"Warning: No OpenGL vendor detected.\n");
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 ")))
151 else if (strstr(vendor,
"ATI") || strstr(vendor,
"AMD")) {
155 else if (strstr(vendor,
"NVIDIA")) {
159 else if (strstr(vendor,
"Intel") ||
161 strstr(renderer,
"Mesa DRI Intel") || strstr(renderer,
"Mesa DRI Mobile Intel"))
166 if (strstr(renderer,
"UHD Graphics") ||
168 strstr(renderer,
"HD Graphics 530") || strstr(renderer,
"Kaby Lake GT2") ||
169 strstr(renderer,
"Whiskey Lake"))
174 else if (strstr(renderer,
"Nouveau") || strstr(vendor,
"nouveau")) {
178 else if (strstr(vendor,
"Mesa")) {
182 else if (strstr(vendor,
"Microsoft")) {
184 if (strstr(renderer,
"Qualcomm")) {
193 else if (strstr(vendor,
"Apple")) {
198 else if (strstr(renderer,
"Apple Software Renderer")) {
202 else if (strstr(renderer,
"llvmpipe") || strstr(renderer,
"softpipe")) {
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);
214 if (!(epoxy_gl_version() >= 43)) {
219 long long driverVersion = 0;
223 WORD ver0 = (driverVersion >> 48) & 0xffff;
224 WORD ver1 = (driverVersion >> 32) & 0xffff;
225 WORD ver2 = (driverVersion >> 16) & 0xffff;
231 if (ver0 < 30 || (ver0 == 30 && ver1 == 0 && ver2 < 3820)) {
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";
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"))
256 if (strstr(renderer,
"HD Graphics 405")) {
262 if (strstr(version,
"Build 20.19.15.51")) {
269 if (strstr(renderer,
"AMD CEDAR")) {
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";
292 (strstr(version,
"4.5.14831") || strstr(version,
"4.5.14760")))
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);
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));
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));
329 glGetIntegerv(GL_DEVICE_NODE_MASK_EXT, &node_mask);
335void GLBackend::platform_exit()
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__);
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);
367 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
368 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
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);
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);
384 glDeleteFramebuffers(1, &
fb);
385 glDeleteTextures(1, &tex);
389 return enable_workaround;
394 return (
char *)glGetStringi(GL_EXTENSIONS,
i);
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);
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;
417 GCaps.hdr_viewport_support =
false;
426 GCaps.shader_draw_parameters_support =
false;
437 GCaps.stencil_export_support =
false;
438 GCaps.clip_control_support =
false;
450 (strstr(version,
"4.5.13399") || strstr(version,
"4.5.13417") ||
451 strstr(version,
"4.5.13422") || strstr(version,
"4.5.13467")))
461 GCaps.mip_render_workaround =
true;
462 GCaps.shader_draw_parameters_support =
false;
463 GCaps.broken_amd_driver =
true;
467 (strstr(renderer,
"AMD VERDE") || strstr(renderer,
"AMD KAVERI") ||
468 strstr(renderer,
"AMD TAHITI")))
471 GCaps.shader_draw_parameters_support =
false;
472 GCaps.broken_amd_driver =
true;
476 strstr(version,
"Mesa 19.3.4"))
478 GCaps.shader_draw_parameters_support =
false;
479 GCaps.broken_amd_driver =
true;
490 GCaps.use_hq_normals_workaround =
true;
493 "RX550/550",
"(TM) 520",
"(TM) 530",
"(TM) 535",
"R5",
"R7",
"R9",
"HD"};
496 GCaps.use_hq_normals_workaround =
true;
505 GCaps.line_directive_workaround =
true;
512 (strstr(renderer,
"HD Graphics 620") || strstr(renderer,
"HD Graphics 630")))
514 GCaps.mip_render_workaround =
true;
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")))
525 GCaps.use_main_context_workaround =
true;
529 strstr(version,
"Build 20.19.15.4285"))
531 GCaps.use_main_context_workaround =
true;
537 GCaps.use_main_context_workaround =
true;
542 (strstr(version,
"Mesa 18.") || strstr(version,
"Mesa 19.0") ||
543 strstr(version,
"Mesa 19.1") || strstr(version,
"Mesa 19.2")))
551 if (strstr(version,
"Mesa 20.") || strstr(version,
"Mesa 21.") ||
552 strstr(version,
"Mesa 22.") || strstr(version,
"Mesa 23."))
554 GCaps.shader_draw_parameters_support =
false;
563 long long driverVersion = 0;
567 WORD ver0 = (driverVersion >> 48) & 0xffff;
573 GCaps.stencil_clasify_buffer_workaround =
true;
583 if (
GCaps.mip_render_workaround ==
false) {
611 GCaps.node_link_instancing_workaround =
true;
617 GCaps.minimum_per_vertex_stride = 1;
650void GLBackend::capabilities_init()
673 epoxy_has_gl_extension(
"GL_ATI_meminfo");
688 glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_ssbo_size);
690 GLint ssbo_alignment;
691 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_alignment);
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);
710 epoxy_has_gl_extension(
"GL_KHR_debug") ||
711 epoxy_has_gl_extension(
"GL_ARB_debug_output");
717 "GL_ARB_shader_viewport_layer_array");
719 "GL_AMD_shader_explicit_vertex_parameter");
721 "GL_ARB_multi_bind");
724 "GL_ARB_shader_draw_parameters");
727 "GL_EXT_texture_filter_anisotropic");
737#if BLI_SUBPROCESS_SUPPORT
748 int thread_count =
U.gpu_shader_workers;
750 if (thread_count == 0) {
@ G_DEBUG_GPU_FORCE_WORKAROUNDS
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)
Compatibility-like things for windows.
bool BLI_windows_get_directx_driver_version(const wchar_t *deviceSubString, long long *r_driverVersion)
@ USER_SHADER_COMPILE_SUBPROCESS
ATTR_WARN_UNUSED_RESULT const BMVert * v
void reinitialize(const int64_t new_size)
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
static bool layered_rendering_support
static bool debug_layer_support
static bool framebuffer_fetch_support
static bool shader_draw_parameters_support
static bool explicit_location_support
static GLint max_ssbo_binds
static bool debug_layer_workaround
static GLint max_ubo_binds
static GLint max_ubo_size
static bool direct_state_access_support
static bool texture_filter_anisotropic_support
static bool unused_fb_slot_workaround
static bool multi_bind_support
static bool clip_control_support
static GLint max_cubemap_size
static bool texture_barrier_support
static bool native_barycentric_support
static bool multi_bind_image_support
static bool generate_mipmap_workaround
static bool multi_draw_indirect_support
BLI_INLINE float fb(float length, float L)
void * MEM_callocN(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void check_gl_error(const char *info)
static bool parse_version(const std::string &version, const std::string &format, Vector< int > &r_version)
static void detect_workarounds()
static bool is_bad_AMD_driver(const char *version_cstr)
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)
int max_shader_storage_buffer_bindings
int max_parallel_compilations
bool geometry_shader_support
bool use_subprocess_shader_compilations
int max_work_group_size[3]
bool hdr_viewport_support
int max_work_group_count[3]
const char *(* extension_get)(int)
bool shader_draw_parameters_support
int max_compute_shader_storage_blocks
size_t storage_buffer_alignment
bool clip_control_support
bool stencil_export_support
size_t max_storage_buffer_size