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()
29 if(this==scratch_binding)
31 glDeleteBuffers(1, &id);
34 void OpenGLBuffer::allocate()
36 size_t size = static_cast<const Buffer *>(this)->size;
38 if(ARB_buffer_storage)
40 static const int flags = GL_MAP_READ_BIT|GL_MAP_WRITE_BIT|GL_DYNAMIC_STORAGE_BIT;
41 if(ARB_direct_state_access)
42 glNamedBufferStorage(id, size, 0, flags);
46 glBufferStorage(GL_ARRAY_BUFFER, size, 0, flags);
49 else if(ARB_direct_state_access)
50 glNamedBufferData(id, size, 0, GL_STATIC_DRAW);
54 glBufferData(GL_ARRAY_BUFFER, size, 0, GL_STATIC_DRAW);
58 void OpenGLBuffer::sub_data(size_t off, size_t sz, const void *d)
60 if(ARB_direct_state_access)
61 glNamedBufferSubData(id, off, sz, d);
65 glBufferSubData(GL_ARRAY_BUFFER, off, sz, d);
69 void *OpenGLBuffer::map()
71 static Require _req(ARB_map_buffer_range);
73 size_t size = static_cast<const Buffer *>(this)->size;
75 if(ARB_direct_state_access)
76 return glMapNamedBufferRange(id, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
80 void *result = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
85 bool OpenGLBuffer::unmap()
87 // TODO check if it's mapped
88 if(ARB_direct_state_access)
89 return glUnmapNamedBuffer(id);
90 else if(OES_mapbuffer)
93 bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
100 void OpenGLBuffer::set_debug_name(const string &name)
104 glObjectLabel(GL_BUFFER, id, name.size(), name.c_str());
110 void OpenGLBuffer::bind_scratch()
112 if(scratch_binding!=this)
114 glBindBuffer(GL_ARRAY_BUFFER, id);
115 scratch_binding = this;
119 void OpenGLBuffer::unbind_scratch()
123 glBindBuffer(GL_ARRAY_BUFFER, 0);