diff --git a/Engine/OSGLContext_win.cpp b/Engine/OSGLContext_win.cpp index 3665c4c03..b9b78ff28 100644 --- a/Engine/OSGLContext_win.cpp +++ b/Engine/OSGLContext_win.cpp @@ -693,7 +693,6 @@ static std::string GetGPUInfoAMDInternal_string(const OSGLContext_wgl_data* wglI static bool GetGPUInfoAMDInternal_int(const OSGLContext_wgl_data* wglInfo, UINT gpuID, int info, int* value) { - std::vector data; int totalSize = 0; @@ -719,6 +718,36 @@ static bool GetGPUInfoAMDInternal_int(const OSGLContext_wgl_data* wglInfo, UINT return true; } +namespace { +class ScopedGLContext { +public: + ScopedGLContext(const GLRendererID& gid) { + assert(!OSGLContext_win::threadHasACurrentContext()); + try { + _context = std::make_unique(FramebufferConfig(), GLVersion.major, GLVersion.minor, false, gid, nullptr); + } catch (const std::exception& e) { + std::cerr << "Failed to create GL context : " << e.what() << std::endl; + return; + } + + if (!OSGLContext_win::makeContextCurrent(_context.get())) { + _context.reset(); + } + } + + ~ScopedGLContext() { + if (_context) { + OSGLContext_win::makeContextCurrent(nullptr); + } + } + + explicit operator bool() const { return (bool)_context; } + +private: + std::unique_ptr _context; +}; +} // namespace + void OSGLContext_win::getGPUInfos(std::list& renderers) { @@ -749,37 +778,27 @@ OSGLContext_win::getGPUInfos(std::list& renderers) for (std::size_t i = 0; i < gpuHandles.size(); ++i) { OpenGLRendererInfo info; info.rendererID.rendererHandle = (void*)gpuHandles[i]; + { + ScopedGLContext scopedContext(info.rendererID); + if (!scopedContext) { + continue; + } - std::unique_ptr context; - try { - GLRendererID gid; - gid.rendererHandle = info.rendererID.rendererHandle; - context.reset( new OSGLContext_win(FramebufferConfig(), GLVersion.major, GLVersion.minor, false, gid, 0) ); - } catch (const std::exception& e) { - continue; - } - - if ( !makeContextCurrent( context.get() ) ) { - continue; - } + try { + OSGLContext::checkOpenGLVersion(); + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + continue; + } - try { - OSGLContext::checkOpenGLVersion(); - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - makeContextCurrent(nullptr); - continue; + info.vendorName = std::string( (const char *) glGetString(GL_VENDOR) ); + info.rendererName = std::string( (const char *) glGetString(GL_RENDERER) ); + info.glVersionString = std::string( (const char *) glGetString(GL_VERSION) ); + info.glslVersionString = std::string( (const char*)glGetString (GL_SHADING_LANGUAGE_VERSION) ); + info.maxMemBytes = nvx_get_GPU_mem_info(); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize); + renderers.push_back(info); } - - info.vendorName = std::string( (const char *) glGetString(GL_VENDOR) ); - info.rendererName = std::string( (const char *) glGetString(GL_RENDERER) ); - info.glVersionString = std::string( (const char *) glGetString(GL_VERSION) ); - info.glslVersionString = std::string( (const char*)glGetString (GL_SHADING_LANGUAGE_VERSION) ); - info.maxMemBytes = nvx_get_GPU_mem_info(); - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize); - renderers.push_back(info); - - makeContextCurrent(nullptr); } } else if (wglInfo->AMD_gpu_association && !isApplication32Bits()) { //https://www.opengl.org/registry/specs/AMD/wgl_gpu_association.txt @@ -798,62 +817,52 @@ OSGLContext_win::getGPUInfos(std::list& renderers) UINT gpuID = gpuIDs[index]; OpenGLRendererInfo info; - info.rendererName = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_RENDERER_STRING_AMD); - if (info.rendererName.empty()) { - continue; - } - - info.vendorName = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_VENDOR_AMD); - if (info.vendorName.empty()) { - continue; - } + info.rendererID.renderID = gpuID; - info.glVersionString = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_OPENGL_VERSION_STRING_AMD); - if (info.glVersionString.empty()) { - continue; - } + { + ScopedGLContext scopedContext(info.rendererID); + if (!scopedContext) { + continue; + } - // note: cannot retrieve GL_SHADING_LANGUAGE_VERSION + info.rendererName = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_RENDERER_STRING_AMD); + if (info.rendererName.empty()) { + continue; + } - info.maxMemBytes = 0; - if (!isApplication32Bits()) { - int ramMB = 0; - // AMD drivers are f*** up in 32 bits, they read a wrong buffer size. - // It works fine in 64 bits mode - if (!GetGPUInfoAMDInternal_int(wglInfo, gpuID, WGL_GPU_RAM_AMD, &ramMB)) { + info.vendorName = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_VENDOR_AMD); + if (info.vendorName.empty()) { continue; } - info.maxMemBytes = ramMB * 1e6; - } - info.rendererID.renderID = gpuID; - - std::unique_ptr context; + info.glVersionString = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_OPENGL_VERSION_STRING_AMD); + if (info.glVersionString.empty()) { + continue; + } - GLRendererID gid; - gid.renderID = info.rendererID.renderID; - try { - context.reset( new OSGLContext_win(FramebufferConfig(), GLVersion.major, GLVersion.minor, false, gid, 0) ); - } catch (const std::exception& e) { - continue; - } + // note: cannot retrieve GL_SHADING_LANGUAGE_VERSION + + info.maxMemBytes = 0; + if (!isApplication32Bits()) { + int ramMB = 0; + // AMD drivers are f*** up in 32 bits, they read a wrong buffer size. + // It works fine in 64 bits mode + if (!GetGPUInfoAMDInternal_int(wglInfo, gpuID, WGL_GPU_RAM_AMD, &ramMB)) { + continue; + } + info.maxMemBytes = ramMB * 1e6; + } - if ( !makeContextCurrent( context.get() ) ) { - continue; - } + try { + OSGLContext::checkOpenGLVersion(); + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + continue; + } - try { - OSGLContext::checkOpenGLVersion(); - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - makeContextCurrent(nullptr); - continue; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize); + renderers.push_back(info); } - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize); - renderers.push_back(info); - - makeContextCurrent(nullptr); } } } @@ -863,38 +872,29 @@ OSGLContext_win::getGPUInfos(std::list& renderers) } if (defaultFallback) { // No extension, use default - std::unique_ptr context; - try { - context.reset( new OSGLContext_win(FramebufferConfig(), GLVersion.major, GLVersion.minor, false, GLRendererID(), 0) ); - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - - return; - } + { + ScopedGLContext scopedContext{GLRendererID()}; + if (!scopedContext) { + return; + } - if ( !makeContextCurrent( context.get() ) ) { - return; - } + try { + OSGLContext::checkOpenGLVersion(); + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + return; + } - try { - OSGLContext::checkOpenGLVersion(); - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - makeContextCurrent(nullptr); - return; + OpenGLRendererInfo info; + info.vendorName = std::string( (const char *) glGetString(GL_VENDOR) ); + info.rendererName = std::string( (const char *) glGetString(GL_RENDERER) ); + info.glVersionString = std::string( (const char *) glGetString(GL_VERSION) ); + info.glslVersionString = std::string( (const char *) glGetString (GL_SHADING_LANGUAGE_VERSION) ); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize); + // We don't have any way to get memory size, set it to 0 + info.maxMemBytes = nvx_get_GPU_mem_info(); + renderers.push_back(info); } - - OpenGLRendererInfo info; - info.vendorName = std::string( (const char *) glGetString(GL_VENDOR) ); - info.rendererName = std::string( (const char *) glGetString(GL_RENDERER) ); - info.glVersionString = std::string( (const char *) glGetString(GL_VERSION) ); - info.glslVersionString = std::string( (const char *) glGetString (GL_SHADING_LANGUAGE_VERSION) ); - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize); - // We don't have any way to get memory size, set it to 0 - info.maxMemBytes = nvx_get_GPU_mem_info(); - renderers.push_back(info); - - makeContextCurrent(nullptr); } } // OSGLContext_win::getGPUInfos