diff --git a/src/Magnum/Context.cpp b/src/Magnum/Context.cpp index 8bd6cfaeb..88460ddac 100644 --- a/src/Magnum/Context.cpp +++ b/src/Magnum/Context.cpp @@ -406,7 +406,13 @@ Context* Context::_current = nullptr; Context::Context(NoCreateT, Int argc, char** argv, void functionLoader()): _functionLoader{functionLoader}, _version{Version::None} { /* Parse arguments */ Utility::Arguments args{"magnum"}; - args.parse(argc, argv); + args.addOption("disable-workarounds").setHelpKey("disable-workarounds", "LIST") + .setHelp("disable-workarounds", "driver workarounds to disable\n (see src/Magnum/Implementation/driverSpecific.cpp for detailed info)") + .parse(argc, argv); + + /* Disable driver workarounds */ + for(auto&& workaround: Utility::String::splitWithoutEmptyParts(args.value("disable-workarounds"))) + disableDriverWorkaround(workaround); } Context::Context(Context&& other): _version{std::move(other._version)}, @@ -619,6 +625,11 @@ bool Context::tryCreate() { Debug() << "OpenGL version:" << versionString(); _state = new Implementation::State(*this); + /* Print a list of used workarounds */ + Debug() << "Using driver workarounds:"; + for(const auto& workaround: _driverWorkarounds) + if(!workaround.second) Debug() << " " << workaround.first; + /* Initialize functionality based on current OpenGL version and extensions */ /** @todo Get rid of these */ DefaultFramebuffer::initializeContextBasedFunctionality(*this); diff --git a/src/Magnum/Context.h b/src/Magnum/Context.h index dc6970c9a..9ce65c437 100644 --- a/src/Magnum/Context.h +++ b/src/Magnum/Context.h @@ -100,12 +100,14 @@ class. The options are as following: ``` Usage: - [--magnum-help] ... + [--magnum-help] [--magnum-disable-workarounds LIST] ... Arguments: ... main application arguments (see -h or --help for details) --magnum-help display this help message and exit + --magnum-disable-workarounds LIST driver workarounds to disable + (see src/Magnum/Implementation/driverSpecific.cpp for detailed info) ``` */ class MAGNUM_EXPORT Context { @@ -473,6 +475,7 @@ class MAGNUM_EXPORT Context { DetectedDrivers detectedDriver(); #ifndef DOXYGEN_GENERATING_OUTPUT + bool isDriverWorkaroundDisabled(const std::string& workaround); Implementation::State& state() { return *_state; } #endif @@ -483,6 +486,7 @@ class MAGNUM_EXPORT Context { bool tryCreate(); void create(); + void disableDriverWorkaround(const std::string& workaround); /* Defined in Implementation/driverSpecific.cpp */ MAGNUM_LOCAL void setupDriverWorkarounds(); @@ -500,6 +504,9 @@ class MAGNUM_EXPORT Context { Implementation::State* _state; std::optional _detectedDrivers; + + /* True means known and disabled, false means known */ + std::vector> _driverWorkarounds; }; #ifndef MAGNUM_TARGET_WEBGL diff --git a/src/Magnum/Implementation/driverSpecific.cpp b/src/Magnum/Implementation/driverSpecific.cpp index 018f94c48..c7fed59e7 100644 --- a/src/Magnum/Implementation/driverSpecific.cpp +++ b/src/Magnum/Implementation/driverSpecific.cpp @@ -24,11 +24,20 @@ */ #include "Magnum/Context.h" + +#include + #include "Magnum/Extensions.h" #include "Magnum/Math/Range.h" namespace Magnum { +#ifndef CORRADE_NO_ASSERT +namespace { + std::vector KnownWorkarounds{}; +} +#endif + namespace Implementation { /* Used in Shader.cpp (duh) */ @@ -97,6 +106,23 @@ auto Context::detectedDriver() -> DetectedDrivers { return *_detectedDrivers; } +void Context::disableDriverWorkaround(const std::string& workaround) { + /* Ignore unknown workarounds */ + if(std::find(KnownWorkarounds.begin(), KnownWorkarounds.end(), workaround) == KnownWorkarounds.end()) return; + _driverWorkarounds.emplace_back(workaround, true); +} + +bool Context::isDriverWorkaroundDisabled(const std::string& workaround) { + CORRADE_INTERNAL_ASSERT(std::find(KnownWorkarounds.begin(), KnownWorkarounds.end(), workaround) != KnownWorkarounds.end()); + + /* If the workaround was already asked for or disabled, return its state, + otherwise add it to the list as used one */ + for(const auto& i: _driverWorkarounds) + if(i.first == workaround) return i.second; + _driverWorkarounds.emplace_back(workaround, false); + return false; +} + void Context::setupDriverWorkarounds() { #define _setRequiredVersion(extension, version) \ if(_extensionRequiredVersion[Extensions::extension::Index] < Version::version) \