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"
16 OpenGLBuffer::OpenGLBuffer()
18 static Require _req(ARB_vertex_buffer_object);
20 if(ARB_direct_state_access)
21 glCreateBuffers(1, &id);
26 OpenGLBuffer::OpenGLBuffer(OpenGLBuffer &&other):
32 OpenGLBuffer::~OpenGLBuffer()
34 if(this==Device::get_current().get_state().scratch_buffer)
37 glDeleteBuffers(1, &id);
40 void OpenGLBuffer::allocate()
42 size_t size = static_cast<const Buffer *>(this)->get_total_size();
44 if(ARB_buffer_storage)
46 static const int flags = GL_MAP_READ_BIT|GL_MAP_WRITE_BIT|GL_DYNAMIC_STORAGE_BIT;
47 if(ARB_direct_state_access)
48 glNamedBufferStorage(id, size, 0, flags);
52 glBufferStorage(GL_ARRAY_BUFFER, size, 0, flags);
55 else if(ARB_direct_state_access)
56 glNamedBufferData(id, size, 0, GL_STATIC_DRAW);
60 glBufferData(GL_ARRAY_BUFFER, size, 0, GL_STATIC_DRAW);
64 void OpenGLBuffer::sub_data(size_t off, size_t sz, const void *d)
66 if(ARB_direct_state_access)
67 glNamedBufferSubData(id, off, sz, d);
71 glBufferSubData(GL_ARRAY_BUFFER, off, sz, d);
75 void *OpenGLBuffer::map()
77 static Require _req(ARB_map_buffer_range);
79 size_t size = static_cast<const Buffer *>(this)->size;
81 if(ARB_direct_state_access)
82 return glMapNamedBufferRange(id, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
86 void *result = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
91 bool OpenGLBuffer::unmap()
93 if(ARB_direct_state_access)
94 return glUnmapNamedBuffer(id);
95 else if(OES_mapbuffer)
98 bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
105 void OpenGLBuffer::set_debug_name(const string &name)
109 glObjectLabel(GL_BUFFER, id, name.size(), name.c_str());
115 void OpenGLBuffer::bind_scratch()
117 const OpenGLBuffer *&scratch_binding = Device::get_current().get_state().scratch_buffer;
118 if(scratch_binding!=this)
120 glBindBuffer(GL_ARRAY_BUFFER, id);
121 scratch_binding = this;
125 void OpenGLBuffer::unbind_scratch()
127 const OpenGLBuffer *&scratch_binding = Device::get_current().get_state().scratch_buffer;
130 glBindBuffer(GL_ARRAY_BUFFER, 0);
136 void Buffer::AsyncTransfer::allocate()
138 dest_addr = buffer.map();
141 void Buffer::AsyncTransfer::finalize()