Skip to content

Commit 82aacc1

Browse files
committed
Merge pull request #103245 from bruvzg/rd_helper
[Windows] Offload `RenderingDevice` creation test to subprocess.
2 parents c4731e1 + ab71749 commit 82aacc1

File tree

11 files changed

+276
-3
lines changed

11 files changed

+276
-3
lines changed

core/os/os.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class OS {
109109

110110
HasServerFeatureCallback has_server_feature_callback = nullptr;
111111
bool _separate_thread_render = false;
112+
bool _silent_crash_handler = false;
112113

113114
// Functions used by Main to initialize/deinitialize the OS.
114115
void add_logger(Logger *p_logger);
@@ -262,6 +263,9 @@ class OS {
262263
void set_stdout_enabled(bool p_enabled);
263264
void set_stderr_enabled(bool p_enabled);
264265

266+
virtual void set_crash_handler_silent() { _silent_crash_handler = true; }
267+
virtual bool is_crash_handler_silent() { return _silent_crash_handler; }
268+
265269
virtual void disable_crash_handler() {}
266270
virtual bool is_disable_crash_handler() const { return false; }
267271
virtual void initialize_debugging() {}
@@ -358,6 +362,10 @@ class OS {
358362
// This is invoked by the GDExtensionManager after loading GDExtensions specified by the project.
359363
virtual void load_platform_gdextensions() const {}
360364

365+
// Windows only. Tests OpenGL context and Rendering Device simultaneous creation. This function is expected to crash on some NVIDIA drivers.
366+
virtual bool _test_create_rendering_device_and_gl() const { return true; }
367+
virtual bool _test_create_rendering_device() const { return true; }
368+
361369
OS();
362370
virtual ~OS();
363371
};

editor/project_manager/project_dialog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ ProjectDialog::ProjectDialog() {
973973
default_renderer_type = EditorSettings::get_singleton()->get_setting("project_manager/default_renderer");
974974
}
975975

976-
rendering_device_supported = DisplayServer::can_create_rendering_device();
976+
rendering_device_supported = DisplayServer::is_rendering_device_supported();
977977

978978
if (!rendering_device_supported) {
979979
default_renderer_type = "gl_compatibility";

main/main.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
979979
String project_path = ".";
980980
bool upwards = false;
981981
String debug_uri = "";
982+
#if defined(TOOLS_ENABLED) && defined(WINDOWS_ENABLED)
983+
bool test_rd_creation = false;
984+
bool test_rd_support = false;
985+
#endif
982986
bool skip_breakpoints = false;
983987
String main_pack;
984988
bool quiet_stdout = false;
@@ -1666,6 +1670,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
16661670
debug_canvas_item_redraw = true;
16671671
} else if (arg == "--debug-stringnames") {
16681672
StringName::set_debug_stringnames(true);
1673+
#endif
1674+
#if defined(TOOLS_ENABLED) && defined(WINDOWS_ENABLED)
1675+
} else if (arg == "--test-rd-support") {
1676+
test_rd_support = true;
1677+
} else if (arg == "--test-rd-creation") {
1678+
test_rd_creation = true;
16691679
#endif
16701680
} else if (arg == "--remote-debug") {
16711681
if (N) {
@@ -1870,6 +1880,30 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
18701880
#endif
18711881
}
18721882

1883+
#if defined(TOOLS_ENABLED) && defined(WINDOWS_ENABLED)
1884+
if (test_rd_support) {
1885+
// Test Rendering Device creation and exit.
1886+
1887+
OS::get_singleton()->set_crash_handler_silent();
1888+
if (OS::get_singleton()->_test_create_rendering_device()) {
1889+
exit_err = ERR_HELP;
1890+
} else {
1891+
exit_err = ERR_UNAVAILABLE;
1892+
}
1893+
goto error;
1894+
} else if (test_rd_creation) {
1895+
// Test OpenGL context and Rendering Device simultaneous creation and exit.
1896+
1897+
OS::get_singleton()->set_crash_handler_silent();
1898+
if (OS::get_singleton()->_test_create_rendering_device_and_gl()) {
1899+
exit_err = ERR_HELP;
1900+
} else {
1901+
exit_err = ERR_UNAVAILABLE;
1902+
}
1903+
goto error;
1904+
}
1905+
#endif
1906+
18731907
#ifdef TOOLS_ENABLED
18741908
if (editor) {
18751909
Engine::get_singleton()->set_editor_hint(true);

platform/linuxbsd/crash_handler_linuxbsd.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ static void handle_crash(int sig) {
5757
abort();
5858
}
5959

60+
if (OS::get_singleton()->is_crash_handler_silent()) {
61+
std::_Exit(0);
62+
}
63+
6064
void *bt_buffer[256];
6165
size_t size = backtrace(bt_buffer, 256);
6266
String _execpath = OS::get_singleton()->get_executable_path();

platform/macos/crash_handler_macos.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ static void handle_crash(int sig) {
8181
abort();
8282
}
8383

84+
if (OS::get_singleton()->is_crash_handler_silent()) {
85+
std::_Exit(0);
86+
}
87+
8488
void *bt_buffer[256];
8589
size_t size = backtrace(bt_buffer, 256);
8690
String _execpath = OS::get_singleton()->get_executable_path();

platform/windows/crash_handler_windows_seh.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
// Backtrace code based on: https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app
4242

4343
#include <algorithm>
44+
#include <cstdlib>
4445
#include <iterator>
4546
#include <string>
4647
#include <vector>
@@ -127,6 +128,10 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
127128
return EXCEPTION_CONTINUE_SEARCH;
128129
}
129130

131+
if (OS::get_singleton()->is_crash_handler_silent()) {
132+
std::_Exit(0);
133+
}
134+
130135
String msg;
131136
const ProjectSettings *proj_settings = ProjectSettings::get_singleton();
132137
if (proj_settings) {

platform/windows/crash_handler_windows_signal.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <cxxabi.h>
4242
#include <signal.h>
4343
#include <algorithm>
44+
#include <cstdlib>
4445
#include <iterator>
4546
#include <string>
4647
#include <vector>
@@ -133,6 +134,10 @@ extern void CrashHandlerException(int signal) {
133134
return;
134135
}
135136

137+
if (OS::get_singleton()->is_crash_handler_silent()) {
138+
std::_Exit(0);
139+
}
140+
136141
String msg;
137142
const ProjectSettings *proj_settings = ProjectSettings::get_singleton();
138143
if (proj_settings) {

platform/windows/os_windows.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@
6262
#include <wbemcli.h>
6363
#include <wincrypt.h>
6464

65+
#if defined(RD_ENABLED)
66+
#include "servers/rendering/rendering_device.h"
67+
#endif
68+
69+
#if defined(GLES3_ENABLED)
70+
#include "gl_manager_windows_native.h"
71+
#endif
72+
73+
#if defined(VULKAN_ENABLED)
74+
#include "rendering_context_driver_vulkan_windows.h"
75+
#endif
76+
#if defined(D3D12_ENABLED)
77+
#include "drivers/d3d12/rendering_context_driver_d3d12.h"
78+
#endif
79+
#if defined(GLES3_ENABLED)
80+
#include "drivers/gles3/rasterizer_gles3.h"
81+
#endif
82+
6583
#ifdef DEBUG_ENABLED
6684
#pragma pack(push, before_imagehlp, 8)
6785
#include <imagehlp.h>
@@ -2346,6 +2364,99 @@ void OS_Windows::add_frame_delay(bool p_can_draw) {
23462364
}
23472365
}
23482366

2367+
bool OS_Windows::_test_create_rendering_device() const {
2368+
// Tests Rendering Device creation.
2369+
2370+
bool ok = false;
2371+
#if defined(RD_ENABLED)
2372+
Error err;
2373+
RenderingContextDriver *rcd = nullptr;
2374+
2375+
#if defined(VULKAN_ENABLED)
2376+
rcd = memnew(RenderingContextDriverVulkan);
2377+
#endif
2378+
#ifdef D3D12_ENABLED
2379+
if (rcd == nullptr) {
2380+
rcd = memnew(RenderingContextDriverD3D12);
2381+
}
2382+
#endif
2383+
if (rcd != nullptr) {
2384+
err = rcd->initialize();
2385+
if (err == OK) {
2386+
RenderingDevice *rd = memnew(RenderingDevice);
2387+
err = rd->initialize(rcd);
2388+
memdelete(rd);
2389+
rd = nullptr;
2390+
if (err == OK) {
2391+
ok = true;
2392+
}
2393+
}
2394+
memdelete(rcd);
2395+
rcd = nullptr;
2396+
}
2397+
#endif
2398+
2399+
return ok;
2400+
}
2401+
2402+
bool OS_Windows::_test_create_rendering_device_and_gl() const {
2403+
// Tests OpenGL context and Rendering Device simultaneous creation. This function is expected to crash on some NVIDIA drivers.
2404+
2405+
WNDCLASSEXW wc_probe;
2406+
memset(&wc_probe, 0, sizeof(WNDCLASSEXW));
2407+
wc_probe.cbSize = sizeof(WNDCLASSEXW);
2408+
wc_probe.style = CS_OWNDC | CS_DBLCLKS;
2409+
wc_probe.lpfnWndProc = (WNDPROC)::DefWindowProcW;
2410+
wc_probe.cbClsExtra = 0;
2411+
wc_probe.cbWndExtra = 0;
2412+
wc_probe.hInstance = GetModuleHandle(nullptr);
2413+
wc_probe.hIcon = LoadIcon(nullptr, IDI_WINLOGO);
2414+
wc_probe.hCursor = nullptr;
2415+
wc_probe.hbrBackground = nullptr;
2416+
wc_probe.lpszMenuName = nullptr;
2417+
wc_probe.lpszClassName = L"Engine probe window";
2418+
2419+
if (!RegisterClassExW(&wc_probe)) {
2420+
return false;
2421+
}
2422+
2423+
HWND hWnd = CreateWindowExW(WS_EX_WINDOWEDGE, L"Engine probe window", L"", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
2424+
if (!hWnd) {
2425+
UnregisterClassW(L"Engine probe window", GetModuleHandle(nullptr));
2426+
return false;
2427+
}
2428+
2429+
bool ok = true;
2430+
#ifdef GLES3_ENABLED
2431+
GLManagerNative_Windows *test_gl_manager_native = memnew(GLManagerNative_Windows);
2432+
if (test_gl_manager_native->window_create(DisplayServer::MAIN_WINDOW_ID, hWnd, GetModuleHandle(nullptr), 800, 600) == OK) {
2433+
RasterizerGLES3::make_current(true);
2434+
} else {
2435+
ok = false;
2436+
}
2437+
#endif
2438+
2439+
MSG msg = {};
2440+
while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) {
2441+
TranslateMessage(&msg);
2442+
DispatchMessageW(&msg);
2443+
}
2444+
2445+
if (ok) {
2446+
ok = _test_create_rendering_device();
2447+
}
2448+
2449+
#ifdef GLES3_ENABLED
2450+
if (test_gl_manager_native) {
2451+
memdelete(test_gl_manager_native);
2452+
}
2453+
#endif
2454+
2455+
DestroyWindow(hWnd);
2456+
UnregisterClassW(L"Engine probe window", GetModuleHandle(nullptr));
2457+
return ok;
2458+
}
2459+
23492460
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
23502461
hInstance = _hInstance;
23512462

platform/windows/os_windows.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ class OS_Windows : public OS {
252252

253253
void set_main_window(HWND p_main_window) { main_window = p_main_window; }
254254

255+
virtual bool _test_create_rendering_device_and_gl() const override;
256+
virtual bool _test_create_rendering_device() const override;
257+
255258
HINSTANCE get_hinstance() { return hInstance; }
256259
OS_Windows(HINSTANCE _hInstance);
257260
~OS_Windows();

0 commit comments

Comments
 (0)