gsdx-ogl: found_GL_ARB_buffer_storage is now mandatory

This commit is contained in:
Gregory Hainaut 2016-04-07 22:17:22 +02:00
parent 52e3c3516d
commit a62019a3fd
5 changed files with 41 additions and 117 deletions

View File

@ -475,7 +475,7 @@ namespace GLLoader {
// GL4.3
status &= status_and_override(found_GL_ARB_copy_image, "GL_ARB_copy_image");
// GL4.4
status &= status_and_override(found_GL_ARB_buffer_storage,"GL_ARB_buffer_storage");
status &= status_and_override(found_GL_ARB_buffer_storage,"GL_ARB_buffer_storage", true);
status &= status_and_override(found_GL_ARB_clear_texture,"GL_ARB_clear_texture");
// GL4.5
status &= status_and_override(found_GL_ARB_clip_control, "GL_ARB_clip_control", true);

View File

@ -352,7 +352,6 @@ namespace GLLoader {
extern bool found_GL_ARB_gpu_shader5;
extern bool found_GL_ARB_shader_image_load_store;
extern bool found_GL_ARB_clear_texture;
extern bool found_GL_ARB_buffer_storage;
extern bool found_GL_ARB_direct_state_access;
extern bool found_GL_EXT_texture_filter_anisotropic;
}

View File

@ -40,7 +40,6 @@ namespace PboPool {
char* m_map[PBO_POOL_SIZE];
uint32 m_current_pbo = 0;
uint32 m_size;
bool m_texture_storage;
GLsync m_fence[PBO_POOL_SIZE];
const uint32 m_pbo_size = 8*1024*1024;
@ -62,19 +61,13 @@ namespace PboPool {
// will use DMA CACHED memory as the source for buffer object operations
void Init() {
glGenBuffers(countof(m_pool), m_pool);
m_texture_storage = GLLoader::found_GL_ARB_buffer_storage;
for (size_t i = 0; i < countof(m_pool); i++) {
BindPbo();
if (m_texture_storage) {
glBufferStorage(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, create_flags);
m_map[m_current_pbo] = (char*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, m_pbo_size, map_flags);
m_fence[m_current_pbo] = 0;
} else {
glBufferData(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, GL_STREAM_COPY);
m_map[m_current_pbo] = NULL;
}
glBufferStorage(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, create_flags);
m_map[m_current_pbo] = (char*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, m_pbo_size, map_flags);
m_fence[m_current_pbo] = 0;
NextPbo();
}
@ -89,44 +82,22 @@ namespace PboPool {
fprintf(stderr, "BUG: PBO too small %d but need %d\n", m_pbo_size, m_size);
}
if (m_texture_storage) {
if (m_offset[m_current_pbo] + m_size >= m_pbo_size) {
//NextPbo(); // For test purpose
NextPboWithSync();
}
// Note: texsubimage will access currently bound buffer
// Pbo ready let's get a pointer
BindPbo();
map = m_map[m_current_pbo] + m_offset[m_current_pbo];
} else {
GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
if (m_offset[m_current_pbo] + m_size >= m_pbo_size) {
NextPbo();
flags &= ~GL_MAP_INVALIDATE_RANGE_BIT;
flags |= GL_MAP_INVALIDATE_BUFFER_BIT;
}
// Pbo ready let's get a pointer
BindPbo();
// Be sure the map is aligned
map = (char*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset[m_current_pbo], m_size, flags);
if (m_offset[m_current_pbo] + m_size >= m_pbo_size) {
//NextPbo(); // For test purpose
NextPboWithSync();
}
// Note: texsubimage will access currently bound buffer
// Pbo ready let's get a pointer
BindPbo();
map = m_map[m_current_pbo] + m_offset[m_current_pbo];
return map;
}
void Unmap() {
if (m_texture_storage) {
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset[m_current_pbo], m_size);
} else {
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset[m_current_pbo], m_size);
}
uptr Offset() {
@ -134,18 +105,16 @@ namespace PboPool {
}
void Destroy() {
if (m_texture_storage) {
for (size_t i = 0; i < countof(m_pool); i++) {
m_map[i] = NULL;
m_offset[i] = 0;
glDeleteSync(m_fence[i]);
for (size_t i = 0; i < countof(m_pool); i++) {
m_map[i] = NULL;
m_offset[i] = 0;
glDeleteSync(m_fence[i]);
// Don't know if we must do it
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pool[i]);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
// Don't know if we must do it
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pool[i]);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glDeleteBuffers(countof(m_pool), m_pool);
}

View File

@ -43,7 +43,6 @@ class GSBufferOGL {
const GLenum m_target;
GLuint m_buffer_name;
uint8* m_buffer_ptr;
const bool m_buffer_storage;
GLsync m_fence[5];
public:
@ -52,7 +51,6 @@ class GSBufferOGL {
, m_count(0)
, m_limit(0)
, m_target(target)
, m_buffer_storage(GLLoader::found_GL_ARB_buffer_storage)
{
glGenBuffers(1, &m_buffer_name);
// Opengl works best with 1-4MB buffer.
@ -63,73 +61,37 @@ class GSBufferOGL {
m_fence[i] = 0;
}
if (m_buffer_storage) {
// TODO: if we do manually the synchronization, I'm not sure size is important. It worths to investigate it.
// => bigger buffer => less sync
bind();
// coherency will be done by flushing
const GLbitfield common_flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT;
const GLbitfield map_flags = common_flags | GL_MAP_FLUSH_EXPLICIT_BIT;
const GLbitfield create_flags = common_flags | GL_CLIENT_STORAGE_BIT;
// TODO: if we do manually the synchronization, I'm not sure size is important. It worths to investigate it.
// => bigger buffer => less sync
bind();
// coherency will be done by flushing
const GLbitfield common_flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT;
const GLbitfield map_flags = common_flags | GL_MAP_FLUSH_EXPLICIT_BIT;
const GLbitfield create_flags = common_flags | GL_CLIENT_STORAGE_BIT;
glBufferStorage(m_target, STRIDE * m_limit, NULL, create_flags );
m_buffer_ptr = (uint8*) glMapBufferRange(m_target, 0, STRIDE * m_limit, map_flags);
if (!m_buffer_ptr) {
fprintf(stderr, "Failed to map buffer\n");
throw GSDXError();
}
} else {
m_buffer_ptr = NULL;
glBufferStorage(m_target, STRIDE * m_limit, NULL, create_flags );
m_buffer_ptr = (uint8*) glMapBufferRange(m_target, 0, STRIDE * m_limit, map_flags);
if (!m_buffer_ptr) {
fprintf(stderr, "Failed to map buffer\n");
throw GSDXError();
}
}
~GSBufferOGL() {
if (m_buffer_storage) {
for (size_t i = 0; i < 5; i++) {
glDeleteSync(m_fence[i]);
}
// Don't know if we must do it
bind();
glUnmapBuffer(m_target);
for (size_t i = 0; i < 5; i++) {
glDeleteSync(m_fence[i]);
}
// Don't know if we must do it
bind();
glUnmapBuffer(m_target);
glDeleteBuffers(1, &m_buffer_name);
}
void allocate() { allocate(m_limit); }
void allocate(size_t new_limit)
{
if (!m_buffer_storage) {
m_start = 0;
m_limit = new_limit;
glBufferData(m_target, m_limit * STRIDE, NULL, GL_STREAM_DRAW);
}
}
void bind()
{
glBindBuffer(m_target, m_buffer_name);
}
void subdata_upload(const void* src)
{
// Current GPU buffer is really too small need to allocate a new one
if (m_count > m_limit) {
//fprintf(stderr, "Allocate a new buffer\n %d", STRIDE);
allocate(std::max<int>(m_count * 3 / 2, m_limit));
} else if (m_count > (m_limit - m_start) ) {
//fprintf(stderr, "Orphan the buffer %d\n", STRIDE);
// Not enough left free room. Just go back at the beginning
m_start = 0;
// Orphan the buffer to avoid synchronization
allocate(m_limit);
}
glBufferSubData(m_target, STRIDE * m_start, STRIDE * m_count, src);
}
void map_upload(const void* src)
{
ASSERT(m_count < m_limit);
@ -207,11 +169,7 @@ class GSBufferOGL {
m_count = count;
if (m_buffer_storage) {
map_upload(src);
} else {
subdata_upload(src);
}
map_upload(src);
}
void EndScene()
@ -267,8 +225,6 @@ public:
m_vb->bind();
m_ib->bind();
m_vb->allocate();
m_ib->allocate();
set_internal_format(layout, layout_nbr);
}

View File

@ -128,7 +128,7 @@ void GSWndGL::PopulateGlFunction()
GL_EXT_LOAD_OPT(glDebugMessageControl);
// GL4.4
GL_EXT_LOAD_OPT(glClearTexImage);
GL_EXT_LOAD_OPT(glBufferStorage);
GL_EXT_LOAD(glBufferStorage);
// GL4.5
GL_EXT_LOAD_OPT(glCreateTextures);