FIX: revert dgpu stuff as mesa conflict

jira: no-jira

Change-Id: I809e55e27f00d084bffe4887846555101c55bb97
This commit is contained in:
jun.zhang 2025-04-08 15:56:49 +08:00 committed by lane.wei
parent e2c4b80435
commit b7f5068e73
5 changed files with 281 additions and 326 deletions

View File

@ -6,9 +6,6 @@
#include <Windows.h> #include <Windows.h>
#include <shellapi.h> #include <shellapi.h>
#include <wchar.h> #include <wchar.h>
#ifdef SLIC3R_GUI #ifdef SLIC3R_GUI
extern "C" extern "C"
{ {
@ -18,98 +15,279 @@ extern "C"
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0; __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0;
} }
#endif /* SLIC3R_GUI */ #endif /* SLIC3R_GUI */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#ifdef SLIC3R_GUI #ifdef SLIC3R_GUI
#include <GL/GL.h> #include <GL/GL.h>
#endif /* SLIC3R_GUI */ #endif /* SLIC3R_GUI */
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
#include <stdio.h> #include <stdio.h>
#ifdef SLIC3R_GUI
class OpenGLVersionCheck
{
public:
std::string version;
std::string glsl_version;
std::string vendor;
std::string renderer;
HINSTANCE hOpenGL = nullptr;
bool success = false;
bool load_opengl_dll()
{
MSG msg = { 0 };
WNDCLASS wc = { 0 };
wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc;
wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr);
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"BambuStudio_opengl_version_check";
wc.style = CS_OWNDC;
if (RegisterClass(&wc)) {
HWND hwnd = CreateWindowW(wc.lpszClassName, L"BambuStudio_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this);
if (hwnd) {
message_pump_exit = false;
while (GetMessage(&msg, NULL, 0, 0) > 0 && !message_pump_exit)
DispatchMessage(&msg);
}
}
return this->success;
}
bool unload_opengl_dll()
{
if (this->hOpenGL != nullptr) {
if (::FreeLibrary(this->hOpenGL) != FALSE) {
if (::GetModuleHandle(L"opengl32.dll") == nullptr) {
printf("System OpenGL library successfully released\n");
this->hOpenGL = nullptr;
return true;
}
else
printf("System OpenGL library released but not removed\n");
}
else
printf("System OpenGL library NOT released\n");
return false;
}
return true;
}
bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
{
// printf("is_version_greater_or_equal_to, version: %s\n", version.c_str());
std::vector<std::string> tokens;
boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on);
if (tokens.empty())
return false;
std::vector<std::string> numbers;
boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on);
unsigned int gl_major = 0;
unsigned int gl_minor = 0;
if (numbers.size() > 0)
gl_major = ::atoi(numbers[0].c_str());
if (numbers.size() > 1)
gl_minor = ::atoi(numbers[1].c_str());
// printf("Major: %d, minor: %d\n", gl_major, gl_minor);
if (gl_major < major)
return false;
else if (gl_major > major)
return true;
else
return gl_minor >= minor;
}
protected:
static bool message_pump_exit;
void check(HWND hWnd)
{
hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0);
if (hOpenGL == nullptr) {
printf("Failed loading the system opengl32.dll\n");
return;
}
typedef HGLRC(WINAPI* Func_wglCreateContext)(HDC);
typedef BOOL(WINAPI* Func_wglMakeCurrent)(HDC, HGLRC);
typedef BOOL(WINAPI* Func_wglDeleteContext)(HGLRC);
typedef GLubyte* (WINAPI* Func_glGetString)(GLenum);
Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext");
Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent)GetProcAddress(hOpenGL, "wglMakeCurrent");
Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext");
Func_glGetString glGetString = (Func_glGetString)GetProcAddress(hOpenGL, "glGetString");
if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) {
printf("Failed loading the system opengl32.dll: The library is invalid.\n");
return;
}
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Color depth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd);
// Gdi32.dll
int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd);
// Gdi32.dll
SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd);
// Opengl32.dll
HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext);
wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext);
// Opengl32.dll
const char* data = (const char*)glGetString(GL_VERSION);
if (data != nullptr)
this->version = data;
// printf("check -version: %s\n", version.c_str());
data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION
if (data != nullptr)
this->glsl_version = data;
data = (const char*)glGetString(GL_VENDOR);
if (data != nullptr)
this->vendor = data;
data = (const char*)glGetString(GL_RENDERER);
if (data != nullptr)
this->renderer = data;
// Opengl32.dll
wglDeleteContext(glcontext);
::ReleaseDC(hWnd, ourWindowHandleToDeviceContext);
this->success = true;
}
static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
OpenGLVersionCheck* ogl_data = reinterpret_cast<OpenGLVersionCheck*>(pCreate->lpCreateParams);
ogl_data->check(hWnd);
DestroyWindow(hWnd);
return 0;
}
case WM_NCDESTROY:
message_pump_exit = true;
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
};
bool OpenGLVersionCheck::message_pump_exit = false;
#endif /* SLIC3R_GUI */
extern "C" { extern "C" {
typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv); typedef int(__stdcall* Slic3rMainFunc)(int argc, wchar_t** argv);
Slic3rMainFunc bambustu_main = nullptr; Slic3rMainFunc bambustu_main = nullptr;
} }
extern "C" { extern "C" {
#ifdef SLIC3R_WRAPPER_NOCONSOLE #ifdef SLIC3R_WRAPPER_NOCONSOLE
int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */) int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */)
{ {
int argc; int argc;
wchar_t **argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
#else #else
int wmain(int argc, wchar_t **argv) int wmain(int argc, wchar_t** argv)
{ {
#endif #endif
// Allow the asserts to open message box, such message box allows to ignore the assert and continue with the application. // Allow the asserts to open message box, such message box allows to ignore the assert and continue with the application.
// Without this call, the seemingly same message box is being opened by the abort() function, but that is too late and // Without this call, the seemingly same message box is being opened by the abort() function, but that is too late and
// the application will be killed even if "Ignore" button is pressed. // the application will be killed even if "Ignore" button is pressed.
_set_error_mode(_OUT_TO_MSGBOX); _set_error_mode(_OUT_TO_MSGBOX);
std::vector<wchar_t*> argv_extended;
std::vector<wchar_t*> argv_extended; argv_extended.emplace_back(argv[0]);
argv_extended.emplace_back(argv[0]);
#ifdef SLIC3R_WRAPPER_GCODEVIEWER #ifdef SLIC3R_WRAPPER_GCODEVIEWER
wchar_t gcodeviewer_param[] = L"--gcodeviewer"; wchar_t gcodeviewer_param[] = L"--gcodeviewer";
argv_extended.emplace_back(gcodeviewer_param); argv_extended.emplace_back(gcodeviewer_param);
#endif /* SLIC3R_WRAPPER_GCODEVIEWER */ #endif /* SLIC3R_WRAPPER_GCODEVIEWER */
#ifdef SLIC3R_GUI #ifdef SLIC3R_GUI
// Here one may push some additional parameters based on the wrapper type. // Here one may push some additional parameters based on the wrapper type.
bool force_mesa = false; bool force_mesa = false;
bool force_hw = false;//for rempote desktop,
#endif /* SLIC3R_GUI */ #endif /* SLIC3R_GUI */
for (int i = 1; i < argc; ++ i) { for (int i = 1; i < argc; ++i) {
#ifdef SLIC3R_GUI #ifdef SLIC3R_GUI
if (wcscmp(argv[i], L"--sw-renderer") == 0) if (wcscmp(argv[i], L"--sw-renderer") == 0)
force_mesa = true; force_mesa = true;
else if (wcscmp(argv[i], L"--no-sw-renderer") == 0) else if (wcscmp(argv[i], L"--no-sw-renderer") == 0)
force_mesa = false; force_hw = true;
#endif /* SLIC3R_GUI */ #endif /* SLIC3R_GUI */
argv_extended.emplace_back(argv[i]); argv_extended.emplace_back(argv[i]);
} }
argv_extended.emplace_back(nullptr); argv_extended.emplace_back(nullptr);
#ifdef SLIC3R_GUI
wchar_t path_to_exe[MAX_PATH + 1] = { 0 }; OpenGLVersionCheck opengl_version_check;
::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH); bool load_mesa =
wchar_t drive[_MAX_DRIVE]; // Forced from the command line.
wchar_t dir[_MAX_DIR]; force_mesa ||
wchar_t fname[_MAX_FNAME]; // Running over a rempote desktop, and the RemoteFX is not enabled, therefore Windows will only provide SW OpenGL 1.1 context.
wchar_t ext[_MAX_EXT]; // In that case, use Mesa.
_wsplitpath(path_to_exe, drive, dir, fname, ext); (::GetSystemMetrics(SM_REMOTESESSION) && !force_hw) ||
_wmakepath(path_to_exe, drive, dir, nullptr, nullptr); // Try to load the default OpenGL driver and test its context version.
!opengl_version_check.load_opengl_dll() || !opengl_version_check.is_version_greater_or_equal_to(3, 2);
wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 }; #endif /* SLIC3R_GUI */
wcscpy(path_to_slic3r, path_to_exe); wchar_t path_to_exe[MAX_PATH + 1] = { 0 };
wcscat(path_to_slic3r, L"BambuStudio.dll"); ::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH);
// printf("Loading Slic3r library: %S\n", path_to_slic3r); wchar_t drive[_MAX_DRIVE];
HINSTANCE hInstance_Slic3r = LoadLibraryExW(path_to_slic3r, nullptr, 0); wchar_t dir[_MAX_DIR];
if (hInstance_Slic3r == nullptr) { wchar_t fname[_MAX_FNAME];
printf("BambuStudio.dll was not loaded, error=%d\n", GetLastError()); wchar_t ext[_MAX_EXT];
return -1; _wsplitpath(path_to_exe, drive, dir, fname, ext);
} _wmakepath(path_to_exe, drive, dir, nullptr, nullptr);
#ifdef SLIC3R_GUI
// resolve function address here // https://wiki.qt.io/Cross_compiling_Mesa_for_Windows
bambustu_main = (Slic3rMainFunc)GetProcAddress(hInstance_Slic3r, // http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
if (load_mesa) {
bool res = opengl_version_check.unload_opengl_dll();
if (!res) {
MessageBox(nullptr, L"Error:BambuStudio was unable to automatically switch to MESA OpenGL library.",
L"BambuStudio Error", MB_OK);
return -1;
}
else {
wchar_t path_to_mesa[MAX_PATH + 1] = { 0 };
wcscpy(path_to_mesa, path_to_exe);
wcscat(path_to_mesa, L"mesa\\opengl32.dll");
printf("Loading MESA OpenGL library: %S\n", path_to_mesa);
HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0);
if (hInstance_OpenGL == nullptr)
printf("MESA OpenGL library was not loaded\n");
else
printf("MESA OpenGL library was loaded sucessfully\n");
}
}
#endif /* SLIC3R_GUI */
wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 };
wcscpy(path_to_slic3r, path_to_exe);
wcscat(path_to_slic3r, L"BambuStudio.dll");
// printf("Loading Slic3r library: %S\n", path_to_slic3r);
HINSTANCE hInstance_Slic3r = LoadLibraryExW(path_to_slic3r, nullptr, 0);
if (hInstance_Slic3r == nullptr) {
printf("BambuStudio.dll was not loaded, error=%d\n", GetLastError());
return -1;
}
// resolve function address here
bambustu_main = (Slic3rMainFunc)GetProcAddress(hInstance_Slic3r,
#ifdef _WIN64 #ifdef _WIN64
// there is just a single calling conversion, therefore no mangling of the function name. // there is just a single calling conversion, therefore no mangling of the function name.
"bambustu_main" "bambustu_main"
#else // stdcall calling convention declaration #else // stdcall calling convention declaration
"_bambustu_main@8" "_bambustu_main@8"
#endif #endif
); );
if (bambustu_main == nullptr) { if (bambustu_main == nullptr) {
printf("could not locate the function bambustu_main in BambuStudio.dll\n"); printf("could not locate the function bambustu_main in BambuStudio.dll\n");
return -1; return -1;
}
// argc minus the trailing nullptr of the argv
return bambustu_main((int)argv_extended.size() - 1, argv_extended.data());
}
} }
// argc minus the trailing nullptr of the argv
return bambustu_main((int)argv_extended.size() - 1, argv_extended.data());
}
}

