2 #include <msp/gl/extensions/arb_buffer_storage.h>
3 #include <msp/gl/extensions/arb_direct_state_access.h>
4 #include <msp/gl/extensions/arb_map_buffer_range.h>
5 #include <msp/gl/extensions/khr_debug.h>
6 #include <msp/strings/format.h>
8 #include "deviceinfo.h"
11 #include "vertexsetup.h"
22 static Require _req(ARB_vertex_buffer_object);
24 if(ARB_direct_state_access)
25 glCreateBuffers(1, &id);
32 glDeleteBuffers(1, &id);
35 void Buffer::storage(unsigned sz)
40 throw incompatible_data("Buffer::storage");
44 throw invalid_argument("Buffer::storage");
49 void Buffer::allocate()
52 throw invalid_operation("Buffer::allocate");
56 if(ARB_buffer_storage)
58 static const int flags = GL_MAP_READ_BIT|GL_MAP_WRITE_BIT|GL_DYNAMIC_STORAGE_BIT;
59 if(ARB_direct_state_access)
60 glNamedBufferStorage(id, size, 0, flags);
63 glBindBuffer(GL_ARRAY_BUFFER, id);
64 glBufferStorage(GL_ARRAY_BUFFER, size, 0, flags);
65 glBindBuffer(GL_ARRAY_BUFFER, 0);
74 void Buffer::set_usage(BufferUsage)
78 void Buffer::data(const void *d)
81 throw invalid_operation("Buffer::data");
83 if(ARB_buffer_storage)
84 return sub_data(0, size, d);
86 if(ARB_direct_state_access)
87 glNamedBufferData(id, size, d, STATIC_DRAW);
90 glBindBuffer(GL_ARRAY_BUFFER, id);
91 glBufferData(GL_ARRAY_BUFFER, size, d, STATIC_DRAW);
92 glBindBuffer(GL_ARRAY_BUFFER, 0);
98 void Buffer::data(unsigned sz, const void *d)
103 throw incompatible_data("Buffer::data");
108 void Buffer::sub_data(unsigned off, unsigned sz, const void *d)
111 throw invalid_operation("Buffer::sub_data");
115 if(ARB_direct_state_access)
116 glNamedBufferSubData(id, off, sz, d);
119 glBindBuffer(GL_ARRAY_BUFFER, id);
120 glBufferSubData(GL_ARRAY_BUFFER, off, sz, d);
121 glBindBuffer(GL_ARRAY_BUFFER, 0);
125 void Buffer::require_size(unsigned req_sz) const
128 throw buffer_too_small(format("buffer has %d bytes; %d required", size, req_sz));
133 static Require _req(ARB_map_buffer_range);
136 if(ARB_direct_state_access)
137 return glMapNamedBufferRange(id, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
140 glBindBuffer(GL_ARRAY_BUFFER, id);
141 void *result = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
142 glBindBuffer(GL_ARRAY_BUFFER, 0);
149 // TODO check if it's mapped
150 if(ARB_direct_state_access)
151 return glUnmapNamedBuffer(id);
152 else if(OES_mapbuffer)
154 glBindBuffer(GL_ARRAY_BUFFER, id);
155 bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
156 glBindBuffer(GL_ARRAY_BUFFER, 0);
163 void Buffer::set_debug_name(const string &name)
167 glObjectLabel(GL_BUFFER, id, name.size(), name.c_str());