diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 5c238c729..7c7a60e83 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -15,12 +15,31 @@ #include "Buffer.h" +#include + +#include "Context.h" +#include "Extensions.h" + namespace Magnum { -void Buffer::copy(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { +Buffer::CopyImplementation Buffer::copyImplementation = &Buffer::copyImplementationDefault; + +void Buffer::initializeContextBasedFunctionality(Context* context) { + if(context->isExtensionSupported()) { + Debug() << "Buffer: using" << Extensions::GL::EXT::direct_state_access::string() << "features"; + + copyImplementation = &Buffer::copyImplementationDSA; + } +} + +void Buffer::copyImplementationDefault(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { read->bind(Target::CopyRead); write->bind(Target::CopyWrite); glCopyBufferSubData(static_cast(Target::CopyRead), static_cast(Target::CopyWrite), readOffset, writeOffset, size); } +void Buffer::copyImplementationDSA(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { + glNamedCopyBufferSubDataEXT(read->_id, write->_id, readOffset, writeOffset, size); +} + } diff --git a/src/Buffer.h b/src/Buffer.h index fb2f75da9..6d9b89ff9 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -29,6 +29,8 @@ namespace Magnum { +class Context; + /** @brief %Buffer @@ -61,6 +63,8 @@ buffer.setData(data, Buffer::Usage::StaticDraw); @todo Support for AMD's query buffer (@extension{AMD,query_buffer_object}) */ class MAGNUM_EXPORT Buffer { + friend class Context; + Buffer(const Buffer& other) = delete; Buffer(Buffer&& other) = delete; Buffer& operator=(const Buffer& other) = delete; @@ -246,13 +250,16 @@ class MAGNUM_EXPORT Buffer { * @param writeOffset Offset in the write buffer * @param size Data size * - * Read buffer is bound to `Target::CopyRead`, write buffer to - * `Target::CopyWrite` and the copy is performed. + * If @extension{EXT,direct_state_access} is not available, read + * buffer is bound to `Target::CopyRead` and write buffer to + * `Target::CopyWrite` before the copy is performed. * @requires_gl31 Extension @extension{ARB,copy_buffer} * @requires_gles30 (no extension providing this functionality) - * @see @fn_gl{CopyBufferSubData} + * @see @fn_gl{CopyBufferSubData} or @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access} */ - static void copy(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + inline static void copy(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { + copyImplementation(read, write, readOffset, writeOffset, size); + } /** * @brief Constructor @@ -480,6 +487,13 @@ class MAGNUM_EXPORT Buffer { } private: + static void initializeContextBasedFunctionality(Context* context); + + typedef void(*CopyImplementation)(Buffer*, Buffer*, GLintptr, GLintptr, GLsizeiptr); + static void MAGNUM_LOCAL copyImplementationDefault(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + static void MAGNUM_LOCAL copyImplementationDSA(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + static CopyImplementation copyImplementation; + GLuint _id; Target _defaultTarget; }; diff --git a/src/Context.cpp b/src/Context.cpp index 2410bcfef..3a46b7638 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -19,6 +19,7 @@ #include #include +#include "Buffer.h" #include "Extensions.h" using namespace std; @@ -191,6 +192,9 @@ Context::Context() { /* Set this context as current */ CORRADE_ASSERT(!_current, "Context: Another context currently active", ); _current = this; + + /* Initialize functionality based on current OpenGL version and extensions */ + Buffer::initializeContextBasedFunctionality(this); } Context::~Context() {