Blender V5.0
wm_platform_support.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include <cstring>
12
13#include "BLI_dynstr.h"
14#include "BLI_fileops.h"
15#include "BLI_linklist.h"
16#include "BLI_path_utils.hh"
17#include "BLI_string.h"
18
19#include "BLT_translation.hh"
20
21#include "BKE_appdir.hh"
22#include "BKE_global.hh"
23
24#include "GPU_context.hh"
25#include "GPU_platform.hh"
26
27#include "CLG_log.h"
28
29#define WM_PLATFORM_SUPPORT_TEXT_SIZE 1024
30
31static CLG_LogRef LOG = {"gpu.platform"};
32
36static bool wm_platform_support_check_approval(const char *platform_support_key, bool update)
37{
38 if (G.factory_startup) {
39 return false;
40 }
41 const std::optional<std::string> cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, nullptr);
42 if (!cfgdir.has_value()) {
43 return false;
44 }
45
46 bool result = false;
47 char filepath[FILE_MAX];
48 BLI_path_join(filepath, sizeof(filepath), cfgdir->c_str(), BLENDER_PLATFORM_SUPPORT_FILE);
49 LinkNode *lines = BLI_file_read_as_lines(filepath);
50 for (LinkNode *line_node = lines; line_node; line_node = line_node->next) {
51 const char *line = static_cast<char *>(line_node->link);
52 if (STREQ(line, platform_support_key)) {
53 result = true;
54 break;
55 }
56 }
57
58 if (!result && update) {
59 FILE *fp = BLI_fopen(filepath, "a");
60 if (fp) {
61 fprintf(fp, "%s\n", platform_support_key);
62 fclose(fp);
63 }
64 }
65
67 return result;
68}
69
70static void wm_platform_support_create_link(char *link)
71{
72 DynStr *ds = BLI_dynstr_new();
73
74 BLI_dynstr_append(ds, "https://docs.blender.org/manual/en/dev/troubleshooting/gpu/");
75#if defined(_WIN32)
76 BLI_dynstr_append(ds, "windows/");
77#elif defined(__APPLE__)
78 BLI_dynstr_append(ds, "apple/");
79#else /* UNIX. */
80 BLI_dynstr_append(ds, "linux/");
81#endif
82
84 BLI_dynstr_append(ds, "intel.html");
85 }
87 BLI_dynstr_append(ds, "nvidia.html");
88 }
90 BLI_dynstr_append(ds, "amd.html");
91 }
92 else {
93 BLI_dynstr_append(ds, "unknown.html");
94 }
95
99}
100
102{
104 char message[WM_PLATFORM_SUPPORT_TEXT_SIZE];
106
107 bool result = true;
108
110 const char *platform_key = GPU_platform_support_level_key();
111
112 CLOG_INFO(&LOG, "Using GPU \"%s\"", GPU_platform_gpu_name());
113 CLOG_INFO(&LOG, "Using Backend \"%s\"", GPU_backend_get_name());
114
115 /* Check if previous check matches the current check. Don't update the approval when running in
116 * `background`. this could have been triggered by installing add-ons via installers. */
117 if (support_level != GPU_SUPPORT_LEVEL_UNSUPPORTED && !G.factory_startup &&
118 wm_platform_support_check_approval(platform_key, !G.background))
119 {
120 /* If it matches the user has confirmed and wishes to use it. */
121 return result;
122 }
123
124 bool backend_detected = GPU_backend_get_type() != GPU_BACKEND_NONE;
125 bool show_message = ELEM(
127 bool show_continue = backend_detected && support_level != GPU_SUPPORT_LEVEL_UNSUPPORTED;
128 bool show_link = backend_detected;
129 link[0] = '\0';
130 if (show_link) {
132 }
133
134 /* Update the message and link based on the found support level. */
135 GHOST_DialogOptions dialog_options = GHOST_DialogOptions(0);
136
137 switch (support_level) {
138 default:
140 break;
141
143 size_t slen = 0;
144 STR_CONCAT(title, slen, "Blender - ");
146 title, slen, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Limited Platform Support"));
147 slen = 0;
149 message,
150 slen,
153 "Your graphics card or driver version has limited support. It may work, but with "
154 "issues."));
155
156 /* TODO: Extra space is needed for the split function in GHOST_SystemX11. We should change
157 * the behavior in GHOST_SystemX11. */
158 STR_CONCAT(message, slen, "\n \n");
160 message,
161 slen,
164 "Newer graphics drivers might be available with better Blender compatibility."));
165 STR_CONCAT(message, slen, "\n \n");
166 STR_CONCAT(message, slen, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Graphics card:\n"));
167 STR_CONCAT(message, slen, GPU_platform_gpu_name());
168
169 dialog_options = GHOST_DialogWarning;
170 break;
171 }
172
174 size_t slen = 0;
175 STR_CONCAT(title, slen, "Blender - ");
177 title, slen, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Platform Unsupported"));
178 slen = 0;
179
180#ifdef __APPLE__
183 message,
184 slen,
185 CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Your graphics card is not supported"));
186 }
187 else {
188 STR_CONCAT(message,
189 slen,
191 "Your graphics card or macOS version is not supported"));
192 STR_CONCAT(message, slen, "\n \n");
193
195 message,
196 slen,
198 "Upgrading to the latest macOS version may improve Blender support"));
199 }
200#else
201 STR_CONCAT(message,
202 slen,
204 "Your graphics card or driver version is not supported."));
205 STR_CONCAT(message, slen, "\n \n");
207 message,
208 slen,
211 "Newer graphics drivers might be available with better Blender compatibility."));
212
213 STR_CONCAT(message, slen, "\n \n");
214 STR_CONCAT(message, slen, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Graphics card:\n"));
215 STR_CONCAT(message, slen, GPU_platform_gpu_name());
216#endif
217 STR_CONCAT(message, slen, "\n \n");
218
219 if (!show_continue) {
220 STR_CONCAT(message,
221 slen,
222 CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Blender will now close."));
223 dialog_options = GHOST_DialogError;
224 result = false;
225 }
226 break;
227 }
228 }
229
230 if (show_message) {
231 /* Always print when in background mode or using debug argument. */
232 if (G.background || G.debug & G_DEBUG) {
233 CLOG_INFO_NOCHECK(&LOG, "%s\n\n%s\n%s\n", title, message, link);
234 }
235 else {
236 CLOG_INFO(&LOG, "%s\n\n%s\n%s\n", title, message, link);
237 }
238 }
239 if (G.background) {
240 /* Don't show the message-box when running in background mode.
241 * Printing to console is enough. */
242 result = true;
243 }
244 else if (show_message) {
246 message,
247 "Find Latest Drivers",
248 show_continue ? "Continue Anyway" : "Exit",
249 link,
250 dialog_options);
251 }
252
253 return result;
254}
std::optional< std::string > BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
Definition appdir.cc:721
@ BLENDER_USER_CONFIG
#define BLENDER_PLATFORM_SUPPORT_FILE
@ G_DEBUG
#define BLI_assert(a)
Definition BLI_assert.h:46
A dynamically sized string ADT.
int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.cc:37
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition BLI_dynstr.cc:56
File and directory operations.
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
struct LinkNode * BLI_file_read_as_lines(const char *filepath) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:563
void BLI_file_free_lines(struct LinkNode *lines)
Definition storage.cc:609
#define FILE_MAX
#define BLI_path_join(...)
#define STR_CONCAT(dst, len, suffix)
Definition BLI_string.h:609
#define ELEM(...)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_WINDOWMANAGER
#define CTX_IFACE_(context, msgid)
#define CLOG_INFO_NOCHECK(clg_ref, format,...)
Definition CLG_log.h:204
#define CLOG_INFO(clg_ref,...)
Definition CLG_log.h:190
GHOST_DialogOptions
@ GHOST_DialogError
@ GHOST_DialogWarning
const char * GPU_backend_get_name()
GPUBackendType GPU_backend_get_type()
@ GPU_DEVICE_ATI
@ GPU_DEVICE_NVIDIA
@ GPU_DEVICE_INTEL
GPUSupportLevel GPU_platform_support_level()
const char * GPU_platform_gpu_name()
const char * GPU_platform_support_level_key()
bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
GPUSupportLevel
@ GPU_SUPPORT_LEVEL_LIMITED
@ GPU_SUPPORT_LEVEL_SUPPORTED
@ GPU_SUPPORT_LEVEL_UNSUPPORTED
@ GPU_DRIVER_ANY
@ GPU_OS_ANY
#define LOG(level)
Definition log.h:97
#define G(x, y, z)
static void update(bNodeTree *ntree)
struct LinkNode * next
static bool wm_platform_support_check_approval(const char *platform_support_key, bool update)
#define WM_PLATFORM_SUPPORT_TEXT_SIZE
bool WM_platform_support_perform_checks()
static void wm_platform_support_create_link(char *link)
void WM_ghost_show_message_box(const char *title, const char *message, const char *help_label, const char *continue_label, const char *link, GHOST_DialogOptions dialog_options)