1 #include <msp/gl/extensions/arb_buffer_storage.h>
2 #include <msp/gl/extensions/arb_direct_state_access.h>
3 #include <msp/gl/extensions/arb_map_buffer_range.h>
4 #include <msp/gl/extensions/arb_vertex_buffer_object.h>
5 #include <msp/gl/extensions/khr_debug.h>
6 #include <msp/gl/extensions/oes_mapbuffer.h>
8 #include "buffer_backend.h"
15 OpenGLBuffer *OpenGLBuffer::scratch_binding = 0;
17 OpenGLBuffer::OpenGLBuffer()
19 static Require _req(ARB_vertex_buffer_object);
21 if(ARB_direct_state_access)
22 glCreateBuffers(1, &id);
27 OpenGLBuffer::OpenGLBuffer(OpenGLBuffer &&other):
33 OpenGLBuffer::~OpenGLBuffer()
35 if(this==scratch_binding)
38 glDeleteBuffers(1, &id);
41 void OpenGLBuffer::allocate()
43 size_t size = static_cast<const Buffer *>(this)->size;
45 if(ARB_buffer_storage)
47 static const int flags = GL_MAP_READ_BIT|GL_MAP_WRITE_BIT|GL_DYNAMIC_STORAGE_BIT;
48 if(ARB_direct_state_access)
49 glNamedBufferStorage(id, size, 0, flags);
53 glBufferStorage(GL_ARRAY_BUFFER, size, 0, flags);
56 else if(ARB_direct_state_access)
57 glNamedBufferData(id, size, 0, GL_STATIC_DRAW);
61 glBufferData(GL_ARRAY_BUFFER, size, 0, GL_STATIC_DRAW);
65 void OpenGLBuffer::sub_data(size_t off, size_t sz, const void *d)
67 if(ARB_direct_state_access)
68 glNamedBufferSubData(id, off, sz, d);
72 glBufferSubData(GL_ARRAY_BUFFER, off, sz, d);
76 void *OpenGLBuffer::map()
78 static Require _req(ARB_map_buffer_range);
80 size_t size = static_cast<const Buffer *>(this)->size;
82 if(ARB_direct_state_access)
83 return glMapNamedBufferRange(id, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
87 void *result = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
92 bool OpenGLBuffer::unmap()
94 // TODO check if it's mapped
95 if(ARB_direct_state_access)
96 return glUnmapNamedBuffer(id);
97 else if(OES_mapbuffer)
100 bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
107 void OpenGLBuffer::set_debug_name(const string &name)
111 glObjectLabel(GL_BUFFER, id, name.size(), name.c_str());
117 void OpenGLBuffer::bind_scratch()
119 if(scratch_binding!=this)
121 glBindBuffer(GL_ARRAY_BUFFER, id);
122 scratch_binding = this;
126 void OpenGLBuffer::unbind_scratch()
130 glBindBuffer(GL_ARRAY_BUFFER, 0);