View File

@ -7172,12 +7172,8 @@ const std::shared_ptr<OpenGLManager>& GUI_App::get_opengl_manager() const
if (m_p_opengl_mgr) { if (m_p_opengl_mgr) {
return m_p_opengl_mgr; return m_p_opengl_mgr;
} }
bool prefer_to_use_dgpu = false;
#ifdef __WIN32__
prefer_to_use_dgpu = app_config->get_bool("prefer_to_use_dgpu");
#endif // __WIN32__
const bool rt = OpenGLManager::init(prefer_to_use_dgpu); const bool rt = OpenGLManager::init();
if (rt) if (rt)
{ {
m_p_opengl_mgr = std::make_shared<OpenGLManager>(); m_p_opengl_mgr = std::make_shared<OpenGLManager>();

View File

@ -1,4 +1,4 @@
#include "libslic3r/libslic3r.h" #include "libslic3r/libslic3r.h"
#include "OpenGLManager.hpp" #include "OpenGLManager.hpp"
#include "GUI.hpp" #include "GUI.hpp"
@ -24,178 +24,6 @@
#include "../Utils/MacDarkMode.hpp" #include "../Utils/MacDarkMode.hpp"
#endif // __APPLE__ #endif // __APPLE__
#ifdef __WIN32__
#ifdef SLIC3R_GUI
class OpenGLVersionCheck
{
public:
std::string version;
std::string glsl_version;
std::string vendor;
std::string renderer;
HINSTANCE hOpenGL = nullptr;
bool success = false;
bool load_opengl_dll()
{
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc;
wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr);
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"BambuStudio_opengl_version_check";
wc.style = CS_OWNDC;
if (RegisterClass(&wc)) {
HWND hwnd = CreateWindowW(wc.lpszClassName, L"BambuStudio_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this);
if (hwnd) {
message_pump_exit = false;
while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit)
DispatchMessage(&msg);
}
}
return this->success;
}
void unload_opengl_dll()
{
if (this->hOpenGL) {
BOOL released = FreeLibrary(this->hOpenGL);
if (released)
printf("System OpenGL library released\n");
else
printf("System OpenGL library NOT released\n");
this->hOpenGL = nullptr;
}
}
bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
{
// printf("is_version_greater_or_equal_to, version: %s\n", version.c_str());
std::vector<std::string> tokens;
boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on);
if (tokens.empty())
return false;
std::vector<std::string> numbers;
boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on);
unsigned int gl_major = 0;
unsigned int gl_minor = 0;
if (numbers.size() > 0)
gl_major = ::atoi(numbers[0].c_str());
if (numbers.size() > 1)
gl_minor = ::atoi(numbers[1].c_str());
// printf("Major: %d, minor: %d\n", gl_major, gl_minor);
if (gl_major < major)
return false;
else if (gl_major > major)
return true;
else
return gl_minor >= minor;
}
protected:
static bool message_pump_exit;
void check(HWND hWnd)
{
hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0);
if (hOpenGL == nullptr) {
printf("Failed loading the system opengl32.dll\n");
return;
}
typedef HGLRC (WINAPI *Func_wglCreateContext)(HDC);
typedef BOOL (WINAPI *Func_wglMakeCurrent )(HDC, HGLRC);
typedef BOOL (WINAPI *Func_wglDeleteContext)(HGLRC);
typedef GLubyte* (WINAPI *Func_glGetString )(GLenum);
Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext");
Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent");
Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext");
Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString");
if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) {
printf("Failed loading the system opengl32.dll: The library is invalid.\n");
return;
}
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Color depth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd);
// Gdi32.dll
int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd);
// Gdi32.dll
SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd);
// Opengl32.dll
HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext);
wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext);
// Opengl32.dll
const char *data = (const char*)glGetString(GL_VERSION);
if (data != nullptr)
this->version = data;
// printf("check -version: %s\n", version.c_str());
data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION
if (data != nullptr)
this->glsl_version = data;
data = (const char*)glGetString(GL_VENDOR);
if (data != nullptr)
this->vendor = data;
data = (const char*)glGetString(GL_RENDERER);
if (data != nullptr)
this->renderer = data;
// Opengl32.dll
wglDeleteContext(glcontext);
::ReleaseDC(hWnd, ourWindowHandleToDeviceContext);
this->success = true;
}
static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
{
CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
OpenGLVersionCheck *ogl_data = reinterpret_cast<OpenGLVersionCheck*>(pCreate->lpCreateParams);
ogl_data->check(hWnd);
DestroyWindow(hWnd);
return 0;
}
case WM_NCDESTROY:
message_pump_exit = true;
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
};
bool OpenGLVersionCheck::message_pump_exit = false;
#endif /* SLIC3R_GUI */
#endif // __WIN32__
#define BBS_GL_EXTENSION_FUNC(_func) (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? _func ## EXT : _func) #define BBS_GL_EXTENSION_FUNC(_func) (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? _func ## EXT : _func)
#define BBS_GL_EXTENSION_PARAMETER(_param) OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? _param ## _EXT : _param #define BBS_GL_EXTENSION_PARAMETER(_param) OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? _param ## _EXT : _param
@ -389,6 +217,10 @@ void OpenGLManager::GLInfo::detect() const
float* max_anisotropy = const_cast<float*>(&m_max_anisotropy); float* max_anisotropy = const_cast<float*>(&m_max_anisotropy);
glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy)); glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy));
} }
int max_offscreen_msaa = 0;
glsafe(::glGetIntegerv(GL_MAX_SAMPLES, &max_offscreen_msaa));
const_cast<OpenGLManager::GLInfo*>(this)->m_max_offscreen_msaa = max_offscreen_msaa;
*const_cast<bool*>(&m_detected) = true; *const_cast<bool*>(&m_detected) = true;
} }
@ -424,6 +256,13 @@ bool OpenGLManager::GLInfo::is_glsl_version_greater_or_equal_to(unsigned int maj
return version_greater_or_equal_to(m_glsl_version, major, minor); return version_greater_or_equal_to(m_glsl_version, major, minor);
} }
uint8_t OpenGLManager::GLInfo::get_max_offscreen_msaa() const
{
if (!m_detected)
detect();
return m_max_offscreen_msaa;
}
// If formatted for github, plaintext with OpenGL extensions enclosed into <details>. // If formatted for github, plaintext with OpenGL extensions enclosed into <details>.
// Otherwise HTML formatted for the system info dialog. // Otherwise HTML formatted for the system info dialog.
std::string OpenGLManager::GLInfo::to_string(bool for_github) const std::string OpenGLManager::GLInfo::to_string(bool for_github) const
@ -506,57 +345,11 @@ OpenGLManager::~OpenGLManager()
#endif //__APPLE__ #endif //__APPLE__
} }
bool OpenGLManager::init(bool prefer_to_use_dgpu) bool OpenGLManager::init()
{ {
if (s_b_initialized) { if (s_b_initialized) {
return true; return true;
} }
#ifdef __WIN32__
if (prefer_to_use_dgpu) {
HMODULE hModExe = nullptr;
hModExe = GetModuleHandle(NULL);
if (hModExe) {
// BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: GetModuleHandle " << hModExe;
auto NvOptimusEnablement = (DWORD *) GetProcAddress(hModExe, "NvOptimusEnablement");
auto AmdPowerXpressRequestHighPerformance = (int *) GetProcAddress(hModExe, "AmdPowerXpressRequestHighPerformance");
if (NvOptimusEnablement) {
*NvOptimusEnablement = 0x00000001;
}
if (AmdPowerXpressRequestHighPerformance) {
// BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: AmdPowerXpressRequestHighPerformance " << *AmdPowerXpressRequestHighPerformance;
*AmdPowerXpressRequestHighPerformance = 1;
}
}
}
#ifdef SLIC3R_GUI
bool force_mesa = false;
wchar_t path_to_exe[MAX_PATH + 1] = {0};
::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH);
OpenGLVersionCheck opengl_version_check;
bool load_mesa =
force_mesa ||
// Try to load the default OpenGL driver and test its context version.
!opengl_version_check.load_opengl_dll() || !opengl_version_check.is_version_greater_or_equal_to(2, 0);
// https://wiki.qt.io/Cross_compiling_Mesa_for_Windows
// http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
if (load_mesa) {
opengl_version_check.unload_opengl_dll();
wchar_t path_to_mesa[MAX_PATH + 1] = {0};
wcscpy(path_to_mesa, path_to_exe);
wcscat(path_to_mesa, L"mesa\\opengl32.dll");
BOOST_LOG_TRIVIAL(info) << "Loading MESA OpenGL library: " << path_to_mesa;
HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0);
if (hInstance_OpenGL == nullptr) {
BOOST_LOG_TRIVIAL(error) << "MESA OpenGL library was not loaded";
} else
BOOST_LOG_TRIVIAL(info) << "MESA OpenGL library was loaded sucessfully";
}
#endif /* SLIC3R_GUI */
#endif // __WIN32__
s_b_initialized = true; s_b_initialized = true;
return s_b_initialized; return s_b_initialized;
} }
@ -739,10 +532,13 @@ void OpenGLManager::_bind_frame_buffer(const std::string& name, EMSAAType msaa_t
height = 1; height = 1;
} }
uint8_t num_samples = get_msaa_samples(msaa_type);
num_samples = std::min(s_gl_info.get_max_offscreen_msaa(), num_samples);
FrameBufferParams t_fb_params; FrameBufferParams t_fb_params;
t_fb_params.m_width = width; t_fb_params.m_width = width;
t_fb_params.m_height = height; t_fb_params.m_height = height;
t_fb_params.m_msaa_type = msaa_type; t_fb_params.m_msaa = num_samples;
const auto& iter = m_name_to_framebuffer.find(name); const auto& iter = m_name_to_framebuffer.find(name);
bool needs_to_recreate = false; bool needs_to_recreate = false;
@ -1073,7 +869,7 @@ void OpenGLManager::detect_multisample(int* attribList)
FrameBuffer::FrameBuffer(const FrameBufferParams& params) FrameBuffer::FrameBuffer(const FrameBufferParams& params)
: m_width(params.m_width) : m_width(params.m_width)
, m_height(params.m_height) , m_height(params.m_height)
, m_msaa_type(params.m_msaa_type) , m_msaa(params.m_msaa)
{ {
} }
@ -1120,7 +916,7 @@ void FrameBuffer::bind()
} }
if (UINT32_MAX == m_gl_id) if (UINT32_MAX == m_gl_id)
{ {
if (EMSAAType::Disabled == m_msaa_type) if (0 == m_msaa)
{ {
create_no_msaa_fbo(true); create_no_msaa_fbo(true);
} }
@ -1204,16 +1000,16 @@ uint32_t FrameBuffer::get_width() const
return m_width; return m_width;
} }
EMSAAType FrameBuffer::get_msaa_type() const uint8_t FrameBuffer::get_msaa_type() const
{ {
return m_msaa_type; return m_msaa;
} }
bool FrameBuffer::is_format_equal(const FrameBufferParams& params) const bool FrameBuffer::is_format_equal(const FrameBufferParams& params) const
{ {
const bool rt = m_width == params.m_width const bool rt = m_width == params.m_width
&& m_height == params.m_height && m_height == params.m_height
&& m_msaa_type == params.m_msaa_type; && m_msaa == params.m_msaa;
return rt; return rt;
} }
@ -1261,15 +1057,14 @@ void FrameBuffer::create_msaa_fbo()
glsafe(BBS_GL_EXTENSION_FUNC(::glBindFramebuffer)(BBS_GL_EXTENSION_PARAMETER(GL_FRAMEBUFFER), m_gl_id_for_back_fbo)); glsafe(BBS_GL_EXTENSION_FUNC(::glBindFramebuffer)(BBS_GL_EXTENSION_PARAMETER(GL_FRAMEBUFFER), m_gl_id_for_back_fbo));
uint8_t num_samples = get_msaa_samples(m_msaa_type);
// use renderbuffer instead of texture to avoid the need to use glTexImage2DMultisample which is available only since OpenGL 3.2 // use renderbuffer instead of texture to avoid the need to use glTexImage2DMultisample which is available only since OpenGL 3.2
glsafe(BBS_GL_EXTENSION_FUNC(::glGenRenderbuffers)(2, m_msaa_back_buffer_rbos)); glsafe(BBS_GL_EXTENSION_FUNC(::glGenRenderbuffers)(2, m_msaa_back_buffer_rbos));
glsafe(BBS_GL_EXTENSION_FUNC(::glBindRenderbuffer)(BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), m_msaa_back_buffer_rbos[0])); glsafe(BBS_GL_EXTENSION_FUNC(::glBindRenderbuffer)(BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), m_msaa_back_buffer_rbos[0]));
glsafe(BBS_GL_EXTENSION_FUNC(::glRenderbufferStorageMultisample)(BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), num_samples, GL_RGBA8, m_width, m_height)); glsafe(BBS_GL_EXTENSION_FUNC(::glRenderbufferStorageMultisample)(BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), m_msaa, GL_RGBA8, m_width, m_height));
glsafe(BBS_GL_EXTENSION_FUNC(::glBindRenderbuffer)(BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), m_msaa_back_buffer_rbos[1])); glsafe(BBS_GL_EXTENSION_FUNC(::glBindRenderbuffer)(BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), m_msaa_back_buffer_rbos[1]));
glsafe(::glRenderbufferStorageMultisample(BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), num_samples, GL_DEPTH24_STENCIL8, m_width, m_height)); glsafe(::glRenderbufferStorageMultisample(BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), m_msaa, GL_DEPTH24_STENCIL8, m_width, m_height));
glsafe(BBS_GL_EXTENSION_FUNC(::glFramebufferRenderbuffer)(BBS_GL_EXTENSION_PARAMETER(GL_FRAMEBUFFER), BBS_GL_EXTENSION_PARAMETER(GL_COLOR_ATTACHMENT0), BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), m_msaa_back_buffer_rbos[0])); glsafe(BBS_GL_EXTENSION_FUNC(::glFramebufferRenderbuffer)(BBS_GL_EXTENSION_PARAMETER(GL_FRAMEBUFFER), BBS_GL_EXTENSION_PARAMETER(GL_COLOR_ATTACHMENT0), BBS_GL_EXTENSION_PARAMETER(GL_RENDERBUFFER), m_msaa_back_buffer_rbos[0]));

