diff --git a/doc/changelog.dox b/doc/changelog.dox index 0103d1d1f..e461dc07e 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -124,6 +124,12 @@ See also: - @ref DebugTools::textureSubImage() for float textures was updated to work with SwiftShader (which has broken @glsl gl_VertexID @ce) +@subsubsection changelog-latest-changes-gl GL library + +- Reworked @ref GL::Mesh internals to make use of + @gl_extension{ARB,direct_state_access} instead of being the last code path + stuck on @gl_extension{EXT,direct_state_access} + @subsubsection changelog-latest-changes-math Math library - @ref Math::BoolVector now implements component-wise @cpp && @ce, diff --git a/src/Magnum/GL/Implementation/MeshState.cpp b/src/Magnum/GL/Implementation/MeshState.cpp index a96df4466..d96587622 100644 --- a/src/Magnum/GL/Implementation/MeshState.cpp +++ b/src/Magnum/GL/Implementation/MeshState.cpp @@ -53,24 +53,31 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector()) { + if(context.isExtensionSupported()) { + extensions.emplace_back(Extensions::ARB::direct_state_access::string()); + + createImplementation = &Mesh::createImplementationVAODSA; + attributePointerImplementation = &Mesh::attributePointerImplementationVAODSA; + bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationVAODSA; + } else if(context.isExtensionSupported()) { extensions.emplace_back(Extensions::EXT::direct_state_access::string()); - attributePointerImplementation = &Mesh::attributePointerImplementationDSAEXT; + createImplementation = &Mesh::createImplementationVAO; + attributePointerImplementation = &Mesh::attributePointerImplementationVAODSAEXT; + bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationVAO; } else #endif { + createImplementation = &Mesh::createImplementationVAO; attributePointerImplementation = &Mesh::attributePointerImplementationVAO; + bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationVAO; } + moveConstructImplementation = &Mesh::moveConstructImplementationVAO; + moveAssignImplementation = &Mesh::moveAssignImplementationVAO; + destroyImplementation = &Mesh::destroyImplementationVAO; acquireVertexBufferImplementation = &Mesh::acquireVertexBufferImplementationVAO; - bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationVAO; bindVAOImplementation = &Mesh::bindVAOImplementationVAO; bindImplementation = &Mesh::bindImplementationVAO; unbindImplementation = &Mesh::unbindImplementationVAO; @@ -90,14 +97,6 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector() && context.isExtensionSupported()) { - extensions.emplace_back(Extensions::ARB::direct_state_access::string()); - createImplementation = &Mesh::createImplementationVAODSA; - } - #endif - #ifdef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_WEBGL /* Multi draw implementation on ES */ @@ -147,9 +146,11 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector()) { + if(context.isExtensionSupported()) { + vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAODSA; + } else if(context.isExtensionSupported()) { if(glVertexArrayVertexAttribDivisorEXT) - vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationDSAEXT; + vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAODSAEXT; else vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAO; } else vertexAttribDivisorImplementation = nullptr; #elif defined(MAGNUM_TARGET_GLES2) diff --git a/src/Magnum/GL/Mesh.cpp b/src/Magnum/GL/Mesh.cpp index 4ddc5e235..7bf6a7e14 100644 --- a/src/Magnum/GL/Mesh.cpp +++ b/src/Magnum/GL/Mesh.cpp @@ -688,7 +688,33 @@ void Mesh::attributePointerImplementationVAO(AttributeLayout&& attribute) { } #ifndef MAGNUM_TARGET_GLES -void Mesh::attributePointerImplementationDSAEXT(AttributeLayout&& attribute) { +void Mesh::attributePointerImplementationVAODSA(AttributeLayout&& attribute) { + _flags |= ObjectFlag::Created; + glEnableVertexArrayAttrib(_id, attribute.location); + + + #ifndef MAGNUM_TARGET_GLES2 + if(attribute.kind == DynamicAttribute::Kind::Integral) + glVertexArrayAttribIFormat(_id, attribute.location, attribute.size, attribute.type, 0); + #ifndef MAGNUM_TARGET_GLES + else if(attribute.kind == DynamicAttribute::Kind::Long) + glVertexArrayAttribLFormat(_id, attribute.location, attribute.size, attribute.type, 0); + #endif + else + #endif + { + glVertexArrayAttribFormat(_id, attribute.location, attribute.size, attribute.type, attribute.kind == DynamicAttribute::Kind::GenericNormalized, 0); + } + + glVertexArrayAttribBinding(_id, attribute.location, attribute.location); + CORRADE_INTERNAL_ASSERT(attribute.stride != 0); + glVertexArrayVertexBuffer(_id, attribute.location, attribute.buffer.id(), attribute.offset, attribute.stride); + + if(attribute.divisor) + (this->*Context::current().state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); +} + +void Mesh::attributePointerImplementationVAODSAEXT(AttributeLayout&& attribute) { _flags |= ObjectFlag::Created; glEnableVertexArrayAttribEXT(_id, attribute.location); @@ -741,7 +767,10 @@ void Mesh::vertexAttribDivisorImplementationVAO(const GLuint index, const GLuint bindVAO(); glVertexAttribDivisor(index, divisor); } -void Mesh::vertexAttribDivisorImplementationDSAEXT(const GLuint index, const GLuint divisor) { +void Mesh::vertexAttribDivisorImplementationVAODSA(const GLuint index, const GLuint divisor) { + glVertexArrayBindingDivisor(_id, index, divisor); +} +void Mesh::vertexAttribDivisorImplementationVAODSAEXT(const GLuint index, const GLuint divisor) { glVertexArrayVertexAttribDivisorEXT(_id, index, divisor); } #elif defined(MAGNUM_TARGET_GLES2) @@ -787,6 +816,12 @@ void Mesh::bindIndexBufferImplementationVAO(Buffer& buffer) { buffer.bindInternal(Buffer::TargetHint::ElementArray); } +#ifndef MAGNUM_TARGET_GLES +void Mesh::bindIndexBufferImplementationVAODSA(Buffer& buffer) { + glVertexArrayElementBuffer(_id, buffer.id()); +} +#endif + void Mesh::bindImplementationDefault() { /* Specify vertex attributes */ for(AttributeLayout& attribute: *reinterpret_cast*>(&_attributes)) diff --git a/src/Magnum/GL/Mesh.h b/src/Magnum/GL/Mesh.h index d1b0c8c60..c096d247a 100644 --- a/src/Magnum/GL/Mesh.h +++ b/src/Magnum/GL/Mesh.h @@ -280,7 +280,7 @@ and @fn_gl_keyword{UseProgram}. Mesh limits and implementation-defined values (such as @ref maxElementIndex()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. -If @gl_extension{EXT,direct_state_access} desktop extension and VAOs are +If @gl_extension{ARB,direct_state_access} desktop extension and VAOs are available, DSA functions are used for specifying attribute locations to avoid unnecessary calls to @fn_gl{BindBuffer} and @fn_gl{BindVertexArray}. See documentation of @ref addVertexBuffer() for more information. @@ -699,8 +699,10 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * @ref setCount(), @fn_gl_keyword{BindVertexArray}, * @fn_gl_keyword{EnableVertexAttribArray}, @fn_gl{BindBuffer}, * @fn_gl_keyword{VertexAttribPointer} or - * @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access}, - * @fn_gl_extension_keyword{VertexArrayVertexAttribOffset,EXT,direct_state_access} + * @fn_gl2{EnableVertexArrayAttrib,EnableVertexAttribArray}, + * @fn_gl2{VertexArrayAttribFormat,VertexAttribFormat}, + * @fn_gl2{VertexArrayAttribBinding,VertexAttribBinding} and + * @fn_gl2{VertexArrayVertexBuffer,BindVertexBuffer} * @requires_gles In WebGL the data must be properly aligned (e.g. all * float data must start at addresses divisible by four). Also the * maximum stride of attribute data must be at most 255 bytes. @@ -731,9 +733,11 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * @fn_gl{BindVertexArray}, @fn_gl_keyword{EnableVertexAttribArray}, * @fn_gl{BindBuffer}, @fn_gl_keyword{VertexAttribPointer}, * @fn_gl_keyword{VertexAttribDivisor} or - * @fn_gl_extension_keyword{EnableVertexArrayAttrib,EXT,direct_state_access}, - * @fn_gl_extension_keyword{VertexArrayVertexAttribOffset,EXT,direct_state_access}, - * @fn_gl_extension_keyword{VertexArrayVertexAttribDivisor,EXT,direct_state_access} + * @fn_gl2{EnableVertexArrayAttrib,EnableVertexAttribArray}, + * @fn_gl2{VertexArrayAttribFormat,VertexAttribFormat}, + * @fn_gl2{VertexArrayAttribBinding,VertexAttribBinding}, + * @fn_gl2{VertexArrayVertexBuffer,BindVertexBuffer} and + * @fn_gl2{VertexArrayBindingDivisor,VertexBindingDivisor} * @requires_gl33 Extension @gl_extension{ARB,instanced_arrays} * @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays}, * @gl_extension{EXT,instanced_arrays} or @@ -1107,13 +1111,15 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { void MAGNUM_GL_LOCAL attributePointerImplementationDefault(AttributeLayout&& attribute); void MAGNUM_GL_LOCAL attributePointerImplementationVAO(AttributeLayout&& attribute); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_GL_LOCAL attributePointerImplementationDSAEXT(AttributeLayout&& attribute); + void MAGNUM_GL_LOCAL attributePointerImplementationVAODSA(AttributeLayout&& attribute); + void MAGNUM_GL_LOCAL attributePointerImplementationVAODSAEXT(AttributeLayout&& attribute); #endif void MAGNUM_GL_LOCAL vertexAttribPointer(AttributeLayout& attribute); #ifndef MAGNUM_TARGET_GLES void MAGNUM_GL_LOCAL vertexAttribDivisorImplementationVAO(GLuint index, GLuint divisor); - void MAGNUM_GL_LOCAL vertexAttribDivisorImplementationDSAEXT(GLuint index, GLuint divisor); + void MAGNUM_GL_LOCAL vertexAttribDivisorImplementationVAODSA(GLuint index, GLuint divisor); + void MAGNUM_GL_LOCAL vertexAttribDivisorImplementationVAODSAEXT(GLuint index, GLuint divisor); #elif defined(MAGNUM_TARGET_GLES2) void MAGNUM_GL_LOCAL vertexAttribDivisorImplementationANGLE(GLuint index, GLuint divisor); #ifndef MAGNUM_TARGET_WEBGL @@ -1128,6 +1134,9 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { void MAGNUM_GL_LOCAL bindIndexBufferImplementationDefault(Buffer&); void MAGNUM_GL_LOCAL bindIndexBufferImplementationVAO(Buffer& buffer); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_GL_LOCAL bindIndexBufferImplementationVAODSA(Buffer& buffer); + #endif void MAGNUM_GL_LOCAL bindImplementationDefault(); void MAGNUM_GL_LOCAL bindImplementationVAO();