diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index e193fc4dbfe..5204c974f00 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -6,7 +6,9 @@ * \ingroup gpu */ +#include #include +#include #include #include "BKE_global.hh" @@ -46,6 +48,67 @@ static bool match_renderer(StringRef renderer, const Vector &items) return false; } +/** + * Return whether an AMD driver version is in [20.11, 22], + * preferring false negatives. + * + * Matches: + * 4.6.14761 Core Profile Context 20.45.44 27.20.14544.6 + * 4.6.14760 Compatibility Profile Context 21.2.3 27.20.14535.3005 + * 4.6.14831 Core Profile Context FireGL 21.Q2.1 27.20.21026.2006 + * 4.6.14830 Core Profile Context 22.6.1 27.20.20913.2000 + * 4.6.14760 Core Profile Context 21.2.3 27.20.14535.3005 + * Rejects: + * 4.6.0 Core Profile Context 23.10.2.231013 + * 4.6.0 Core Profile Context 24.7.1.240618 + * 4.6.0 Core Profile Context 25.3.2.250311 + * by matching + * " 2" digits "." "Q"? digits "." digits " " + */ +static bool is_AMD_between_20_11_and_22(const char *version) +{ + const char *spc_2 = strstr(version, " 2"); + if (!spc_2) { + return false; + } + + char *after_first = nullptr; + long first = std::strtol(spc_2, &after_first, 10); + if (first < 20 || first > 22) { + return false; + } + if (*after_first != '.') { + return false; + } + ++after_first; + + if (*after_first == 'Q') { + ++after_first; + } + char *after_second = nullptr; + long second = std::strtol(after_first, &after_second, 10); + if (after_second == after_first) { + return false; + } + + if (*after_second != '.') { + return false; + } + ++after_second; + + char *after_third = nullptr; + long third = std::strtol(after_second, &after_third, 10); + if (after_third == after_second) { + return false; + } + + if (*after_third != ' ') { + return false; + } + + return (first == 20 && second >= 11) || first == 21 || first == 22; +} + void GLBackend::platform_init() { BLI_assert(!GPG.initialized); @@ -414,9 +477,7 @@ static void detect_workarounds() if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_OFFICIAL)) { /* Check for AMD legacy driver. Assuming that when these drivers are used this bug is present. */ - if (strstr(version, " 22.6.1 ") || strstr(version, " 21.Q1.2 ") || - strstr(version, " 21.Q2.1 ")) - { + if (is_AMD_between_20_11_and_22(version)) { GCaps.use_hq_normals_workaround = true; } const Vector matches = { @@ -431,9 +492,7 @@ static void detect_workarounds() * install of the driver. */ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_OFFICIAL)) { - if (strstr(version, " 22.6.1 ") || strstr(version, " 21.Q1.2 ") || - strstr(version, " 21.Q2.1 ")) - { + if (is_AMD_between_20_11_and_22(version)) { GCaps.line_directive_workaround = true; } }