View File

@ -49,7 +49,7 @@ struct FrameBufferParams
{ {
uint32_t m_width{ 0 }; uint32_t m_width{ 0 };
uint32_t m_height{ 0 }; uint32_t m_height{ 0 };
EMSAAType m_msaa_type{ EMSAAType::Disabled }; uint32_t m_msaa{ 0 };
}; };
struct FrameBuffer struct FrameBuffer
@ -72,7 +72,7 @@ struct FrameBuffer
uint32_t get_width() const; uint32_t get_width() const;
EMSAAType get_msaa_type() const; uint8_t get_msaa_type() const;
bool is_format_equal(const FrameBufferParams& params) const; bool is_format_equal(const FrameBufferParams& params) const;
private: private:
@ -92,7 +92,7 @@ private:
private: private:
uint32_t m_width{ 0 }; uint32_t m_width{ 0 };
uint32_t m_height{ 0 }; uint32_t m_height{ 0 };
EMSAAType m_msaa_type{ EMSAAType::Disabled }; uint8_t m_msaa{ 0 };
uint32_t m_msaa_back_buffer_rbos[2]{ UINT32_MAX, UINT32_MAX }; uint32_t m_msaa_back_buffer_rbos[2]{ UINT32_MAX, UINT32_MAX };
uint32_t m_gl_id_for_back_fbo{ UINT32_MAX }; uint32_t m_gl_id_for_back_fbo{ UINT32_MAX };
uint32_t m_gl_id{ UINT32_MAX }; uint32_t m_gl_id{ UINT32_MAX };
@ -136,6 +136,7 @@ public:
std::string m_glsl_version; std::string m_glsl_version;
std::string m_vendor; std::string m_vendor;
std::string m_renderer; std::string m_renderer;
int8_t m_max_offscreen_msaa{ 0 };
public: public:
GLInfo() = default; GLInfo() = default;
@ -152,6 +153,8 @@ public:
bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const; bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const;
bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const; bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const;
uint8_t get_max_offscreen_msaa() const;
// If formatted for github, plaintext with OpenGL extensions enclosed into <details>. // If formatted for github, plaintext with OpenGL extensions enclosed into <details>.
// Otherwise HTML formatted for the system info dialog. // Otherwise HTML formatted for the system info dialog.
std::string to_string(bool for_github) const; std::string to_string(bool for_github) const;
@ -256,7 +259,6 @@ public:
bool is_legacy_framebuffer_enabled() const; bool is_legacy_framebuffer_enabled() const;
void set_gizmo_keep_screen_size_enabled(bool is_enabled); void set_gizmo_keep_screen_size_enabled(bool is_enabled);
bool is_gizmo_keep_screen_size_enabled() const; bool is_gizmo_keep_screen_size_enabled() const;
void set_msaa_type(const std::string& type); void set_msaa_type(const std::string& type);
void set_msaa_type(EMSAAType type); void set_msaa_type(EMSAAType type);
EMSAAType get_msaa_type() const; EMSAAType get_msaa_type() const;
@ -266,8 +268,7 @@ public:
bool is_fxaa_enabled() const; bool is_fxaa_enabled() const;
void blit_framebuffer(const std::string& source, const std::string& target); void blit_framebuffer(const std::string& source, const std::string& target);
static bool init(bool prefer_to_use_dgpu = false); static bool init();
static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } static bool are_compressed_textures_supported() { return s_compressed_textures_supported; }
static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; } static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; }
static bool are_framebuffers_supported() { return (s_framebuffers_type != EFramebufferType::Unknown); } static bool are_framebuffers_supported() { return (s_framebuffers_type != EFramebufferType::Unknown); }

