From 7f4a986c38d2403bbf8dbbb7eb9c4683e4ea4e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 29 Jun 2014 09:25:54 +0200 Subject: [PATCH] Added Context::detectedDriver(). A general way to detect drivers, which can be later used for applying driver-specific workarounds. Currently used for disabling ARB_explicit_uniform_location on AMD drivers. --- src/Magnum/CMakeLists.txt | 1 + src/Magnum/Context.h | 31 +++++++++++++ src/Magnum/Implementation/detectedDriver.cpp | 46 +++++++++++++++++++ .../Implementation/setupDriverWorkarounds.cpp | 3 +- 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/Magnum/Implementation/detectedDriver.cpp diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index c3b0cf490..dd7499091 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -62,6 +62,7 @@ set(Magnum_SRCS Implementation/ShaderProgramState.cpp Implementation/State.cpp Implementation/TextureState.cpp + Implementation/detectedDriver.cpp Implementation/maxTextureSize.cpp Implementation/setupDriverWorkarounds.cpp diff --git a/src/Magnum/Context.h b/src/Magnum/Context.h index 93eee5bef..90aa81797 100644 --- a/src/Magnum/Context.h +++ b/src/Magnum/Context.h @@ -38,6 +38,7 @@ #include "Magnum/Magnum.h" #include "Magnum/OpenGL.h" #include "Magnum/visibility.h" +#include "MagnumExternal/Optional/optional.hpp" namespace Magnum { @@ -169,6 +170,25 @@ class MAGNUM_EXPORT Context { */ typedef Containers::EnumSet States; + /** + * @brief Detected driver + * + * @see @ref DetectedDriver, @ref detectedDriver() + */ + enum class DetectedDriver: UnsignedShort { + #ifndef MAGNUM_TARGET_GLES + /** Binary AMD desktop drivers on Windows and Linux */ + AMD = 1 << 0 + #endif + }; + + /** + * @brief Detected drivers + * + * @see @ref detectedDriver() + */ + typedef Containers::EnumSet DetectedDrivers; + /** * @brief Constructor * @@ -432,6 +452,15 @@ class MAGNUM_EXPORT Context { */ void resetState(States states = ~States{}); + /** + * @brief Detect driver + * + * Tries to detect driver using various OpenGL state queries. Once the + * detection is done, the result is cached, repeated queries don't + * result in repeated GL calls. + */ + DetectedDrivers detectedDriver(); + #ifndef DOXYGEN_GENERATING_OUTPUT Implementation::State& state() { return *_state; } #endif @@ -451,6 +480,8 @@ class MAGNUM_EXPORT Context { std::vector _supportedExtensions; Implementation::State* _state; + + std::optional _detectedDrivers; }; /** @debugoperatorclassenum{Magnum::Context,Magnum::Context::Flag} */ diff --git a/src/Magnum/Implementation/detectedDriver.cpp b/src/Magnum/Implementation/detectedDriver.cpp new file mode 100644 index 000000000..d672bb71e --- /dev/null +++ b/src/Magnum/Implementation/detectedDriver.cpp @@ -0,0 +1,46 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Magnum/Context.h" +#include "Magnum/Math/Range.h" + +namespace Magnum { + +auto Context::detectedDriver() -> Context::DetectedDrivers { + if(_detectedDrivers) return *_detectedDrivers; + + _detectedDrivers = DetectedDrivers{}; + + /* AMD binary desktop drivers */ + #ifndef MAGNUM_TARGET_GLES + const std::string vendor = vendorString(); + if(vendor.find("ATI Technologies Inc.") != std::string::npos) + return *_detectedDrivers |= DetectedDriver::AMD; + #endif + + return *_detectedDrivers; +} + +} diff --git a/src/Magnum/Implementation/setupDriverWorkarounds.cpp b/src/Magnum/Implementation/setupDriverWorkarounds.cpp index a29332253..ca7c0bb70 100644 --- a/src/Magnum/Implementation/setupDriverWorkarounds.cpp +++ b/src/Magnum/Implementation/setupDriverWorkarounds.cpp @@ -35,8 +35,7 @@ void Context::setupDriverWorkarounds() { #ifndef MAGNUM_TARGET_GLES /* This extension causes crash in GLSL compiler on AMD linux drivers 13.251 */ - const std::string vendor = vendorString(); - if(vendor.find("ATI Technologies Inc.") != std::string::npos) + if(detectedDriver() & DetectedDriver::AMD) _setRequiredVersion(GL::ARB::explicit_uniform_location, None); #endif