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 {
struct ContextState;
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
*/
#include <cstddef>
#include "Magnum/Types.h"
#ifndef DOXYGEN_GENERATING_OUTPUT
@ -40,6 +42,20 @@ typedef unsigned int GLuint; /* Needed by Implementation/State.h */
namespace Magnum { namespace GL {
#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,
FramebufferTarget enums used only directly with framebuffer instance */
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 */
}
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_GLES
, minMapAlignment(0)
@ -99,7 +99,8 @@ BufferState::BufferState(Context& context, std::vector<std::string>& extensions)
context.isDriverWorkaroundDisabled("intel-windows-crazy-broken-buffer-dsa"_s))
#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;
copyImplementation = &Buffer::copyImplementationDSA;
@ -140,7 +141,8 @@ BufferState::BufferState(Context& context, std::vector<std::string>& extensions)
#ifndef MAGNUM_TARGET_GLES
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;
invalidateSubImplementation = &Buffer::invalidateSubImplementationARB;
@ -154,7 +156,8 @@ BufferState::BufferState(Context& context, std::vector<std::string>& extensions)
#ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES
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;
bindRangesImplementation = &Buffer::bindImplementationMulti;

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

@ -25,8 +25,6 @@
DEALINGS IN THE SOFTWARE.
*/
#include <vector>
#include "Magnum/GL/Buffer.h"
namespace Magnum { namespace GL { namespace Implementation {
@ -46,7 +44,7 @@ struct BufferState {
static std::size_t indexForTarget(Buffer::TargetHint target);
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();

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

@ -33,7 +33,7 @@ namespace Magnum { namespace GL { namespace Implementation {
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
if((context.detectedDriver() & Context::DetectedDriver::NVidia) &&
!context.isDriverWorkaroundDisabled("nv-zero-context-profile-mask"_s))

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

@ -25,9 +25,7 @@
DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include <vector>
#include "Magnum/Magnum.h"
#include "Magnum/GL/GL.h"
#ifdef _MSC_VER
@ -40,7 +38,7 @@
namespace Magnum { namespace GL { namespace Implementation {
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
enum class CoreProfile {

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

@ -31,7 +31,7 @@
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},
maxLoggedMessages{0},
maxMessageLength{0},
@ -45,7 +45,8 @@ DebugState::DebugState(Context& context, std::vector<std::string>& extensions):
#endif
{
#ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::KHR::debug::string());
extensions[Extensions::KHR::debug::Index] =
Extensions::KHR::debug::string();
#endif
getLabelImplementation = &AbstractObject::getLabelImplementationKhrDesktopES32;
@ -60,7 +61,8 @@ DebugState::DebugState(Context& context, std::vector<std::string>& extensions):
#endif
#ifdef MAGNUM_TARGET_GLES
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;
labelImplementation = &AbstractObject::labelImplementationKhrES;
@ -74,7 +76,8 @@ DebugState::DebugState(Context& context, std::vector<std::string>& extensions):
#endif
{
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;
labelImplementation = &AbstractObject::labelImplementationExt;
@ -84,14 +87,16 @@ DebugState::DebugState(Context& context, std::vector<std::string>& extensions):
}
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;
popGroupImplementation = &DebugGroup::popImplementationExt;
messageInsertImplementation = &DebugMessage::insertImplementationExt;
#ifndef MAGNUM_TARGET_GLES
} 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;
popGroupImplementation = &DebugGroup::popImplementationNoOp;

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

@ -25,9 +25,6 @@
DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include <vector>
#include "Magnum/GL/DebugOutput.h"
#include "Magnum/GL/GL.h"
@ -38,7 +35,7 @@
namespace Magnum { namespace GL { namespace Implementation {
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);
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;
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))
maxSamples{0},
#endif
@ -51,7 +51,9 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Create implementation */
#ifndef MAGNUM_TARGET_GLES
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;
createRenderbufferImplementation = &Renderbuffer::createImplementationDSA;
@ -65,7 +67,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES
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;
@ -143,7 +146,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
} else
#endif
{
/* Extension name added above */
extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
copySubCubeMapImplementation = &AbstractFramebuffer::copySubCubeMapImplementationDSA;
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))
#endif
) {
/* Extension name added above */
extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
layeredTextureCubeMapArrayImplementation = &Framebuffer::textureImplementationDSA;
} else
@ -203,12 +208,16 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Framebuffer texture attachment on ES3 */
#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;
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;
else
} else {
textureImplementation = nullptr;
}
#endif
#ifdef MAGNUM_TARGET_GLES2
@ -221,20 +230,24 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
checkStatusImplementation = &Framebuffer::checkStatusImplementationDefault;
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>()) {
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>()) {
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
enums. However, on my system only NV_framebuffer_multisample is
supported, but NV_framebuffer_blit isn't. I will hold my breath and
assume these enums are available. */
} 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 */
} else {
@ -249,17 +262,21 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
#ifndef MAGNUM_TARGET_WEBGL
/* Framebuffer draw mapping on ES2 */
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;
} 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;
} else drawBuffersImplementation = nullptr;
#else
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 */
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationEXT;
} else drawBuffersImplementation = nullptr;
@ -296,7 +313,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
if(context.isExtensionSupported<Extensions::ARB::direct_state_access>()
&& !((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))
implementationColorReadFormatTypeImplementation = &AbstractFramebuffer::implementationColorReadFormatTypeImplementationFramebufferDSAMesa;
@ -319,9 +337,11 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
#endif
{
#ifndef MAGNUM_TARGET_GLES
extensions.emplace_back(Extensions::ARB::robustness::string());
extensions[Extensions::ARB::robustness::Index] =
Extensions::ARB::robustness::string();
#else
extensions.push_back(Extensions::EXT::robustness::string());
extensions[Extensions::EXT::robustness::Index] =
Extensions::EXT::robustness::string();
#endif
readImplementation = &AbstractFramebuffer::readImplementationRobustness;
@ -335,7 +355,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Multisample renderbuffer storage implementation */
#ifndef MAGNUM_TARGET_GLES
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;
@ -344,11 +365,13 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
{
#if defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
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;
} 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;
} else renderbufferStorageMultisampleImplementation = nullptr;
@ -360,7 +383,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Framebuffer invalidation implementation on desktop GL */
#ifndef MAGNUM_TARGET_GLES
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>()) {
/* Extension added above */
@ -379,7 +403,8 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Framebuffer invalidation implementation on ES2 */
#elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
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;
} else {
@ -395,7 +420,9 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Blit implementation on desktop GL */
#ifndef MAGNUM_TARGET_GLES
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;
} else blitImplementation = &AbstractFramebuffer::blitImplementationDefault;
@ -403,11 +430,15 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Blit implementation on ES2 */
#elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
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;
} 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;
} else blitImplementation = nullptr;

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

@ -25,9 +25,6 @@
DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include <vector>
#include "Magnum/GL/Framebuffer.h"
#ifdef _MSC_VER
@ -42,7 +39,7 @@ namespace Magnum { namespace GL { namespace Implementation {
struct FramebufferState {
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();

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

@ -37,7 +37,7 @@ namespace Magnum { namespace GL { namespace Implementation {
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
, maxElementIndex{0}, maxElementsIndices{0}, maxElementsVertices{0}
#endif
@ -52,9 +52,11 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#endif
{
#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)
extensions.push_back(Extensions::OES::vertex_array_object::string());
extensions[Extensions::OES::vertex_array_object::Index] =
Extensions::OES::vertex_array_object::string();
#endif
#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))
#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 */
#ifdef CORRADE_TARGET_WINDOWS
@ -122,7 +125,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
} else
#endif
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;
#ifndef MAGNUM_TARGET_GLES2
@ -130,7 +134,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
drawElementsInstancedBaseVertexImplementation = glDrawElementsInstancedBaseVertexEXT;
#endif
} 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;
#ifndef MAGNUM_TARGET_GLES2
@ -140,7 +145,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
} else
#else
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
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_GLES2
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;
/* This variant isn't in the ext, emulated using
@ -182,7 +189,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#endif
#else
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
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
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;
multiDrawElementsImplementation = glMultiDrawElementsEXT;
} 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;
multiDrawElementsImplementation = glMultiDrawElementsANGLE;
} else CORRADE_INTERNAL_ASSERT_UNREACHABLE();
#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
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))
#ifndef MAGNUM_TARGET_WEBGL
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;
} 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
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
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
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
/* Instanced draw ímplementation on ES2 */
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;
drawElementsInstancedImplementation = glDrawElementsInstancedANGLE;
@ -303,18 +318,22 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#ifndef MAGNUM_TARGET_WEBGL
else if(context.isExtensionSupported<Extensions::EXT::instanced_arrays>() ||
context.isExtensionSupported<Extensions::EXT::draw_instanced>()) {
extensions.push_back(context.isExtensionSupported<Extensions::EXT::instanced_arrays>() ?
Extensions::EXT::instanced_arrays::string() :
Extensions::EXT::draw_instanced::string());
if(context.isExtensionSupported<Extensions::EXT::instanced_arrays>())
extensions[Extensions::EXT::instanced_arrays::Index] =
Extensions::EXT::instanced_arrays::string();
else extensions[Extensions::EXT::draw_instanced::Index] =
Extensions::EXT::draw_instanced::string();
drawArraysInstancedImplementation = glDrawArraysInstancedEXT;
drawElementsInstancedImplementation = glDrawElementsInstancedEXT;
} else if(context.isExtensionSupported<Extensions::NV::instanced_arrays>() ||
context.isExtensionSupported<Extensions::NV::draw_instanced>()) {
extensions.push_back(context.isExtensionSupported<Extensions::NV::instanced_arrays>() ?
Extensions::NV::instanced_arrays::string() :
Extensions::NV::draw_instanced::string());
if(context.isExtensionSupported<Extensions::NV::instanced_arrays>())
extensions[Extensions::NV::instanced_arrays::Index] =
Extensions::NV::instanced_arrays::string();
else extensions[Extensions::NV::draw_instanced::Index] =
Extensions::NV::draw_instanced::string();
drawArraysInstancedImplementation = glDrawArraysInstancedNV;
drawElementsInstancedImplementation = glDrawElementsInstancedNV;
@ -332,27 +351,37 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
&& (!(context.detectedDriver() & Context::DetectedDriver::IntelWindows) ||
context.isDriverWorkaroundDisabled("intel-windows-crazy-broken-vao-dsa"_s))
#endif
)
) {
extensions[Extensions::ARB::direct_state_access::Index] =
Extensions::ARB::direct_state_access::string();
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;
else
} else {
vertexAttribDivisorImplementation = nullptr;
}
#elif defined(MAGNUM_TARGET_GLES2)
/* Instanced arrays implementation on ES2 */
if(context.isExtensionSupported<Extensions::ANGLE::instanced_arrays>()) {
/* Extension added above */
extensions[Extensions::ANGLE::instanced_arrays::Index] =
Extensions::ANGLE::instanced_arrays::string();
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationANGLE;
}
#ifndef MAGNUM_TARGET_WEBGL
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;
} 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;
}

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

@ -25,9 +25,6 @@
DEALINGS IN THE SOFTWARE.
*/
#include <vector>
#include <string>
#include "Magnum/GL/Mesh.h"
namespace Magnum { namespace GL { namespace Implementation {
@ -35,7 +32,7 @@ namespace Magnum { namespace GL { namespace Implementation {
struct ContextState;
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();
void reset();

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

@ -35,7 +35,7 @@ namespace Magnum { namespace GL { namespace Implementation {
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 */
#ifndef MAGNUM_TARGET_GLES
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)) {
createImplementation = &AbstractQuery::createImplementationDefault;
} 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;
} else
#endif
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;
} 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;
}
} else

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

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

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

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

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

@ -25,9 +25,6 @@
DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include <vector>
#include "Magnum/GL/Renderer.h"
#include "Magnum/Math/Range.h"
@ -36,7 +33,7 @@ namespace Magnum { namespace GL { namespace Implementation {
struct ContextState;
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)();
void(*clearDepthfImplementation)(GLfloat);

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

@ -37,7 +37,7 @@ namespace Magnum { namespace GL { namespace Implementation {
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_WEBGL
, 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
{
#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
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(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;
uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationSSOEXT;

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

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

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

@ -36,7 +36,7 @@ namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals;
ShaderState::ShaderState(Context& context, std::vector<std::string>&):
ShaderState::ShaderState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*>):
maxVertexOutputComponents{}, maxFragmentInputComponents{},
#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{},

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

@ -25,9 +25,9 @@
DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include <vector>
#include <Corrade/Utility/StlForwardString.h>
#include "Magnum/Magnum.h"
#include "Magnum/GL/GL.h"
#include "Magnum/GL/OpenGL.h"
@ -41,7 +41,7 @@
namespace Magnum { namespace GL { namespace Implementation {
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 {
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)

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

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

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

@ -43,7 +43,7 @@ namespace Magnum { namespace GL { namespace Implementation {
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))
max3DSize{},
#endif
@ -69,7 +69,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Create implementation */
#ifndef MAGNUM_TARGET_GLES
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;
} else
@ -114,7 +115,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Multi bind implementation */
#ifndef MAGNUM_TARGET_GLES
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;
@ -127,7 +129,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES
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;
parameterfImplementation = &AbstractTexture::parameterImplementationDSA;
@ -244,7 +247,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Data invalidation implementation */
#ifndef MAGNUM_TARGET_GLES
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;
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationARB;
@ -281,7 +285,9 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationDSA;
} 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;
getCompressedImageImplementation = &AbstractTexture::getCompressedImageImplementationRobustness;
@ -292,7 +298,9 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
/* Image retrieval implementation for cube map */
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;
getCompressedCubeImageImplementation = &CubeMapTexture::getCompressedImageImplementationDSA;
@ -342,9 +350,11 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
#endif
{
#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)
extensions.push_back(Extensions::EXT::texture_storage::string());
extensions[Extensions::EXT::texture_storage::Index] =
Extensions::EXT::texture_storage::string();
#endif
#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
have DSA alternative, so it must be handled specially. */
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>()) {
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)
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;
if(context.isVersionSupported(Version::GLES320))
if(context.isVersionSupported(Version::GLES320)) {
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;
else
} else {
storage3DMultisampleImplementation = nullptr;
}
#endif
/* Anisotropic filter implementation */
#ifndef MAGNUM_TARGET_GLES
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;
} else
#endif
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;
} else setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationNoOp;

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

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

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

@ -7,7 +7,7 @@
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
maxBuffers{0}, maxVertexStreams{0},
#endif
@ -15,7 +15,8 @@ TransformFeedbackState::TransformFeedbackState(Context& context, std::vector<std
{
#ifndef MAGNUM_TARGET_GLES
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;
attachRangeImplementation = &TransformFeedback::attachImplementationDSA;

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

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

Loading…
Cancel
Save