Browse Source

GL: avoid populating and sorting (!!) a vector of strings for exts.

Ew. At first I tried to just port a growable Array of StringViews (which
would already save quite a lot), but then I realized I have a clear
upper bound on the extensions and so can use a "counting sort" without
having to deduplicate anything after.

After the previous (rather minimal) reduction by the Context cleanup,
this reduces the size of magnum-gl-info.wasm from 245 to 237 kB. Quite
significant, I'd say!
euler-xxx
Vladimír Vondruš 5 years ago
parent
commit
e96996ea01
  1. 11
      src/Magnum/GL/Context.h
  2. 16
      src/Magnum/GL/GL.h
  3. 11
      src/Magnum/GL/Implementation/BufferState.cpp
  4. 4
      src/Magnum/GL/Implementation/BufferState.h
  5. 2
      src/Magnum/GL/Implementation/ContextState.cpp
  6. 6
      src/Magnum/GL/Implementation/ContextState.h
  7. 17
      src/Magnum/GL/Implementation/DebugState.cpp
  8. 5
      src/Magnum/GL/Implementation/DebugState.h
  9. 83
      src/Magnum/GL/Implementation/FramebufferState.cpp
  10. 5
      src/Magnum/GL/Implementation/FramebufferState.h
  11. 85
      src/Magnum/GL/Implementation/MeshState.cpp
  12. 5
      src/Magnum/GL/Implementation/MeshState.h
  13. 14
      src/Magnum/GL/Implementation/QueryState.cpp
  14. 6
      src/Magnum/GL/Implementation/QueryState.h
  15. 21
      src/Magnum/GL/Implementation/RendererState.cpp
  16. 5
      src/Magnum/GL/Implementation/RendererState.h
  17. 8
      src/Magnum/GL/Implementation/ShaderProgramState.cpp
  18. 6
      src/Magnum/GL/Implementation/ShaderProgramState.h
  19. 2
      src/Magnum/GL/Implementation/ShaderState.cpp
  20. 6
      src/Magnum/GL/Implementation/ShaderState.h
  21. 24
      src/Magnum/GL/Implementation/State.cpp
  22. 47
      src/Magnum/GL/Implementation/TextureState.cpp
  23. 4
      src/Magnum/GL/Implementation/TextureState.h
  24. 5
      src/Magnum/GL/Implementation/TransformFeedbackState.cpp
  25. 7
      src/Magnum/GL/Implementation/TransformFeedbackState.h

11
src/Magnum/GL/Context.h

