Browse Source

GL: add a type trait for checking if a type is an extension.

Similar to what Vulkan has. Will be used mainly for guarding implicit
conversion to the Extension class.
euler-xxx
Vladimír Vondruš 5 years ago
parent
commit
49630d43d4
  1. 29
      src/Magnum/GL/Context.h
  2. 45
      src/Magnum/GL/Test/ContextTest.cpp

29
src/Magnum/GL/Context.h

@ -57,6 +57,14 @@ namespace GL {
namespace Implementation { namespace Implementation {
struct ContextState; struct ContextState;
struct State; struct State;
template<class...> class IsExtension;
template<> class IsExtension<> { public: enum: bool { value = true }; };
CORRADE_HAS_TYPE(IsExtension<U>, decltype(T::Index));
template<class T, class U, class ...Args> class IsExtension<T, U, Args...> {
/** @todo C++17: use &&... instead of all this */
public: enum: bool { value = IsExtension<T>::value && IsExtension<U, Args...>::value };
};
} }
/** /**
@ -650,8 +658,8 @@ class MAGNUM_GL_EXPORT Context {
* @ref MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(), * @ref MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(),
* @ref isExtensionDisabled() * @ref isExtensionDisabled()
*/ */
template<class T> bool isExtensionSupported() const { template<class E> bool isExtensionSupported() const {
return isExtensionSupported<T>(version()); return isExtensionSupported<E>(version());
} }
/** /**
@ -664,8 +672,9 @@ class MAGNUM_GL_EXPORT Context {
* *
* @snippet MagnumGL.cpp Context-isExtensionSupported-version * @snippet MagnumGL.cpp Context-isExtensionSupported-version
*/ */
template<class T> bool isExtensionSupported(Version version) const { template<class E> bool isExtensionSupported(Version version) const {
return _extensionRequiredVersion[T::Index] <= version && _extensionStatus[T::Index]; static_assert(Implementation::IsExtension<E>::value, "expected an OpenGL extension");
return _extensionRequiredVersion[E::Index] <= version && _extensionStatus[E::Index];
} }
/** /**
@ -688,8 +697,8 @@ class MAGNUM_GL_EXPORT Context {
* extensions return `false` in @ref isExtensionSupported() even if * extensions return `false` in @ref isExtensionSupported() even if
* they are advertised as being supported by the driver. * they are advertised as being supported by the driver.
*/ */
template<class T> bool isExtensionDisabled() const { template<class E> bool isExtensionDisabled() const {
return isExtensionDisabled<T>(version()); return isExtensionDisabled<E>(version());
} }
/** /**
@ -698,9 +707,11 @@ class MAGNUM_GL_EXPORT Context {
* Similar to above, but can also check for extensions which are * Similar to above, but can also check for extensions which are
* disabled only for particular versions. * disabled only for particular versions.
*/ */
template<class T> bool isExtensionDisabled(Version version) const { template<class E> bool isExtensionDisabled(Version version) const {
/* The extension is advertised, but the minimal version has been increased */ static_assert(Implementation::IsExtension<E>::value, "expected an OpenGL extension");
return T::requiredVersion() <= version && _extensionRequiredVersion[T::Index] > version; /* The extension is advertised, but the minimal version has been
increased */
return E::requiredVersion() <= version && _extensionRequiredVersion[E::Index] > version;
} }
/** /**

45
src/Magnum/GL/Test/ContextTest.cpp

@ -37,6 +37,8 @@ namespace Magnum { namespace GL { namespace Test { namespace {
struct ContextTest: TestSuite::Tester { struct ContextTest: TestSuite::Tester {
explicit ContextTest(); explicit ContextTest();
void isExtension();
void constructNoCreate(); void constructNoCreate();
void constructCopyMove(); void constructCopyMove();
@ -52,7 +54,9 @@ struct ContextTest: TestSuite::Tester {
}; };
ContextTest::ContextTest() { ContextTest::ContextTest() {
addTests({&ContextTest::constructNoCreate, addTests({&ContextTest::isExtension,
&ContextTest::constructNoCreate,
&ContextTest::constructCopyMove, &ContextTest::constructCopyMove,
&ContextTest::makeCurrentNoOp, &ContextTest::makeCurrentNoOp,
@ -66,6 +70,45 @@ ContextTest::ContextTest() {
&ContextTest::debugDetectedDrivers}); &ContextTest::debugDetectedDrivers});
} }
void ContextTest::isExtension() {
CORRADE_VERIFY(Implementation::IsExtension<Extensions::KHR::debug>::value);
CORRADE_VERIFY(!Implementation::IsExtension<Extension>::value);
CORRADE_VERIFY(!Implementation::IsExtension<int>::value);
{
/* Not really a problem right now, but once people hit this we might
want to guard against this (especially because the Index might be
out of bounds) */
struct ALExtension {
enum: std::size_t { Index };
};
CORRADE_EXPECT_FAIL("AL/Vk extensions are not rejected right now.");
CORRADE_VERIFY(!Implementation::IsExtension<ALExtension>::value);
}
/* Variadic check (used in variadic addEnabledExtensions()), check that it
properly fails for each occurence of a non-extension */
CORRADE_VERIFY((Implementation::IsExtension<
Extensions::KHR::debug,
Extensions::EXT::texture_filter_anisotropic,
Extensions::KHR::texture_compression_astc_hdr>::value));
CORRADE_VERIFY(!(Implementation::IsExtension<
Extension,
Extensions::KHR::debug,
Extensions::EXT::texture_filter_anisotropic>::value));
CORRADE_VERIFY(!(Implementation::IsExtension<
Extensions::KHR::debug,
Extension,
Extensions::EXT::texture_filter_anisotropic>::value));
CORRADE_VERIFY(!(Implementation::IsExtension<
Extensions::KHR::debug,
Extensions::EXT::texture_filter_anisotropic,
Extension>::value));
/* Empty variadic list should return true */
CORRADE_VERIFY(Implementation::IsExtension<>::value);
}
void ContextTest::constructNoCreate() { void ContextTest::constructNoCreate() {
{ {
/* Shouldn't crash during construction, shouldn't attempt to access GL, /* Shouldn't crash during construction, shouldn't attempt to access GL,

Loading…
Cancel
Save