Browse Source

First extension-aware functionality - Buffer::copy().

If EXT_direct_state_access is supported, it uses faster alternative to
explicit binding.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
806828f173
  1. 21
      src/Buffer.cpp
  2. 22
      src/Buffer.h
  3. 4
      src/Context.cpp

21
src/Buffer.cpp

@ -15,12 +15,31 @@
#include "Buffer.h"
#include <Utility/Debug.h>
#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<Extensions::GL::EXT::direct_state_access>()) {
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<GLenum>(Target::CopyRead), static_cast<GLenum>(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);
}
}

22
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;
};

4
src/Context.cpp

@ -19,6 +19,7 @@
#include <unordered_map>
#include <Utility/Debug.h>
#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() {

Loading…
Cancel
Save