From 8446186a4ee670dcf587084a4c2cb28eebb7fb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 25 Dec 2014 14:56:48 +0100 Subject: [PATCH] Account for missing glVertexArrayVertexAttribDivisorEXT. This function was added to ARB_instanced_arrays spec very late and thus some implementations don't provide it (one case being AMD drivers on Linux). If that function is not available, the non-DSA VAO specification is used instead. --- src/Magnum/Implementation/MeshState.cpp | 9 +++++++++ src/Magnum/Implementation/MeshState.h | 2 +- src/Magnum/Mesh.cpp | 21 +++++++++++++++------ src/Magnum/Mesh.h | 5 ++++- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/Magnum/Implementation/MeshState.cpp b/src/Magnum/Implementation/MeshState.cpp index e2e595c91..6e3a02ed2 100644 --- a/src/Magnum/Implementation/MeshState.cpp +++ b/src/Magnum/Implementation/MeshState.cpp @@ -137,7 +137,16 @@ MeshState::MeshState(Context& context, std::vector& extensions): cu drawArraysInstancedImplementation = nullptr; drawElementsInstancedImplementation = nullptr; } + #endif + #ifndef MAGNUM_TARGET_GLES + /* Partial EXT_DSA implementation of vertex attrib divisor */ + if(context.isExtensionSupported()) { + if(glVertexArrayVertexAttribDivisorEXT) + vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationDSAEXT; + else vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAO; + } else vertexAttribDivisorImplementation = nullptr; + #elif defined(MAGNUM_TARGET_GLES2) /* Instanced arrays implementation on ES2 */ if(context.isExtensionSupported()) { /* Extension added above */ diff --git a/src/Magnum/Implementation/MeshState.h b/src/Magnum/Implementation/MeshState.h index 95b0bbc6c..7f49f116d 100644 --- a/src/Magnum/Implementation/MeshState.h +++ b/src/Magnum/Implementation/MeshState.h @@ -46,7 +46,7 @@ struct MeshState { void(Mesh::*attributeLPointerImplementation)(const Mesh::LongAttribute&); #endif #endif - #ifdef MAGNUM_TARGET_GLES2 + #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2) void(Mesh::*vertexAttribDivisorImplementation)(GLuint, GLuint); #endif void(Mesh::*bindIndexBufferImplementation)(Buffer&); diff --git a/src/Magnum/Mesh.cpp b/src/Magnum/Mesh.cpp index fd5756dab..bc4fe8269 100644 --- a/src/Magnum/Mesh.cpp +++ b/src/Magnum/Mesh.cpp @@ -406,7 +406,8 @@ void Mesh::attributePointerImplementationDSAEXT(const GenericAttribute& attribut _created = true; glEnableVertexArrayAttribEXT(_id, attribute.location); glVertexArrayVertexAttribOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset); - if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); + if(attribute.divisor) + (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); } #endif @@ -442,7 +443,8 @@ void Mesh::attributePointerImplementationDSAEXT(const IntegerAttribute& attribut _created = true; glEnableVertexArrayAttribEXT(_id, attribute.location); glVertexArrayVertexAttribIOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); - if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); + if(attribute.divisor) + (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); } #endif @@ -472,7 +474,8 @@ void Mesh::attributePointerImplementationDSAEXT(const LongAttribute& attribute) _created = true; glEnableVertexArrayAttribEXT(_id, attribute.location); glVertexArrayVertexAttribLOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); - if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); + if(attribute.divisor) + (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); } void Mesh::vertexAttribPointer(const LongAttribute& attribute) { @@ -483,7 +486,15 @@ void Mesh::vertexAttribPointer(const LongAttribute& attribute) { } #endif -#ifdef MAGNUM_TARGET_GLES2 +#ifndef MAGNUM_TARGET_GLES +void Mesh::vertexAttribDivisorImplementationVAO(const GLuint index, const GLuint divisor) { + bindVAO(); + glVertexAttribDivisor(index, divisor); +} +void Mesh::vertexAttribDivisorImplementationDSAEXT(const GLuint index, const GLuint divisor) { + glVertexArrayVertexAttribDivisorEXT(_id, index, divisor); +} +#elif defined(MAGNUM_TARGET_GLES2) void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLuint divisor) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glVertexAttribDivisorANGLE(index, divisor); @@ -493,7 +504,6 @@ void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLui CORRADE_ASSERT_UNREACHABLE(); #endif } - void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint divisor) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glVertexAttribDivisorEXT(index, divisor); @@ -503,7 +513,6 @@ void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint CORRADE_ASSERT_UNREACHABLE(); #endif } - void Mesh::vertexAttribDivisorImplementationNV(const GLuint index, const GLuint divisor) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glVertexAttribDivisorNV(index, divisor); diff --git a/src/Magnum/Mesh.h b/src/Magnum/Mesh.h index 80816a651..77fa358cc 100644 --- a/src/Magnum/Mesh.h +++ b/src/Magnum/Mesh.h @@ -981,7 +981,10 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { void MAGNUM_LOCAL vertexAttribPointer(const LongAttribute& attribute); #endif - #ifdef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL vertexAttribDivisorImplementationVAO(GLuint index, GLuint divisor); + void MAGNUM_LOCAL vertexAttribDivisorImplementationDSAEXT(GLuint index, GLuint divisor); + #elif defined(MAGNUM_TARGET_GLES2) void MAGNUM_LOCAL vertexAttribDivisorImplementationANGLE(GLuint index, GLuint divisor); void MAGNUM_LOCAL vertexAttribDivisorImplementationEXT(GLuint index, GLuint divisor); void MAGNUM_LOCAL vertexAttribDivisorImplementationNV(GLuint index, GLuint divisor);