@ -57,17 +57,6 @@ namespace GL {
namespace Implementation { namespace Implementation {
struct ContextState; struct ContextState;
struct State; struct State;
enum: std::size_t {
ExtensionCount =
#ifndef MAGNUM_TARGET_GLES
192
#elif !defined(MAGNUM_TARGET_WEBGL)
160
#else
48
#endif
};
} }
/** /**

16
src/Magnum/GL/GL.h

@ -29,6 +29,8 @@
* @brief Forward declarations for the @ref Magnum::GL namespace * @brief Forward declarations for the @ref Magnum::GL namespace
*/ */
#include <cstddef>
#include "Magnum/Types.h" #include "Magnum/Types.h"
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
@ -40,6 +42,20 @@ typedef unsigned int GLuint; /* Needed by Implementation/State.h */
namespace Magnum { namespace GL { namespace Magnum { namespace GL {
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
/* Needed by Context as well as all Implementation::*State classes */
enum: std::size_t {
ExtensionCount =
#ifndef MAGNUM_TARGET_GLES
192
#elif !defined(MAGNUM_TARGET_WEBGL)
160
#else
48
#endif
};
}
/* FramebufferClear[Mask], FramebufferBlit[Mask], FramebufferBlitFilter, /* FramebufferClear[Mask], FramebufferBlit[Mask], FramebufferBlitFilter,
FramebufferTarget enums used only directly with framebuffer instance */ FramebufferTarget enums used only directly with framebuffer instance */
class AbstractFramebuffer; class AbstractFramebuffer;

11
src/Magnum/GL/Implementation/BufferState.cpp

@ -80,7 +80,7 @@ std::size_t BufferState::indexForTarget(Buffer::TargetHint target) {
CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
} }
BufferState::BufferState(Context& context, std::vector<std::string>& extensions): bindings() BufferState::BufferState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions): bindings()
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
, minMapAlignment(0) , minMapAlignment(0)
@ -99,7 +99,8 @@ BufferState::BufferState(Context& context, std::vector<std::string>& extensions)
context.isDriverWorkaroundDisabled("intel-windows-crazy-broken-buffer-dsa"_s)) context.isDriverWorkaroundDisabled("intel-windows-crazy-broken-buffer-dsa"_s))
#endif #endif
) { ) {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
createImplementation = &Buffer::createImplementationDSA; createImplementation = &Buffer::createImplementationDSA;
copyImplementation = &Buffer::copyImplementationDSA; copyImplementation = &Buffer::copyImplementationDSA;
@ -140,7 +141,8 @@ BufferState::BufferState(Context& context, std::vector<std::string>& extensions)
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::invalidate_subdata>()) { if(context.isExtensionSupported<Extensions::ARB::invalidate_subdata>()) {
extensions.emplace_back(Extensions::ARB::invalidate_subdata::string()); extensions[Extensions::ARB::invalidate_subdata::Index] =
Extensions::ARB::invalidate_subdata::string();
invalidateImplementation = &Buffer::invalidateImplementationARB; invalidateImplementation = &Buffer::invalidateImplementationARB;
invalidateSubImplementation = &Buffer::invalidateSubImplementationARB; invalidateSubImplementation = &Buffer::invalidateSubImplementationARB;
@ -154,7 +156,8 @@ BufferState::BufferState(Context& context, std::vector<std::string>& extensions)
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::multi_bind>()) { if(context.isExtensionSupported<Extensions::ARB::multi_bind>()) {
extensions.emplace_back(Extensions::ARB::multi_bind::string()); extensions[Extensions::ARB::multi_bind::Index] =
Extensions::ARB::multi_bind::string();
bindBasesImplementation = &Buffer::bindImplementationMulti; bindBasesImplementation = &Buffer::bindImplementationMulti;
bindRangesImplementation = &Buffer::bindImplementationMulti; bindRangesImplementation = &Buffer::bindImplementationMulti;

4
src/Magnum/GL/Implementation/BufferState.h

@ -25,8 +25,6 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <vector>
#include "Magnum/GL/Buffer.h" #include "Magnum/GL/Buffer.h"
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
@ -46,7 +44,7 @@ struct BufferState {
static std::size_t indexForTarget(Buffer::TargetHint target); static std::size_t indexForTarget(Buffer::TargetHint target);
static const Buffer::TargetHint targetForIndex[TargetCount-1]; static const Buffer::TargetHint targetForIndex[TargetCount-1];
explicit BufferState(Context& context, std::vector<std::string>& extensions); explicit BufferState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
void reset(); void reset();

2
src/Magnum/GL/Implementation/ContextState.cpp

@ -33,7 +33,7 @@ namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals; using namespace Containers::Literals;
ContextState::ContextState(Context& context, std::vector<std::string>&) { ContextState::ContextState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*>) {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if((context.detectedDriver() & Context::DetectedDriver::NVidia) && if((context.detectedDriver() & Context::DetectedDriver::NVidia) &&
!context.isDriverWorkaroundDisabled("nv-zero-context-profile-mask"_s)) !context.isDriverWorkaroundDisabled("nv-zero-context-profile-mask"_s))

6
src/Magnum/GL/Implementation/ContextState.h

@ -25,9 +25,7 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string> #include "Magnum/Magnum.h"
#include <vector>
#include "Magnum/GL/GL.h" #include "Magnum/GL/GL.h"
#ifdef _MSC_VER #ifdef _MSC_VER
@ -40,7 +38,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
struct ContextState { struct ContextState {
explicit ContextState(Context& context, std::vector<std::string>& extensions); explicit ContextState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
enum class CoreProfile { enum class CoreProfile {

17
src/Magnum/GL/Implementation/DebugState.cpp

@ -31,7 +31,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
DebugState::DebugState(Context& context, std::vector<std::string>& extensions): DebugState::DebugState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions):
maxLabelLength{0}, maxLabelLength{0},
maxLoggedMessages{0}, maxLoggedMessages{0},
maxMessageLength{0}, maxMessageLength{0},
@ -45,7 +45,8 @@ DebugState::DebugState(Context& context, std::vector<std::string>& extensions):
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::KHR::debug::string()); extensions[Extensions::KHR::debug::Index] =
Extensions::KHR::debug::string();
#endif #endif
getLabelImplementation = &AbstractObject::getLabelImplementationKhrDesktopES32; getLabelImplementation = &AbstractObject::getLabelImplementationKhrDesktopES32;
@ -60,7 +61,8 @@ DebugState::DebugState(Context& context, std::vector<std::string>& extensions):
#endif #endif
#ifdef MAGNUM_TARGET_GLES #ifdef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::KHR::debug>()) { if(context.isExtensionSupported<Extensions::KHR::debug>()) {
extensions.emplace_back(Extensions::KHR::debug::string()); extensions[Extensions::KHR::debug::Index] =
Extensions::KHR::debug::string();
getLabelImplementation = &AbstractObject::getLabelImplementationKhrES; getLabelImplementation = &AbstractObject::getLabelImplementationKhrES;
labelImplementation = &AbstractObject::labelImplementationKhrES; labelImplementation = &AbstractObject::labelImplementationKhrES;
@ -74,7 +76,8 @@ DebugState::DebugState(Context& context, std::vector<std::string>& extensions):
#endif #endif
{ {
if(context.isExtensionSupported<Extensions::EXT::debug_label>()) { if(context.isExtensionSupported<Extensions::EXT::debug_label>()) {
extensions.emplace_back(Extensions::EXT::debug_label::string()); extensions[Extensions::EXT::debug_label::Index] =
Extensions::EXT::debug_label::string();
getLabelImplementation = &AbstractObject::getLabelImplementationExt; getLabelImplementation = &AbstractObject::getLabelImplementationExt;
labelImplementation = &AbstractObject::labelImplementationExt; labelImplementation = &AbstractObject::labelImplementationExt;
@ -84,14 +87,16 @@ DebugState::DebugState(Context& context, std::vector<std::string>& extensions):
} }
if(context.isExtensionSupported<Extensions::EXT::debug_marker>()) { if(context.isExtensionSupported<Extensions::EXT::debug_marker>()) {
extensions.emplace_back(Extensions::EXT::debug_marker::string()); extensions[Extensions::EXT::debug_marker::Index] =
Extensions::EXT::debug_marker::string();
pushGroupImplementation = &DebugGroup::pushImplementationExt; pushGroupImplementation = &DebugGroup::pushImplementationExt;
popGroupImplementation = &DebugGroup::popImplementationExt; popGroupImplementation = &DebugGroup::popImplementationExt;
messageInsertImplementation = &DebugMessage::insertImplementationExt; messageInsertImplementation = &DebugMessage::insertImplementationExt;
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
} else if(context.isExtensionSupported<Extensions::GREMEDY::string_marker>()) { } else if(context.isExtensionSupported<Extensions::GREMEDY::string_marker>()) {
extensions.emplace_back(Extensions::GREMEDY::string_marker::string()); extensions[Extensions::GREMEDY::string_marker::Index] =
Extensions::GREMEDY::string_marker::string();
pushGroupImplementation = &DebugGroup::pushImplementationNoOp; pushGroupImplementation = &DebugGroup::pushImplementationNoOp;
popGroupImplementation = &DebugGroup::popImplementationNoOp; popGroupImplementation = &DebugGroup::popImplementationNoOp;

5
src/Magnum/GL/Implementation/DebugState.h

@ -25,9 +25,6 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string>
#include <vector>
#include "Magnum/GL/DebugOutput.h" #include "Magnum/GL/DebugOutput.h"
#include "Magnum/GL/GL.h" #include "Magnum/GL/GL.h"
@ -38,7 +35,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
struct DebugState { struct DebugState {
explicit DebugState(Context& context, std::vector<std::string>& extensions); explicit DebugState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
std::string(*getLabelImplementation)(GLenum, GLuint); std::string(*getLabelImplementation)(GLenum, GLuint);
void(*labelImplementation)(GLenum, GLuint, Containers::ArrayView<const char>); void(*labelImplementation)(GLenum, GLuint, Containers::ArrayView<const char>);

83
src/Magnum/GL/Implementation/FramebufferState.cpp

@ -39,7 +39,7 @@ using namespace Containers::Literals;
constexpr const Range2Di FramebufferState::DisengagedViewport; constexpr const Range2Di FramebufferState::DisengagedViewport;
FramebufferState::FramebufferState(Context& context, std::vector<std::string>& extensions): readBinding{0}, drawBinding{0}, renderbufferBinding{0}, maxDrawBuffers{0}, maxColorAttachments{0}, maxRenderbufferSize{0}, FramebufferState::FramebufferState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions): readBinding{0}, drawBinding{0}, renderbufferBinding{0}, maxDrawBuffers{0}, maxColorAttachments{0}, maxRenderbufferSize{0},
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
maxSamples{0}, maxSamples{0},
#endif #endif
@ -51,7 +51,9 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Create implementation */ /* Create implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
createImplementation = &Framebuffer::createImplementationDSA; createImplementation = &Framebuffer::createImplementationDSA;
createRenderbufferImplementation = &Renderbuffer::createImplementationDSA; createRenderbufferImplementation = &Renderbuffer::createImplementationDSA;
@ -65,7 +67,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* DSA/non-DSA implementation */ /* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
/* Extension added above */ extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSA; checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSA;
@ -143,7 +146,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
} else } else
#endif #endif
{ {
/* Extension name added above */ extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
copySubCubeMapImplementation = &AbstractFramebuffer::copySubCubeMapImplementationDSA; copySubCubeMapImplementation = &AbstractFramebuffer::copySubCubeMapImplementationDSA;
textureCubeMapImplementation = &Framebuffer::textureCubeMapImplementationDSA; textureCubeMapImplementation = &Framebuffer::textureCubeMapImplementationDSA;
@ -165,7 +169,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
context.isDriverWorkaroundDisabled("intel-windows-broken-dsa-layered-cubemap-array-framebuffer-attachment"_s)) context.isDriverWorkaroundDisabled("intel-windows-broken-dsa-layered-cubemap-array-framebuffer-attachment"_s))
#endif #endif
) { ) {
/* Extension name added above */ extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
layeredTextureCubeMapArrayImplementation = &Framebuffer::textureImplementationDSA; layeredTextureCubeMapArrayImplementation = &Framebuffer::textureImplementationDSA;
} else } else
@ -203,12 +208,16 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Framebuffer texture attachment on ES3 */ /* Framebuffer texture attachment on ES3 */
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2) #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2)
if(context.isVersionSupported(Version::GLES320)) if(context.isVersionSupported(Version::GLES320)) {
textureImplementation = &Framebuffer::textureImplementationDefault; textureImplementation = &Framebuffer::textureImplementationDefault;
else if(context.isExtensionSupported<Extensions::EXT::geometry_shader>()) } else if(context.isExtensionSupported<Extensions::EXT::geometry_shader>()) {
extensions[Extensions::EXT::geometry_shader::Index] =
Extensions::EXT::geometry_shader::string();
textureImplementation = &Framebuffer::textureImplementationEXT; textureImplementation = &Framebuffer::textureImplementationEXT;
else } else {
textureImplementation = nullptr; textureImplementation = nullptr;
}
#endif #endif
#ifdef MAGNUM_TARGET_GLES2 #ifdef MAGNUM_TARGET_GLES2
@ -221,20 +230,24 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
checkStatusImplementation = &Framebuffer::checkStatusImplementationDefault; checkStatusImplementation = &Framebuffer::checkStatusImplementationDefault;
if(context.isExtensionSupported<Extensions::ANGLE::framebuffer_blit>()) { if(context.isExtensionSupported<Extensions::ANGLE::framebuffer_blit>()) {
extensions.push_back(Extensions::ANGLE::framebuffer_blit::string()); extensions[Extensions::ANGLE::framebuffer_blit::Index] =
Extensions::ANGLE::framebuffer_blit::string();
} else if(context.isExtensionSupported<Extensions::APPLE::framebuffer_multisample>()) { } else if(context.isExtensionSupported<Extensions::APPLE::framebuffer_multisample>()) {
extensions.push_back(Extensions::APPLE::framebuffer_multisample::string()); extensions[Extensions::APPLE::framebuffer_multisample::Index] =
Extensions::APPLE::framebuffer_multisample::string();
} else if(context.isExtensionSupported<Extensions::NV::framebuffer_blit>()) { } else if(context.isExtensionSupported<Extensions::NV::framebuffer_blit>()) {
extensions.push_back(Extensions::NV::framebuffer_blit::string()); extensions[Extensions::NV::framebuffer_blit::Index] =
Extensions::NV::framebuffer_blit::string();
/* NV_framebuffer_multisample requires NV_framebuffer_blit, which has these /* NV_framebuffer_multisample requires NV_framebuffer_blit, which has these
enums. However, on my system only NV_framebuffer_multisample is enums. However, on my system only NV_framebuffer_multisample is
supported, but NV_framebuffer_blit isn't. I will hold my breath and supported, but NV_framebuffer_blit isn't. I will hold my breath and
assume these enums are available. */ assume these enums are available. */
} else if(context.isExtensionSupported<Extensions::NV::framebuffer_multisample>()) { } else if(context.isExtensionSupported<Extensions::NV::framebuffer_multisample>()) {
extensions.push_back(Extensions::NV::framebuffer_multisample::string()); extensions[Extensions::NV::framebuffer_multisample::Index] =
Extensions::NV::framebuffer_multisample::string();
/* If no such extension is available, reset back to single target */ /* If no such extension is available, reset back to single target */
} else { } else {
@ -249,17 +262,21 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
/* Framebuffer draw mapping on ES2 */ /* Framebuffer draw mapping on ES2 */
if(context.isExtensionSupported<Extensions::EXT::draw_buffers>()) { if(context.isExtensionSupported<Extensions::EXT::draw_buffers>()) {
extensions.push_back(Extensions::EXT::draw_buffers::string()); extensions[Extensions::EXT::draw_buffers::Index] =
Extensions::EXT::draw_buffers::string();
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationEXT; drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationEXT;
} else if(context.isExtensionSupported<Extensions::NV::draw_buffers>()) { } else if(context.isExtensionSupported<Extensions::NV::draw_buffers>()) {
extensions.push_back(Extensions::NV::draw_buffers::string()); extensions[Extensions::NV::draw_buffers::Index] =
Extensions::NV::draw_buffers::string();
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationNV; drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationNV;
} else drawBuffersImplementation = nullptr; } else drawBuffersImplementation = nullptr;
#else #else
if(context.isExtensionSupported<Extensions::WEBGL::draw_buffers>()) { if(context.isExtensionSupported<Extensions::WEBGL::draw_buffers>()) {
extensions.push_back(Extensions::WEBGL::draw_buffers::string()); extensions[Extensions::WEBGL::draw_buffers::Index] =
Extensions::WEBGL::draw_buffers::string();
/* The EXT implementation is exposed in Emscripten */ /* The EXT implementation is exposed in Emscripten */
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationEXT; drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationEXT;
} else drawBuffersImplementation = nullptr; } else drawBuffersImplementation = nullptr;
@ -296,7 +313,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>() if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()
&& !((context.detectedDriver() & Context::DetectedDriver::NVidia) && !context.isDriverWorkaroundDisabled("nv-implementation-color-read-format-dsa-broken"_s)) && !((context.detectedDriver() & Context::DetectedDriver::NVidia) && !context.isDriverWorkaroundDisabled("nv-implementation-color-read-format-dsa-broken"_s))
) { ) {
/* DSA extension added above */ extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
if((context.detectedDriver() & Context::DetectedDriver::Mesa) && !context.isDriverWorkaroundDisabled("mesa-implementation-color-read-format-dsa-explicit-binding"_s)) if((context.detectedDriver() & Context::DetectedDriver::Mesa) && !context.isDriverWorkaroundDisabled("mesa-implementation-color-read-format-dsa-explicit-binding"_s))
implementationColorReadFormatTypeImplementation = &AbstractFramebuffer::implementationColorReadFormatTypeImplementationFramebufferDSAMesa; implementationColorReadFormatTypeImplementation = &AbstractFramebuffer::implementationColorReadFormatTypeImplementationFramebufferDSAMesa;
@ -319,9 +337,11 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::ARB::robustness::string()); extensions[Extensions::ARB::robustness::Index] =
Extensions::ARB::robustness::string();
#else #else
extensions.push_back(Extensions::EXT::robustness::string()); extensions[Extensions::EXT::robustness::Index] =
Extensions::EXT::robustness::string();
#endif #endif
readImplementation = &AbstractFramebuffer::readImplementationRobustness; readImplementation = &AbstractFramebuffer::readImplementationRobustness;
@ -335,7 +355,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Multisample renderbuffer storage implementation */ /* Multisample renderbuffer storage implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
/* Extension added above */ extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSA; renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSA;
@ -344,11 +365,13 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
{ {
#if defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isExtensionSupported<Extensions::ANGLE::framebuffer_multisample>()) { if(context.isExtensionSupported<Extensions::ANGLE::framebuffer_multisample>()) {
extensions.push_back(Extensions::ANGLE::framebuffer_multisample::string()); extensions[Extensions::ANGLE::framebuffer_multisample::Index] =
Extensions::ANGLE::framebuffer_multisample::string();
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationANGLE; renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationANGLE;
} else if (context.isExtensionSupported<Extensions::NV::framebuffer_multisample>()) { } else if (context.isExtensionSupported<Extensions::NV::framebuffer_multisample>()) {
extensions.push_back(Extensions::NV::framebuffer_multisample::string()); extensions[Extensions::NV::framebuffer_multisample::Index] =
Extensions::NV::framebuffer_multisample::string();
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationNV; renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationNV;
} else renderbufferStorageMultisampleImplementation = nullptr; } else renderbufferStorageMultisampleImplementation = nullptr;
@ -360,7 +383,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Framebuffer invalidation implementation on desktop GL */ /* Framebuffer invalidation implementation on desktop GL */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::invalidate_subdata>()) { if(context.isExtensionSupported<Extensions::ARB::invalidate_subdata>()) {
extensions.emplace_back(Extensions::ARB::invalidate_subdata::string()); extensions[Extensions::ARB::invalidate_subdata::Index] =
Extensions::ARB::invalidate_subdata::string();
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
/* Extension added above */ /* Extension added above */
@ -379,7 +403,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Framebuffer invalidation implementation on ES2 */ /* Framebuffer invalidation implementation on ES2 */
#elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isExtensionSupported<Extensions::EXT::discard_framebuffer>()) { if(context.isExtensionSupported<Extensions::EXT::discard_framebuffer>()) {
extensions.push_back(Extensions::EXT::discard_framebuffer::string()); extensions[Extensions::EXT::discard_framebuffer::Index] =
Extensions::EXT::discard_framebuffer::string();
invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDefault; invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDefault;
} else { } else {
@ -395,7 +420,9 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Blit implementation on desktop GL */ /* Blit implementation on desktop GL */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
/* Extension added above */ extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
blitImplementation = &AbstractFramebuffer::blitImplementationDSA; blitImplementation = &AbstractFramebuffer::blitImplementationDSA;
} else blitImplementation = &AbstractFramebuffer::blitImplementationDefault; } else blitImplementation = &AbstractFramebuffer::blitImplementationDefault;
@ -403,11 +430,15 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Blit implementation on ES2 */ /* Blit implementation on ES2 */
#elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isExtensionSupported<Extensions::ANGLE::framebuffer_blit>()) { if(context.isExtensionSupported<Extensions::ANGLE::framebuffer_blit>()) {
extensions.push_back(Extensions::ANGLE::framebuffer_blit::string()); extensions[Extensions::ANGLE::framebuffer_blit::Index] =
Extensions::ANGLE::framebuffer_blit::string();
blitImplementation = &AbstractFramebuffer::blitImplementationANGLE; blitImplementation = &AbstractFramebuffer::blitImplementationANGLE;
} else if(context.isExtensionSupported<Extensions::NV::framebuffer_blit>()) { } else if(context.isExtensionSupported<Extensions::NV::framebuffer_blit>()) {
extensions.push_back(Extensions::NV::framebuffer_blit::string()); extensions[Extensions::NV::framebuffer_blit::Index] =
Extensions::NV::framebuffer_blit::string();
blitImplementation = &AbstractFramebuffer::blitImplementationNV; blitImplementation = &AbstractFramebuffer::blitImplementationNV;
} else blitImplementation = nullptr; } else blitImplementation = nullptr;

5
src/Magnum/GL/Implementation/FramebufferState.h

@ -25,9 +25,6 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string>
#include <vector>
#include "Magnum/GL/Framebuffer.h" #include "Magnum/GL/Framebuffer.h"
#ifdef _MSC_VER #ifdef _MSC_VER
@ -42,7 +39,7 @@ namespace Magnum { namespace GL { namespace Implementation {
struct FramebufferState { struct FramebufferState {
constexpr static const Range2Di DisengagedViewport{{}, {-1, -1}}; constexpr static const Range2Di DisengagedViewport{{}, {-1, -1}};
explicit FramebufferState(Context& context, std::vector<std::string>& extensions); explicit FramebufferState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
void reset(); void reset();

85
src/Magnum/GL/Implementation/MeshState.cpp

@ -37,7 +37,7 @@ namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals; using namespace Containers::Literals;
MeshState::MeshState(Context& context, ContextState& contextState, std::vector<std::string>& extensions): currentVAO(0) MeshState::MeshState(Context& context, ContextState& contextState, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions): currentVAO(0)
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
, maxElementIndex{0}, maxElementsIndices{0}, maxElementsVertices{0} , maxElementIndex{0}, maxElementsIndices{0}, maxElementsVertices{0}
#endif #endif
@ -52,9 +52,11 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::ARB::vertex_array_object::string()); extensions[Extensions::ARB::vertex_array_object::Index] =
Extensions::ARB::vertex_array_object::string();
#elif defined(MAGNUM_TARGET_GLES2) #elif defined(MAGNUM_TARGET_GLES2)
extensions.push_back(Extensions::OES::vertex_array_object::string()); extensions[Extensions::OES::vertex_array_object::Index] =
Extensions::OES::vertex_array_object::string();
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -64,7 +66,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
context.isDriverWorkaroundDisabled("intel-windows-crazy-broken-vao-dsa"_s)) context.isDriverWorkaroundDisabled("intel-windows-crazy-broken-vao-dsa"_s))
#endif #endif
) { ) {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
/* Intel Windows drivers are ... special */ /* Intel Windows drivers are ... special */
#ifdef CORRADE_TARGET_WINDOWS #ifdef CORRADE_TARGET_WINDOWS
@ -122,7 +125,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
} else } else
#endif #endif
if(context.isExtensionSupported<Extensions::EXT::draw_elements_base_vertex>()) { if(context.isExtensionSupported<Extensions::EXT::draw_elements_base_vertex>()) {
extensions.push_back(Extensions::EXT::draw_elements_base_vertex::string()); extensions[Extensions::EXT::draw_elements_base_vertex::Index] =
Extensions::EXT::draw_elements_base_vertex::string();
drawElementsBaseVertexImplementation = glDrawElementsBaseVertexEXT; drawElementsBaseVertexImplementation = glDrawElementsBaseVertexEXT;
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -130,7 +134,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
drawElementsInstancedBaseVertexImplementation = glDrawElementsInstancedBaseVertexEXT; drawElementsInstancedBaseVertexImplementation = glDrawElementsInstancedBaseVertexEXT;
#endif #endif
} else if(context.isExtensionSupported<Extensions::OES::draw_elements_base_vertex>()) { } else if(context.isExtensionSupported<Extensions::OES::draw_elements_base_vertex>()) {
extensions.push_back(Extensions::OES::draw_elements_base_vertex::string()); extensions[Extensions::OES::draw_elements_base_vertex::Index] =
Extensions::OES::draw_elements_base_vertex::string();
drawElementsBaseVertexImplementation = glDrawElementsBaseVertexOES; drawElementsBaseVertexImplementation = glDrawElementsBaseVertexOES;
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -140,7 +145,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
} else } else
#else #else
if(context.isExtensionSupported<Extensions::WEBGL::draw_instanced_base_vertex_base_instance>()) { if(context.isExtensionSupported<Extensions::WEBGL::draw_instanced_base_vertex_base_instance>()) {
extensions.push_back(Extensions::WEBGL::draw_instanced_base_vertex_base_instance::string()); extensions[Extensions::WEBGL::draw_instanced_base_vertex_base_instance::Index] =
Extensions::WEBGL::draw_instanced_base_vertex_base_instance::string();
/* The WEBGL extension uses the same entrypoints as the ANGLE extension /* The WEBGL extension uses the same entrypoints as the ANGLE extension
it was based on, however we wrap it to supply trivial instance count it was based on, however we wrap it to supply trivial instance count
@ -171,7 +177,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
if(context.isExtensionSupported<Extensions::ANGLE::base_vertex_base_instance>()) { if(context.isExtensionSupported<Extensions::ANGLE::base_vertex_base_instance>()) {
extensions.push_back(Extensions::ANGLE::base_vertex_base_instance::string()); extensions[Extensions::ANGLE::base_vertex_base_instance::Index] =
Extensions::ANGLE::base_vertex_base_instance::string();
drawArraysInstancedBaseInstanceImplementation = glDrawArraysInstancedBaseInstanceANGLE; drawArraysInstancedBaseInstanceImplementation = glDrawArraysInstancedBaseInstanceANGLE;
/* This variant isn't in the ext, emulated using /* This variant isn't in the ext, emulated using
@ -182,7 +189,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#endif #endif
#else #else
if(context.isExtensionSupported<Extensions::WEBGL::draw_instanced_base_vertex_base_instance>()) { if(context.isExtensionSupported<Extensions::WEBGL::draw_instanced_base_vertex_base_instance>()) {
extensions.push_back(Extensions::WEBGL::draw_instanced_base_vertex_base_instance::string()); extensions[Extensions::WEBGL::draw_instanced_base_vertex_base_instance::Index] =
Extensions::WEBGL::draw_instanced_base_vertex_base_instance::string();
/* The WEBGL extension uses the same entrypoints as the ANGLE extension /* The WEBGL extension uses the same entrypoints as the ANGLE extension
it was based on. Only available since 1.39.15: it was based on. Only available since 1.39.15:
@ -221,19 +229,22 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
{ {
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
if(context.isExtensionSupported<Extensions::EXT::multi_draw_arrays>()) { if(context.isExtensionSupported<Extensions::EXT::multi_draw_arrays>()) {
extensions.push_back(Extensions::EXT::multi_draw_arrays::string()); extensions[Extensions::EXT::multi_draw_arrays::Index] =
Extensions::EXT::multi_draw_arrays::string();
multiDrawArraysImplementation = glMultiDrawArraysEXT; multiDrawArraysImplementation = glMultiDrawArraysEXT;
multiDrawElementsImplementation = glMultiDrawElementsEXT; multiDrawElementsImplementation = glMultiDrawElementsEXT;
} else if(context.isExtensionSupported<Extensions::ANGLE::multi_draw>()) { } else if(context.isExtensionSupported<Extensions::ANGLE::multi_draw>()) {
extensions.push_back(Extensions::ANGLE::multi_draw::string()); extensions[Extensions::ANGLE::multi_draw::Index] =
Extensions::ANGLE::multi_draw::string();
multiDrawArraysImplementation = glMultiDrawArraysANGLE; multiDrawArraysImplementation = glMultiDrawArraysANGLE;
multiDrawElementsImplementation = glMultiDrawElementsANGLE; multiDrawElementsImplementation = glMultiDrawElementsANGLE;
} else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); } else CORRADE_INTERNAL_ASSERT_UNREACHABLE();
#else #else
{ {
extensions.push_back(Extensions::WEBGL::multi_draw::string()); extensions[Extensions::WEBGL::multi_draw::Index] =
Extensions::WEBGL::multi_draw::string();
/* The WEBGL extension uses the same entrypoints as the ANGLE /* The WEBGL extension uses the same entrypoints as the ANGLE
extension it was based on. Only available since 2.0.0: extension it was based on. Only available since 2.0.0:
@ -254,11 +265,13 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
if(context.isExtensionSupported<Extensions::EXT::draw_elements_base_vertex>()) { if(context.isExtensionSupported<Extensions::EXT::draw_elements_base_vertex>()) {
extensions.push_back(Extensions::EXT::draw_elements_base_vertex::string()); extensions[Extensions::EXT::draw_elements_base_vertex::Index] =
Extensions::EXT::draw_elements_base_vertex::string();
multiDrawElementsBaseVertexImplementation = glMultiDrawElementsBaseVertexEXT; multiDrawElementsBaseVertexImplementation = glMultiDrawElementsBaseVertexEXT;
} else if(context.isExtensionSupported<Extensions::OES::draw_elements_base_vertex>()) { } else if(context.isExtensionSupported<Extensions::OES::draw_elements_base_vertex>()) {
extensions.push_back(Extensions::OES::draw_elements_base_vertex::string()); extensions[Extensions::OES::draw_elements_base_vertex::Index] =
Extensions::OES::draw_elements_base_vertex::string();
/* Yes, it's really EXT, the same as with /* Yes, it's really EXT, the same as with
EXT_draw_elements_base_vertex. I have no idea why the two EXT_draw_elements_base_vertex. I have no idea why the two
@ -267,7 +280,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
} else } else
#else #else
if(context.isExtensionSupported<Extensions::WEBGL::multi_draw_instanced_base_vertex_base_instance>()) { if(context.isExtensionSupported<Extensions::WEBGL::multi_draw_instanced_base_vertex_base_instance>()) {
extensions.push_back(Extensions::WEBGL::multi_draw_instanced_base_vertex_base_instance::string()); extensions[Extensions::WEBGL::multi_draw_instanced_base_vertex_base_instance::Index] =
Extensions::WEBGL::multi_draw_instanced_base_vertex_base_instance::string();
/* The WEBGL extension uses the same entrypoints as the ANGLE /* The WEBGL extension uses the same entrypoints as the ANGLE
extension it was based on, however we wrap it and supply trivial extension it was based on, however we wrap it and supply trivial
@ -295,7 +309,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#ifdef MAGNUM_TARGET_GLES2 #ifdef MAGNUM_TARGET_GLES2
/* Instanced draw ímplementation on ES2 */ /* Instanced draw ímplementation on ES2 */
if(context.isExtensionSupported<Extensions::ANGLE::instanced_arrays>()) { if(context.isExtensionSupported<Extensions::ANGLE::instanced_arrays>()) {
extensions.push_back(Extensions::ANGLE::instanced_arrays::string()); extensions[Extensions::ANGLE::instanced_arrays::Index] =
Extensions::ANGLE::instanced_arrays::string();
drawArraysInstancedImplementation = glDrawArraysInstancedANGLE; drawArraysInstancedImplementation = glDrawArraysInstancedANGLE;
drawElementsInstancedImplementation = glDrawElementsInstancedANGLE; drawElementsInstancedImplementation = glDrawElementsInstancedANGLE;
@ -303,18 +318,22 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
else if(context.isExtensionSupported<Extensions::EXT::instanced_arrays>() || else if(context.isExtensionSupported<Extensions::EXT::instanced_arrays>() ||
context.isExtensionSupported<Extensions::EXT::draw_instanced>()) { context.isExtensionSupported<Extensions::EXT::draw_instanced>()) {
extensions.push_back(context.isExtensionSupported<Extensions::EXT::instanced_arrays>() ? if(context.isExtensionSupported<Extensions::EXT::instanced_arrays>())
Extensions::EXT::instanced_arrays::string() : extensions[Extensions::EXT::instanced_arrays::Index] =
Extensions::EXT::draw_instanced::string()); Extensions::EXT::instanced_arrays::string();
else extensions[Extensions::EXT::draw_instanced::Index] =
Extensions::EXT::draw_instanced::string();
drawArraysInstancedImplementation = glDrawArraysInstancedEXT; drawArraysInstancedImplementation = glDrawArraysInstancedEXT;
drawElementsInstancedImplementation = glDrawElementsInstancedEXT; drawElementsInstancedImplementation = glDrawElementsInstancedEXT;
} else if(context.isExtensionSupported<Extensions::NV::instanced_arrays>() || } else if(context.isExtensionSupported<Extensions::NV::instanced_arrays>() ||
context.isExtensionSupported<Extensions::NV::draw_instanced>()) { context.isExtensionSupported<Extensions::NV::draw_instanced>()) {
extensions.push_back(context.isExtensionSupported<Extensions::NV::instanced_arrays>() ? if(context.isExtensionSupported<Extensions::NV::instanced_arrays>())
Extensions::NV::instanced_arrays::string() : extensions[Extensions::NV::instanced_arrays::Index] =
Extensions::NV::draw_instanced::string()); Extensions::NV::instanced_arrays::string();
else extensions[Extensions::NV::draw_instanced::Index] =
Extensions::NV::draw_instanced::string();
drawArraysInstancedImplementation = glDrawArraysInstancedNV; drawArraysInstancedImplementation = glDrawArraysInstancedNV;
drawElementsInstancedImplementation = glDrawElementsInstancedNV; drawElementsInstancedImplementation = glDrawElementsInstancedNV;
@ -332,27 +351,37 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
&& (!(context.detectedDriver() & Context::DetectedDriver::IntelWindows) || && (!(context.detectedDriver() & Context::DetectedDriver::IntelWindows) ||
context.isDriverWorkaroundDisabled("intel-windows-crazy-broken-vao-dsa"_s)) context.isDriverWorkaroundDisabled("intel-windows-crazy-broken-vao-dsa"_s))
#endif #endif
) ) {
extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAODSA; vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAODSA;
else if(context.isExtensionSupported<Extensions::ARB::vertex_array_object>()) } else if(context.isExtensionSupported<Extensions::ARB::vertex_array_object>()) {
extensions[Extensions::ARB::vertex_array_object::Index] =
Extensions::ARB::vertex_array_object::string();
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAO; vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAO;
else } else {
vertexAttribDivisorImplementation = nullptr; vertexAttribDivisorImplementation = nullptr;
}
#elif defined(MAGNUM_TARGET_GLES2) #elif defined(MAGNUM_TARGET_GLES2)
/* Instanced arrays implementation on ES2 */ /* Instanced arrays implementation on ES2 */
if(context.isExtensionSupported<Extensions::ANGLE::instanced_arrays>()) { if(context.isExtensionSupported<Extensions::ANGLE::instanced_arrays>()) {
/* Extension added above */ extensions[Extensions::ANGLE::instanced_arrays::Index] =
Extensions::ANGLE::instanced_arrays::string();
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationANGLE; vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationANGLE;
} }
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
else if(context.isExtensionSupported<Extensions::EXT::instanced_arrays>()) { else if(context.isExtensionSupported<Extensions::EXT::instanced_arrays>()) {
extensions.push_back(Extensions::EXT::instanced_arrays::string()); extensions[Extensions::EXT::instanced_arrays::Index] =
Extensions::EXT::instanced_arrays::string();
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationEXT; vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationEXT;
} else if(context.isExtensionSupported<Extensions::NV::instanced_arrays>()) { } else if(context.isExtensionSupported<Extensions::NV::instanced_arrays>()) {
extensions.push_back(Extensions::NV::instanced_arrays::string()); extensions[Extensions::NV::instanced_arrays::Index] =
Extensions::NV::instanced_arrays::string();
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationNV; vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationNV;
} }

5
src/Magnum/GL/Implementation/MeshState.h

@ -25,9 +25,6 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <vector>
#include <string>
#include "Magnum/GL/Mesh.h" #include "Magnum/GL/Mesh.h"
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
@ -35,7 +32,7 @@ namespace Magnum { namespace GL { namespace Implementation {
struct ContextState; struct ContextState;
struct MeshState { struct MeshState {
explicit MeshState(Context& context, ContextState& contextState, std::vector<std::string>& extensions); explicit MeshState(Context& context, ContextState& contextState, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
~MeshState(); ~MeshState();
void reset(); void reset();

14
src/Magnum/GL/Implementation/QueryState.cpp

@ -35,7 +35,7 @@ namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals; using namespace Containers::Literals;
QueryState::QueryState(Context& context, std::vector<std::string>& extensions) { QueryState::QueryState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions) {
/* Create implementation */ /* Create implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
@ -43,15 +43,21 @@ QueryState::QueryState(Context& context, std::vector<std::string>& extensions) {
if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && !context.isDriverWorkaroundDisabled("intel-windows-broken-dsa-indexed-queries"_s)) { if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && !context.isDriverWorkaroundDisabled("intel-windows-broken-dsa-indexed-queries"_s)) {
createImplementation = &AbstractQuery::createImplementationDefault; createImplementation = &AbstractQuery::createImplementationDefault;
} else if((context.detectedDriver() & Context::DetectedDriver::Amd) && !context.isDriverWorkaroundDisabled("amd-windows-dsa-createquery-except-xfb-overflow"_s)) { } else if((context.detectedDriver() & Context::DetectedDriver::Amd) && !context.isDriverWorkaroundDisabled("amd-windows-dsa-createquery-except-xfb-overflow"_s)) {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
createImplementation = &AbstractQuery::createImplementationDSAExceptXfbOverflow; createImplementation = &AbstractQuery::createImplementationDSAExceptXfbOverflow;
} else } else
#endif #endif
if((context.detectedDriver() & Context::DetectedDriver::Mesa) && !context.isDriverWorkaroundDisabled("mesa-dsa-createquery-except-pipeline-stats"_s)) { if((context.detectedDriver() & Context::DetectedDriver::Mesa) && !context.isDriverWorkaroundDisabled("mesa-dsa-createquery-except-pipeline-stats"_s)) {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
createImplementation = &AbstractQuery::createImplementationDSAExceptPipelineStats; createImplementation = &AbstractQuery::createImplementationDSAExceptPipelineStats;
} else { } else {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
createImplementation = &AbstractQuery::createImplementationDSA; createImplementation = &AbstractQuery::createImplementationDSA;
} }
} else } else

6
src/Magnum/GL/Implementation/QueryState.h

@ -25,9 +25,7 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string> #include "Magnum/Magnum.h"
#include <vector>
#include "Magnum/GL/GL.h" #include "Magnum/GL/GL.h"
#ifdef _MSC_VER #ifdef _MSC_VER
@ -40,7 +38,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
struct QueryState { struct QueryState {
explicit QueryState(Context& context, std::vector<std::string>& extensions); explicit QueryState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
void reset(); void reset();

21
src/Magnum/GL/Implementation/RendererState.cpp

@ -35,7 +35,7 @@ namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals; using namespace Containers::Literals;
RendererState::RendererState(Context& context, ContextState& contextState, std::vector<std::string>& extensions) RendererState::RendererState(Context& context, ContextState& contextState, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions)
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
: resetNotificationStrategy() : resetNotificationStrategy()
#endif #endif
@ -46,7 +46,8 @@ RendererState::RendererState(Context& context, ContextState& contextState, std::
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::ARB::ES2_compatibility::string()); extensions[Extensions::ARB::ES2_compatibility::Index] =
Extensions::ARB::ES2_compatibility::string();
#endif #endif
clearDepthfImplementation = &Renderer::clearDepthfImplementationES; clearDepthfImplementation = &Renderer::clearDepthfImplementationES;
@ -64,9 +65,11 @@ RendererState::RendererState(Context& context, ContextState& contextState, std::
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::ARB::robustness::string()); extensions[Extensions::ARB::robustness::Index] =
Extensions::ARB::robustness::string();
#else #else
extensions.push_back(Extensions::EXT::robustness::string()); extensions[Extensions::EXT::robustness::Index] =
Extensions::EXT::robustness::string();
#endif #endif
graphicsResetStatusImplementation = &Renderer::graphicsResetStatusImplementationRobustness; graphicsResetStatusImplementation = &Renderer::graphicsResetStatusImplementationRobustness;
@ -103,12 +106,16 @@ RendererState::RendererState(Context& context, ContextState& contextState, std::
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
minSampleShadingImplementation = &Renderer::minSampleShadingImplementationDefault; minSampleShadingImplementation = &Renderer::minSampleShadingImplementationDefault;
#elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isVersionSupported(Version::GLES320)) if(context.isVersionSupported(Version::GLES320)) {
minSampleShadingImplementation = &Renderer::minSampleShadingImplementationDefault; minSampleShadingImplementation = &Renderer::minSampleShadingImplementationDefault;
else if(context.isExtensionSupported<Extensions::OES::sample_shading>()) } else if(context.isExtensionSupported<Extensions::OES::sample_shading>()) {
extensions[Extensions::OES::sample_shading::Index] =
Extensions::OES::sample_shading::string();
minSampleShadingImplementation = &Renderer::minSampleShadingImplementationOES; minSampleShadingImplementation = &Renderer::minSampleShadingImplementationOES;
else } else {
minSampleShadingImplementation = nullptr; minSampleShadingImplementation = nullptr;
}
#endif #endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)

5
src/Magnum/GL/Implementation/RendererState.h

@ -25,9 +25,6 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string>
#include <vector>
#include "Magnum/GL/Renderer.h" #include "Magnum/GL/Renderer.h"
#include "Magnum/Math/Range.h" #include "Magnum/Math/Range.h"
@ -36,7 +33,7 @@ namespace Magnum { namespace GL { namespace Implementation {
struct ContextState; struct ContextState;
struct RendererState { struct RendererState {
explicit RendererState(Context& context, ContextState& contextState, std::vector<std::string>& extensions); explicit RendererState(Context& context, ContextState& contextState, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
Range1D(*lineWidthRangeImplementation)(); Range1D(*lineWidthRangeImplementation)();
void(*clearDepthfImplementation)(GLfloat); void(*clearDepthfImplementation)(GLfloat);

8
src/Magnum/GL/Implementation/ShaderProgramState.cpp

@ -37,7 +37,7 @@ namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals; using namespace Containers::Literals;
ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string>& extensions): current(0), maxVertexAttributes(0) ShaderProgramState::ShaderProgramState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions): current(0), maxVertexAttributes(0)
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
, maxGeometryOutputVertices{0}, maxAtomicCounterBufferSize(0), maxComputeSharedMemorySize(0), maxComputeWorkGroupInvocations(0), maxImageUnits(0), maxCombinedShaderOutputResources(0), maxUniformLocations(0) , maxGeometryOutputVertices{0}, maxAtomicCounterBufferSize(0), maxComputeSharedMemorySize(0), maxComputeWorkGroupInvocations(0), maxImageUnits(0), maxCombinedShaderOutputResources(0), maxUniformLocations(0)
@ -86,7 +86,8 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::ARB::separate_shader_objects::string()); extensions[Extensions::ARB::separate_shader_objects::Index] =
Extensions::ARB::separate_shader_objects::string();
#endif #endif
uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationSSO; uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
@ -133,7 +134,8 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL) #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isExtensionSupported<Extensions::EXT::separate_shader_objects>()) { if(context.isExtensionSupported<Extensions::EXT::separate_shader_objects>()) {
extensions.push_back(Extensions::EXT::separate_shader_objects::string()); extensions[Extensions::EXT::separate_shader_objects::Index] =
Extensions::EXT::separate_shader_objects::string();
uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationSSOEXT; uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationSSOEXT;
uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationSSOEXT; uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationSSOEXT;

6
src/Magnum/GL/Implementation/ShaderProgramState.h

@ -25,9 +25,9 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string> #include <Corrade/Utility/StlForwardString.h>
#include <vector>
#include "Magnum/Magnum.h"
#include "Magnum/GL/GL.h" #include "Magnum/GL/GL.h"
#include "Magnum/GL/OpenGL.h" #include "Magnum/GL/OpenGL.h"
#include "Magnum/Math/Vector3.h" #include "Magnum/Math/Vector3.h"
@ -39,7 +39,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
struct ShaderProgramState { struct ShaderProgramState {
explicit ShaderProgramState(Context& context, std::vector<std::string>& extensions); explicit ShaderProgramState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
void reset(); void reset();

2
src/Magnum/GL/Implementation/ShaderState.cpp

@ -36,7 +36,7 @@ namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals; using namespace Containers::Literals;
ShaderState::ShaderState(Context& context, std::vector<std::string>&): ShaderState::ShaderState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*>):
maxVertexOutputComponents{}, maxFragmentInputComponents{}, maxVertexOutputComponents{}, maxFragmentInputComponents{},
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{}, maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{}, maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{}, maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{}, maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{}, maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{},

6
src/Magnum/GL/Implementation/ShaderState.h

@ -25,9 +25,9 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string> #include <Corrade/Utility/StlForwardString.h>
#include <vector>
#include "Magnum/Magnum.h"
#include "Magnum/GL/GL.h" #include "Magnum/GL/GL.h"
#include "Magnum/GL/OpenGL.h" #include "Magnum/GL/OpenGL.h"
@ -41,7 +41,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
struct ShaderState { struct ShaderState {
explicit ShaderState(Context& context, std::vector<std::string>& extensions); explicit ShaderState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
enum: std::size_t { enum: std::size_t {
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)

24
src/Magnum/GL/Implementation/State.cpp

@ -25,9 +25,6 @@
#include "State.h" #include "State.h"
#include <algorithm>
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/GL/Context.h" #include "Magnum/GL/Context.h"
#include "Magnum/GL/Extensions.h" #include "Magnum/GL/Extensions.h"
#include "Magnum/GL/Implementation/BufferState.h" #include "Magnum/GL/Implementation/BufferState.h"
@ -49,14 +46,12 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
State::State(Context& context, std::ostream* const out) { State::State(Context& context, std::ostream* const out) {
/* List of extensions used in current context. Guesstimate count to avoid /* Extensions that might get used by current context. The State classes
unnecessary reallocations. */ will set strings based on Extension::index() and then we'll go through
std::vector<std::string> extensions; the list and print ones that aren't null. It's 1.5 kB of temporary data
#ifndef MAGNUM_TARGET_GLES but I think in terms of code size and overhead it's better than
extensions.reserve(32); populating a heap array and then std::sort() it to remove duplicates. */
#else const char* extensions[Implementation::ExtensionCount]{};
extensions.reserve(8);
#endif
buffer.reset(new BufferState{context, extensions}); buffer.reset(new BufferState{context, extensions});
this->context.reset(new ContextState{context, extensions}); this->context.reset(new ContextState{context, extensions});
@ -74,12 +69,9 @@ State::State(Context& context, std::ostream* const out) {
transformFeedback.reset(new TransformFeedbackState{context, extensions}); transformFeedback.reset(new TransformFeedbackState{context, extensions});
#endif #endif
/* Sort the features and remove duplicates */
std::sort(extensions.begin(), extensions.end());
extensions.erase(std::unique(extensions.begin(), extensions.end()), extensions.end());
Debug{out} << "Using optional features:"; Debug{out} << "Using optional features:";
for(const auto& ext: extensions) Debug(out) << " " << ext; for(const char* extension: extensions)
if(extension) Debug(out) << " " << extension;
} }
State::~State() = default; State::~State() = default;

47
src/Magnum/GL/Implementation/TextureState.cpp

@ -43,7 +43,7 @@ namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals; using namespace Containers::Literals;
TextureState::TextureState(Context& context, std::vector<std::string>& extensions): maxSize{}, TextureState::TextureState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions): maxSize{},
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
max3DSize{}, max3DSize{},
#endif #endif
@ -69,7 +69,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Create implementation */ /* Create implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
createImplementation = &AbstractTexture::createImplementationDSA; createImplementation = &AbstractTexture::createImplementationDSA;
} else } else
@ -114,7 +115,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Multi bind implementation */ /* Multi bind implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::multi_bind>()) { if(context.isExtensionSupported<Extensions::ARB::multi_bind>()) {
extensions.emplace_back(Extensions::ARB::multi_bind::string()); extensions[Extensions::ARB::multi_bind::Index] =
Extensions::ARB::multi_bind::string();
bindMultiImplementation = &AbstractTexture::bindImplementationMulti; bindMultiImplementation = &AbstractTexture::bindImplementationMulti;
@ -127,7 +129,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* DSA/non-DSA implementation */ /* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
parameteriImplementation = &AbstractTexture::parameterImplementationDSA; parameteriImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfImplementation = &AbstractTexture::parameterImplementationDSA; parameterfImplementation = &AbstractTexture::parameterImplementationDSA;
@ -244,7 +247,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Data invalidation implementation */ /* Data invalidation implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::invalidate_subdata>()) { if(context.isExtensionSupported<Extensions::ARB::invalidate_subdata>()) {
extensions.emplace_back(Extensions::ARB::invalidate_subdata::string()); extensions[Extensions::ARB::invalidate_subdata::Index] =
Extensions::ARB::invalidate_subdata::string();
invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationARB; invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationARB;
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationARB; invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationARB;
@ -281,7 +285,9 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationDSA; getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationDSA;
} else if(context.isExtensionSupported<Extensions::ARB::robustness>()) { } else if(context.isExtensionSupported<Extensions::ARB::robustness>()) {
extensions.emplace_back(Extensions::ARB::robustness::string()); extensions[Extensions::ARB::robustness::Index] =
Extensions::ARB::robustness::string();
getImageImplementation = &AbstractTexture::getImageImplementationRobustness; getImageImplementation = &AbstractTexture::getImageImplementationRobustness;
getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationRobustness; getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationRobustness;
@ -292,7 +298,9 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Image retrieval implementation for cube map */ /* Image retrieval implementation for cube map */
if(context.isExtensionSupported<Extensions::ARB::get_texture_sub_image>()) { if(context.isExtensionSupported<Extensions::ARB::get_texture_sub_image>()) {
extensions.emplace_back(Extensions::ARB::get_texture_sub_image::string()); extensions[Extensions::ARB::get_texture_sub_image::Index] =
Extensions::ARB::get_texture_sub_image::string();
getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSA; getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSA;
getCompressedCubeImageImplementation = &CubeMapTexture::getCompressedImageImplementationDSA; getCompressedCubeImageImplementation = &CubeMapTexture::getCompressedImageImplementationDSA;
@ -342,9 +350,11 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::ARB::texture_storage::string()); extensions[Extensions::ARB::texture_storage::Index] =
Extensions::ARB::texture_storage::string();
#elif defined(MAGNUM_TARGET_GLES2) #elif defined(MAGNUM_TARGET_GLES2)
extensions.push_back(Extensions::EXT::texture_storage::string()); extensions[Extensions::EXT::texture_storage::Index] =
Extensions::EXT::texture_storage::string();
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -387,7 +397,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Storage implementation for multisample textures. The fallback doesn't /* Storage implementation for multisample textures. The fallback doesn't
have DSA alternative, so it must be handled specially. */ have DSA alternative, so it must be handled specially. */
if(context.isExtensionSupported<Extensions::ARB::texture_storage_multisample>()) { if(context.isExtensionSupported<Extensions::ARB::texture_storage_multisample>()) {
extensions.emplace_back(Extensions::ARB::texture_storage_multisample::string()); extensions[Extensions::ARB::texture_storage_multisample::Index] =
Extensions::ARB::texture_storage_multisample::string();
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA; storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
@ -403,24 +414,30 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
#elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault; storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;
if(context.isVersionSupported(Version::GLES320)) if(context.isVersionSupported(Version::GLES320)) {
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault; storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;
else if(context.isExtensionSupported<Extensions::OES::texture_storage_multisample_2d_array>()) } else if(context.isExtensionSupported<Extensions::OES::texture_storage_multisample_2d_array>()) {
extensions[Extensions::OES::texture_storage_multisample_2d_array::Index] =
Extensions::OES::texture_storage_multisample_2d_array::string();
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationOES; storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationOES;
else } else {
storage3DMultisampleImplementation = nullptr; storage3DMultisampleImplementation = nullptr;
}
#endif #endif
/* Anisotropic filter implementation */ /* Anisotropic filter implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::EXT::texture_filter_anisotropic>()) { if(context.isExtensionSupported<Extensions::EXT::texture_filter_anisotropic>()) {
extensions.emplace_back(Extensions::ARB::texture_filter_anisotropic::string()); extensions[Extensions::ARB::texture_filter_anisotropic::Index] =
Extensions::ARB::texture_filter_anisotropic::string();
setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationArb; setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationArb;
} else } else
#endif #endif
if(context.isExtensionSupported<Extensions::EXT::texture_filter_anisotropic>()) { if(context.isExtensionSupported<Extensions::EXT::texture_filter_anisotropic>()) {
extensions.emplace_back(Extensions::EXT::texture_filter_anisotropic::string()); extensions[Extensions::EXT::texture_filter_anisotropic::Index] =
Extensions::EXT::texture_filter_anisotropic::string();
setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationExt; setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationExt;
} else setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationNoOp; } else setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationNoOp;

4
src/Magnum/GL/Implementation/TextureState.h

@ -25,8 +25,6 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string>
#include <vector>
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
#include <Corrade/Utility/StlForwardTuple.h> #include <Corrade/Utility/StlForwardTuple.h>
@ -53,7 +51,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
struct TextureState { struct TextureState {
explicit TextureState(Context& context, std::vector<std::string>& extensions); explicit TextureState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
~TextureState(); ~TextureState();
void reset(); void reset();

5
src/Magnum/GL/Implementation/TransformFeedbackState.cpp

@ -7,7 +7,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
TransformFeedbackState::TransformFeedbackState(Context& context, std::vector<std::string>& extensions): maxInterleavedComponents{0}, maxSeparateAttributes{0}, maxSeparateComponents{0}, TransformFeedbackState::TransformFeedbackState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions): maxInterleavedComponents{0}, maxSeparateAttributes{0}, maxSeparateComponents{0},
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
maxBuffers{0}, maxVertexStreams{0}, maxBuffers{0}, maxVertexStreams{0},
#endif #endif
@ -15,7 +15,8 @@ TransformFeedbackState::TransformFeedbackState(Context& context, std::vector<std
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) { if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()) {
extensions.emplace_back(Extensions::ARB::direct_state_access::string()); extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
createImplementation = &TransformFeedback::createImplementationDSA; createImplementation = &TransformFeedback::createImplementationDSA;
attachRangeImplementation = &TransformFeedback::attachImplementationDSA; attachRangeImplementation = &TransformFeedback::attachImplementationDSA;

7
src/Magnum/GL/Implementation/TransformFeedbackState.h

@ -25,9 +25,10 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include <string> #include <initializer_list>
#include <vector> #include <Corrade/Utility/StlForwardTuple.h>
#include "Magnum/Magnum.h"
#include "Magnum/GL/GL.h" #include "Magnum/GL/GL.h"
#include "Magnum/GL/OpenGL.h" #include "Magnum/GL/OpenGL.h"
@ -45,7 +46,7 @@
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
struct TransformFeedbackState { struct TransformFeedbackState {
explicit TransformFeedbackState(Context& context, std::vector<std::string>& extensions); explicit TransformFeedbackState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions);
void reset(); void reset();

Loading…
Cancel
Save