Browse Source

Audio: make it possible to disable OpenAL extensions as well.

Finally, a feature parity.
pull/364/head
Vladimír Vondruš 7 years ago
parent
commit
8af19f21f0
  1. 45
      src/Magnum/Audio/Context.cpp
  2. 32
      src/Magnum/Audio/Context.h
  3. 45
      src/Magnum/Audio/Test/ContextALTest.cpp
  4. 2
      src/Magnum/Audio/al-info.cpp
  5. 12
      src/Magnum/GL/Context.cpp
  6. 2
      src/Magnum/GL/Context.h

45
src/Magnum/Audio/Context.cpp

@ -128,10 +128,16 @@ Context::Context(NoCreateT, Int argc, const char** argv) noexcept: _device{}, _c
Utility::Arguments args{"magnum",
Utility::Arguments::Flag::IgnoreUnknownOptions};
args.addOption("log", "default").setHelp("log", "console logging", "default|quiet|verbose")
.addOption("disable-extensions").setHelp("disable-extensions", "API extensions to disable", "LIST")
.setFromEnvironment("log")
.parse(argc, argv);
/* Decide how to display initialization log */
_displayInitializationLog = !(args.value("log") == "quiet" || args.value("log") == "QUIET");
/* Disable extensions */
for(auto&& extension: Utility::String::splitWithoutEmptyParts(args.value("disable-extensions")))
_disabledExtensionStrings.push_back(extension);
}
void Context::create(const Configuration& configuration) {
@ -211,14 +217,43 @@ bool Context::tryCreate(const Configuration& configuration) {
const auto found = extensionMap.find(extension);
if(found != extensionMap.end()) {
_supportedExtensions.push_back(found->second);
_extensionStatus.set(found->second.index());
_extensionStatus.set(found->second.index(), true);
}
}
if(_displayInitializationLog) {
/* Print some info */
Debug() << "Audio Renderer:" << rendererString() << "by" << vendorString();
Debug() << "OpenAL version:" << versionString();
std::ostream* output = _displayInitializationLog ? Debug::output() : nullptr;
/* Print some info */
Debug{output} << "Audio renderer:" << rendererString() << "by" << vendorString();
Debug{output} << "OpenAL version:" << versionString();
/* Disable extensions as requested by the user */
if(!_disabledExtensionStrings.empty()) {
bool headerPrinted = false;
/* Disable extensions that are known and supported and print a message
for each */
for(auto&& extension: _disabledExtensionStrings) {
auto found = extensionMap.find(extension);
/* No error message here because some of the extensions could be
from Vulkan or OpenGL. That also means we print the header only
when we actually have something to say */
if(found == extensionMap.end()) continue;
/* If the extension isn't supported in the first place, don't do
anything. If it is, set its status as unsupported but flip the
corresponding bit in the disabled bitmap so we know it is
supported and only got disabled */
if(!_extensionStatus[found->second.index()]) continue;
_extensionStatus.set(found->second.index(), false);
_disabledExtensions.set(found->second.index(), true);
if(!headerPrinted) {
Debug{output} << "Disabling extensions:";
headerPrinted = true;
}
Debug{output} << " " << extension;
}
}
return true;

32
src/Magnum/Audio/Context.h

@ -43,6 +43,7 @@
#include "Magnum/Magnum.h"
#include "Magnum/Tags.h"
#include "Magnum/Audio/visibility.h"
#include "Magnum/Math/BoolVector.h"
#include "MagnumExternal/OpenAL/extensions.h"
namespace Magnum { namespace Audio {
@ -91,13 +92,16 @@ The context is configurable through command-line options, that can be passed
for example from the `Platform::*Application` classes. Usage:
@code{.sh}
<application> [--magnum-help] [--magnum-log default|quiet|verbose] ...
<application> [--magnum-help] [--magnum-disable-extensions LIST]
[--magnum-log default|quiet|verbose] ...
@endcode
Arguments:
- `...` --- main application arguments (see `-h` or `--help` for details)
- `--magnum-help` --- display this help message and exit
- `--magnum-disable-extensions LIST` --- API extensions to disable
(environment: `MAGNUM_DISABLE_EXTENSIONS`)
- `--magnum-log default|quiet|verbose` --- console logging
(environment: `MAGNUM_LOG`) (default: `default`)
@ -380,6 +384,28 @@ class MAGNUM_AUDIO_EXPORT Context {
return _extensionStatus[extension.index()];
}
/**
* @brief Whether given extension is disabled
*
* Can be used for detecting driver bug workarounds. Disabled
* extensions return @cpp false @ce in @ref isExtensionSupported() even
* if they are advertised as being supported by the driver.
*/
template<class T> bool isExtensionDisabled() const {
return _disabledExtensions[T::Index];
}
/**
* @brief Whether given extension is disabled
*
* Can be used e.g. for listing extensions available on current
* hardware, but for general usage prefer @ref isExtensionDisabled() const,
* as it does most operations in compile time.
*/
bool isExtensionDisabled(const Extension& extension) const {
return _disabledExtensions[extension.index()];
}
private:
MAGNUM_AUDIO_LOCAL static Context* _current;
@ -388,8 +414,10 @@ class MAGNUM_AUDIO_EXPORT Context {
ALCdevice* _device;
ALCcontext* _context;
std::bitset<Implementation::ExtensionCount> _extensionStatus;
Math::BoolVector<Implementation::ExtensionCount> _extensionStatus;
Math::BoolVector<Implementation::ExtensionCount> _disabledExtensions;
std::vector<Extension> _supportedExtensions;
std::vector<std::string> _disabledExtensionStrings;
};
/**

45
src/Magnum/Audio/Test/ContextALTest.cpp

@ -43,7 +43,9 @@ struct ContextALTest: TestSuite::Tester {
void ignoreUnrelatedOptions();
void extensionsString();
void isExtensionEnabled();
void isExtensionSupported();
void isExtensionUnsupported();
void isExtensionDisabled();
};
ContextALTest::ContextALTest():
@ -57,7 +59,9 @@ ContextALTest::ContextALTest():
addTests({&ContextALTest::ignoreUnrelatedOptions,
&ContextALTest::extensionsString,
&ContextALTest::isExtensionEnabled});
&ContextALTest::isExtensionSupported,
&ContextALTest::isExtensionUnsupported,
&ContextALTest::isExtensionDisabled});
}
void ContextALTest::construct() {
@ -110,10 +114,43 @@ void ContextALTest::extensionsString() {
CORRADE_VERIFY(!extensions.empty());
}
void ContextALTest::isExtensionEnabled() {
void ContextALTest::isExtensionSupported() {
Context context;
CORRADE_VERIFY(context.isExtensionSupported<Extensions::ALC::EXT::ENUMERATION>());
CORRADE_VERIFY(!context.isExtensionDisabled<Extensions::ALC::EXT::ENUMERATION>());
CORRADE_VERIFY(Context::current().isExtensionSupported<Extensions::ALC::EXT::ENUMERATION>());
Extension e{Extensions::ALC::EXT::ENUMERATION::Index,
Extensions::ALC::EXT::ENUMERATION::string()};
CORRADE_VERIFY(context.isExtensionSupported(e));
CORRADE_VERIFY(!context.isExtensionDisabled(e));
}
void ContextALTest::isExtensionUnsupported() {
Context context;
if(context.isExtensionSupported<Extensions::ALC::SOFTX::HRTF>())
CORRADE_SKIP("Extension" + std::string{Extensions::ALC::SOFTX::HRTF::string()} + " is supported, can't test.");
CORRADE_VERIFY(!context.isExtensionSupported<Extensions::ALC::SOFTX::HRTF>());
CORRADE_VERIFY(!context.isExtensionDisabled<Extensions::ALC::SOFTX::HRTF>());
Extension e{Extensions::ALC::SOFTX::HRTF::Index,
Extensions::ALC::SOFTX::HRTF::string()};
CORRADE_VERIFY(!context.isExtensionSupported(e));
CORRADE_VERIFY(!context.isExtensionDisabled(e));
}
void ContextALTest::isExtensionDisabled() {
/* Yes, FFS. this is a weird-ass name */
const char* argv[] = { "", "--magnum-disable-extensions", "ALC_ENUMERATION_EXT" };
Context context{Containers::arraySize(argv), argv};
CORRADE_VERIFY(!context.isExtensionSupported<Extensions::ALC::EXT::ENUMERATION>());
CORRADE_VERIFY(context.isExtensionDisabled<Extensions::ALC::EXT::ENUMERATION>());
Extension e{Extensions::ALC::EXT::ENUMERATION::Index,
Extensions::ALC::EXT::ENUMERATION::string()};
CORRADE_VERIFY(!context.isExtensionSupported(e));
CORRADE_VERIFY(context.isExtensionDisabled(e));
}
}}}}

