Browse Source

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.
pull/122/merge
Vladimír Vondruš 11 years ago
parent
commit
356491e1df
  1. 13
      src/Magnum/Context.cpp
  2. 9
      src/Magnum/Context.h
  3. 26
      src/Magnum/Implementation/driverSpecific.cpp

13
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} { Context::Context(NoCreateT, Int argc, char** argv, void functionLoader()): _functionLoader{functionLoader}, _version{Version::None} {
/* Parse arguments */ /* Parse arguments */
Utility::Arguments args{"magnum"}; 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)}, Context::Context(Context&& other): _version{std::move(other._version)},
@ -619,6 +625,11 @@ bool Context::tryCreate() {
Debug() << "OpenGL version:" << versionString(); Debug() << "OpenGL version:" << versionString();
_state = new Implementation::State(*this); _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 */ /* Initialize functionality based on current OpenGL version and extensions */
/** @todo Get rid of these */ /** @todo Get rid of these */
DefaultFramebuffer::initializeContextBasedFunctionality(*this); DefaultFramebuffer::initializeContextBasedFunctionality(*this);

9
src/Magnum/Context.h

@ -100,12 +100,14 @@ class. The options are as following:
``` ```
Usage: Usage:
<application> [--magnum-help] ... <application> [--magnum-help] [--magnum-disable-workarounds LIST] ...
Arguments: Arguments:
... main application arguments ... main application arguments
(see -h or --help for details) (see -h or --help for details)
--magnum-help display this help message and exit --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 { class MAGNUM_EXPORT Context {
@ -473,6 +475,7 @@ class MAGNUM_EXPORT Context {
DetectedDrivers detectedDriver(); DetectedDrivers detectedDriver();
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
bool isDriverWorkaroundDisabled(const std::string& workaround);
Implementation::State& state() { return *_state; } Implementation::State& state() { return *_state; }
#endif #endif
@ -483,6 +486,7 @@ class MAGNUM_EXPORT Context {
bool tryCreate(); bool tryCreate();
void create(); void create();
void disableDriverWorkaround(const std::string& workaround);
/* Defined in Implementation/driverSpecific.cpp */ /* Defined in Implementation/driverSpecific.cpp */
MAGNUM_LOCAL void setupDriverWorkarounds(); MAGNUM_LOCAL void setupDriverWorkarounds();
@ -500,6 +504,9 @@ class MAGNUM_EXPORT Context {
Implementation::State* _state; Implementation::State* _state;
std::optional<DetectedDrivers> _detectedDrivers; std::optional<DetectedDrivers> _detectedDrivers;
/* True means known and disabled, false means known */
std::vector<std::pair<std::string, bool>> _driverWorkarounds;
}; };
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL

26
src/Magnum/Implementation/driverSpecific.cpp

@ -24,11 +24,20 @@
*/ */
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include <algorithm>
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "Magnum/Math/Range.h" #include "Magnum/Math/Range.h"
namespace Magnum { namespace Magnum {
#ifndef CORRADE_NO_ASSERT
namespace {
std::vector<std::string> KnownWorkarounds{};
}
#endif
namespace Implementation { namespace Implementation {
/* Used in Shader.cpp (duh) */ /* Used in Shader.cpp (duh) */
@ -97,6 +106,23 @@ auto Context::detectedDriver() -> DetectedDrivers {
return *_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() { void Context::setupDriverWorkarounds() {
#define _setRequiredVersion(extension, version) \ #define _setRequiredVersion(extension, version) \
if(_extensionRequiredVersion[Extensions::extension::Index] < Version::version) \ if(_extensionRequiredVersion[Extensions::extension::Index] < Version::version) \

Loading…
Cancel
Save