From 356491e1dfb74df635fe607fc2f75a6989278e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 25 Nov 2015 02:29:17 +0100 Subject: [PATCH] More transparent way to handle driver workarounds. The engine can now list all driver workarounds that were used during the initialization. Any listed workaround can then be disabled from the command-line using `--magnum-disable-workarounds` command-line parameter. The disabling and querying API is private and undocumented, because the driver workarounds should be disabled only by end-users and not application developers. The workaround list is now empty, but will be filled up in the following commits and the workarounds will be probably documented only privately in Implementation/driverSpecific.hpp, as it is really something that should be used only to debug driver problems. --- src/Magnum/Context.cpp | 13 +++++++++- src/Magnum/Context.h | 9 ++++++- src/Magnum/Implementation/driverSpecific.cpp | 26 ++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) 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) \