2
src/Magnum/Audio/al-info.cpp

@ -140,6 +140,8 @@ int main(const int argc, const char** const argv) {
d << " " << extensionName << std::string(60-extensionName.size(), ' ');
if(c.isExtensionSupported(extension))
d << "SUPPORTED";
else if(c.isExtensionDisabled(extension))
d << " removed";
else
d << " -";
}

12
src/Magnum/GL/Context.cpp

@ -465,7 +465,7 @@ Context::Context(NoCreateT, Utility::Arguments& args, Int argc, const char** arg
CORRADE_INTERNAL_ASSERT(args.prefix() == "magnum");
args.addOption("disable-workarounds")
.setHelp("disable-workarounds", "driver workarounds to disable\n (see https://doc.magnum.graphics/magnum/opengl-workarounds.html for detailed info)", "LIST")
.addOption("disable-extensions").setHelp("disable-extensions", "OpenGL extensions to disable", "LIST")
.addOption("disable-extensions").setHelp("disable-extensions", "API extensions to disable", "LIST")
.addOption("gpu-validation", "off").setHelp("gpu-validation", "GPU validation using KHR_debug (if present)", "off|on")
.addOption("log", "default").setHelp("log", "console logging", "default|quiet|verbose")
.setFromEnvironment("disable-workarounds")
@ -713,7 +713,7 @@ bool Context::tryCreate() {
/* Disable extensions as requested by the user */
if(!_disabledExtensions.empty()) {
Debug{output} << "Disabling extensions:";
bool headerPrinted = false;
/* Put remaining extensions into the hashmap for faster lookup */
std::unordered_map<std::string, Extension> allExtensions{std::move(futureExtensions)};
@ -725,10 +725,16 @@ bool Context::tryCreate() {
for each */
for(auto&& extension: _disabledExtensions) {
auto found = allExtensions.find(extension);
/** @todo Error message here? I should not clutter the output at this point */
/* No error message here because some of the extensions could be
from Vulkan or OpenAL. That also means we print the header only
when we actually have something to say */
if(found == allExtensions.end()) continue;
_extensionRequiredVersion[found->second.index()] = Version::None;
if(!headerPrinted) {
Debug{output} << "Disabling extensions:";
headerPrinted = true;
}
Debug{output} << " " << extension;
}
}

2
src/Magnum/GL/Context.h

@ -134,7 +134,7 @@ Arguments:
- `--magnum-disable-workarounds LIST` --- driver workarounds to disable (see
@ref opengl-workarounds for detailed info) (environment:
`MAGNUM_DISABLE_WORKAROUNDS`)
- `--magnum-disable-extensions LIST` --- OpenGL extensions to disable
- `--magnum-disable-extensions LIST` --- API extensions to disable
(environment: `MAGNUM_DISABLE_EXTENSIONS`)
- `--magnum-gpu-validation off|on` --- GPU validation using
@gl_extension{KHR,debug}, if present (environment:

Loading…
Cancel
Save