View File

@ -890,13 +890,6 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxWindow *pa
} }
} }
} }
#ifdef __WIN32__
if (param == "prefer_to_use_dgpu") {
app_config->set_bool(param, checkbox->GetValue());
app_config->save();
}
#endif // __WIN32__
e.Skip(); e.Skip();
}); });
@ -1218,11 +1211,6 @@ wxWindow* PreferencesDialog::create_general_page()
_L("Improved rendering performance under the scene of multiple plates and many models."), 50, _L("Improved rendering performance under the scene of multiple plates and many models."), 50,
"enable_lod"); "enable_lod");
#ifdef __WIN32__
auto prefer_to_use_dgpu = create_item_checkbox(_L("Prefer to use high performance GPU (Effective after manual restart Bambu Studio)"), page,
_L("If enabled, this feature can improve rendering performance to some extent. However, it may cause flickering on multi-GPU systems, so it is recommended to disable it."), 50, "prefer_to_use_dgpu.");
#endif // __WIN32__
float range_min = 1.0, range_max = 2.5; float range_min = 1.0, range_max = 2.5;
auto item_grabber_size_settings = create_item_range_input(_L("Grabber scale"), page, auto item_grabber_size_settings = create_item_range_input(_L("Grabber scale"), page,
_L("Set grabber size for move,rotate,scale tool.") + _L("Value range") + ":[" + std::to_string(range_min) + "," + _L("Set grabber size for move,rotate,scale tool.") + _L("Value range") + ":[" + std::to_string(range_min) + "," +
@ -1318,9 +1306,6 @@ wxWindow* PreferencesDialog::create_general_page()
sizer_page->Add(item_show_shells_in_preview_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_show_shells_in_preview_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_import_single_svg_and_split, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_import_single_svg_and_split, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_gamma_correct_in_import_obj, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_gamma_correct_in_import_obj, 0, wxTOP, FromDIP(3));
#ifdef __WIN32__
sizer_page->Add(prefer_to_use_dgpu, 0, wxTOP, FromDIP(3));
#endif // __WIN32__
sizer_page->Add(enable_lod_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(enable_lod_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_grabber_size_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_grabber_size_settings, 0, wxTOP, FromDIP(3));