diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 2a887424ce..e45795e363 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -771,7 +771,7 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, boo else glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data())); - if (use_mipmaps) { + if (use_mipmaps && OpenGLManager::use_manually_generated_mipmaps()) { // we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards int lod_w = m_width; int lod_h = m_height; @@ -800,8 +800,9 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, boo glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level)); glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); } - } - else { + } else if (use_mipmaps && !OpenGLManager::use_manually_generated_mipmaps()) { + glGenerateMipmap(GL_TEXTURE_2D); + } else { glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); } diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 450e5aba35..cfed0f996f 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -207,6 +207,7 @@ std::string OpenGLManager::GLInfo::to_string(bool for_github) const OpenGLManager::GLInfo OpenGLManager::s_gl_info; bool OpenGLManager::s_compressed_textures_supported = false; +bool OpenGLManager::m_use_manually_generated_mipmaps = true; OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::EMultisampleState::Unknown; OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown; @@ -276,6 +277,34 @@ bool OpenGLManager::init_gl() wxMessageBox(message, _L("Error loading shaders"), wxOK | wxICON_ERROR); } } + +#ifdef _WIN32 + // Since AMD driver version 22.7.1, there is probably some bug in the driver that causes the issue with the missing + // texture of the bed. It seems that this issue only triggers when mipmaps are generated manually + // (combined with a texture compression) and when mipmaps are generated through OpenGL glGenerateMipmap is working. + // So, for newer drivers than 22.6.1, the last working driver version, we use mipmaps generated through OpenGL. + if (const auto gl_info = OpenGLManager::get_gl_info(); boost::contains(gl_info.get_vendor(), "ATI Technologies Inc.")) { + // WHQL drivers seem to have one more version number at the end besides non-WHQL drivers. + // WHQL: 4.6.14800 Compatibility Profile Context 22.6.1 30.0.21023.1015 + // Non-WHQL: 4.6.0 Compatibility Profile Context 22.8.1.220810 + std::regex version_rgx(R"(Compatibility\sProfile\sContext\s(\d+)\.(\d+)\.(\d+))"); + if (std::smatch matches; std::regex_search(gl_info.get_version(), matches, version_rgx) && matches.size() == 4) { + int version_major = std::stoi(matches[1].str()); + int version_minor = std::stoi(matches[2].str()); + int version_patch = std::stoi(matches[3].str()); + BOOST_LOG_TRIVIAL(debug) << "Found AMD driver version: " << version_major << "." << version_minor << "." << version_patch; + + if (version_major > 22 || (version_major == 22 && version_minor > 6) || (version_major == 22 && version_minor == 6 && version_patch > 1)) { + m_use_manually_generated_mipmaps = false; + BOOST_LOG_TRIVIAL(debug) << "Mipmapping through OpenGL was enabled."; + } + } else { + BOOST_LOG_TRIVIAL(error) << "Not recognized format of version."; + } + } else { + BOOST_LOG_TRIVIAL(error) << "Unable to parse version of AMD driver."; + } +#endif } return true; diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 72a4e6bc07..f1ba47c5ec 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -84,6 +84,7 @@ private: static EMultisampleState s_multisample; static EFramebufferType s_framebuffers_type; + static bool m_use_manually_generated_mipmaps; public: OpenGLManager() = default; ~OpenGLManager(); @@ -100,6 +101,7 @@ public: static EFramebufferType get_framebuffers_type() { return s_framebuffers_type; } static wxGLCanvas* create_wxglcanvas(wxWindow& parent); static const GLInfo& get_gl_info() { return s_gl_info; } + static bool use_manually_generated_mipmaps() { return m_use_manually_generated_mipmaps; } private: static void detect_multisample(int* attribList);