mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: found_GL_ARB_buffer_storage is now mandatory
This commit is contained in:
parent
52e3c3516d
commit
a62019a3fd
|
@ -475,7 +475,7 @@ namespace GLLoader {
|
||||||
// GL4.3
|
// GL4.3
|
||||||
status &= status_and_override(found_GL_ARB_copy_image, "GL_ARB_copy_image");
|
status &= status_and_override(found_GL_ARB_copy_image, "GL_ARB_copy_image");
|
||||||
// GL4.4
|
// 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");
|
status &= status_and_override(found_GL_ARB_clear_texture,"GL_ARB_clear_texture");
|
||||||
// GL4.5
|
// GL4.5
|
||||||
status &= status_and_override(found_GL_ARB_clip_control, "GL_ARB_clip_control", true);
|
status &= status_and_override(found_GL_ARB_clip_control, "GL_ARB_clip_control", true);
|
||||||
|
|
|
@ -352,7 +352,6 @@ namespace GLLoader {
|
||||||
extern bool found_GL_ARB_gpu_shader5;
|
extern bool found_GL_ARB_gpu_shader5;
|
||||||
extern bool found_GL_ARB_shader_image_load_store;
|
extern bool found_GL_ARB_shader_image_load_store;
|
||||||
extern bool found_GL_ARB_clear_texture;
|
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_ARB_direct_state_access;
|
||||||
extern bool found_GL_EXT_texture_filter_anisotropic;
|
extern bool found_GL_EXT_texture_filter_anisotropic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ namespace PboPool {
|
||||||
char* m_map[PBO_POOL_SIZE];
|
char* m_map[PBO_POOL_SIZE];
|
||||||
uint32 m_current_pbo = 0;
|
uint32 m_current_pbo = 0;
|
||||||
uint32 m_size;
|
uint32 m_size;
|
||||||
bool m_texture_storage;
|
|
||||||
GLsync m_fence[PBO_POOL_SIZE];
|
GLsync m_fence[PBO_POOL_SIZE];
|
||||||
const uint32 m_pbo_size = 8*1024*1024;
|
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
|
// will use DMA CACHED memory as the source for buffer object operations
|
||||||
void Init() {
|
void Init() {
|
||||||
glGenBuffers(countof(m_pool), m_pool);
|
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++) {
|
for (size_t i = 0; i < countof(m_pool); i++) {
|
||||||
BindPbo();
|
BindPbo();
|
||||||
|
|
||||||
if (m_texture_storage) {
|
glBufferStorage(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, create_flags);
|
||||||
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_map[m_current_pbo] = (char*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, m_pbo_size, map_flags);
|
m_fence[m_current_pbo] = 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
NextPbo();
|
NextPbo();
|
||||||
}
|
}
|
||||||
|
@ -89,44 +82,22 @@ namespace PboPool {
|
||||||
fprintf(stderr, "BUG: PBO too small %d but need %d\n", m_pbo_size, m_size);
|
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) {
|
||||||
if (m_offset[m_current_pbo] + m_size >= m_pbo_size) {
|
//NextPbo(); // For test purpose
|
||||||
//NextPbo(); // For test purpose
|
NextPboWithSync();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unmap() {
|
void Unmap() {
|
||||||
if (m_texture_storage) {
|
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset[m_current_pbo], m_size);
|
||||||
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset[m_current_pbo], m_size);
|
|
||||||
} else {
|
|
||||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uptr Offset() {
|
uptr Offset() {
|
||||||
|
@ -134,18 +105,16 @@ namespace PboPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Destroy() {
|
void Destroy() {
|
||||||
if (m_texture_storage) {
|
for (size_t i = 0; i < countof(m_pool); i++) {
|
||||||
for (size_t i = 0; i < countof(m_pool); i++) {
|
m_map[i] = NULL;
|
||||||
m_map[i] = NULL;
|
m_offset[i] = 0;
|
||||||
m_offset[i] = 0;
|
glDeleteSync(m_fence[i]);
|
||||||
glDeleteSync(m_fence[i]);
|
|
||||||
|
|
||||||
// Don't know if we must do it
|
// Don't know if we must do it
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pool[i]);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pool[i]);
|
||||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
}
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
|
||||||
}
|
}
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
glDeleteBuffers(countof(m_pool), m_pool);
|
glDeleteBuffers(countof(m_pool), m_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ class GSBufferOGL {
|
||||||
const GLenum m_target;
|
const GLenum m_target;
|
||||||
GLuint m_buffer_name;
|
GLuint m_buffer_name;
|
||||||
uint8* m_buffer_ptr;
|
uint8* m_buffer_ptr;
|
||||||
const bool m_buffer_storage;
|
|
||||||
GLsync m_fence[5];
|
GLsync m_fence[5];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -52,7 +51,6 @@ class GSBufferOGL {
|
||||||
, m_count(0)
|
, m_count(0)
|
||||||
, m_limit(0)
|
, m_limit(0)
|
||||||
, m_target(target)
|
, m_target(target)
|
||||||
, m_buffer_storage(GLLoader::found_GL_ARB_buffer_storage)
|
|
||||||
{
|
{
|
||||||
glGenBuffers(1, &m_buffer_name);
|
glGenBuffers(1, &m_buffer_name);
|
||||||
// Opengl works best with 1-4MB buffer.
|
// Opengl works best with 1-4MB buffer.
|
||||||
|
@ -63,73 +61,37 @@ class GSBufferOGL {
|
||||||
m_fence[i] = 0;
|
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.
|
||||||
// TODO: if we do manually the synchronization, I'm not sure size is important. It worths to investigate it.
|
// => bigger buffer => less sync
|
||||||
// => bigger buffer => less sync
|
bind();
|
||||||
bind();
|
// coherency will be done by flushing
|
||||||
// coherency will be done by flushing
|
const GLbitfield common_flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT;
|
||||||
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 map_flags = common_flags | GL_MAP_FLUSH_EXPLICIT_BIT;
|
const GLbitfield create_flags = common_flags | GL_CLIENT_STORAGE_BIT;
|
||||||
const GLbitfield create_flags = common_flags | GL_CLIENT_STORAGE_BIT;
|
|
||||||
|
|
||||||
glBufferStorage(m_target, STRIDE * m_limit, NULL, create_flags );
|
glBufferStorage(m_target, STRIDE * m_limit, NULL, create_flags );
|
||||||
m_buffer_ptr = (uint8*) glMapBufferRange(m_target, 0, STRIDE * m_limit, map_flags);
|
m_buffer_ptr = (uint8*) glMapBufferRange(m_target, 0, STRIDE * m_limit, map_flags);
|
||||||
if (!m_buffer_ptr) {
|
if (!m_buffer_ptr) {
|
||||||
fprintf(stderr, "Failed to map buffer\n");
|
fprintf(stderr, "Failed to map buffer\n");
|
||||||
throw GSDXError();
|
throw GSDXError();
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_buffer_ptr = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GSBufferOGL() {
|
~GSBufferOGL() {
|
||||||
if (m_buffer_storage) {
|
for (size_t i = 0; i < 5; i++) {
|
||||||
for (size_t i = 0; i < 5; i++) {
|
glDeleteSync(m_fence[i]);
|
||||||
glDeleteSync(m_fence[i]);
|
|
||||||
}
|
|
||||||
// Don't know if we must do it
|
|
||||||
bind();
|
|
||||||
glUnmapBuffer(m_target);
|
|
||||||
}
|
}
|
||||||
|
// Don't know if we must do it
|
||||||
|
bind();
|
||||||
|
glUnmapBuffer(m_target);
|
||||||
glDeleteBuffers(1, &m_buffer_name);
|
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()
|
void bind()
|
||||||
{
|
{
|
||||||
glBindBuffer(m_target, m_buffer_name);
|
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)
|
void map_upload(const void* src)
|
||||||
{
|
{
|
||||||
ASSERT(m_count < m_limit);
|
ASSERT(m_count < m_limit);
|
||||||
|
@ -207,11 +169,7 @@ class GSBufferOGL {
|
||||||
|
|
||||||
m_count = count;
|
m_count = count;
|
||||||
|
|
||||||
if (m_buffer_storage) {
|
map_upload(src);
|
||||||
map_upload(src);
|
|
||||||
} else {
|
|
||||||
subdata_upload(src);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndScene()
|
void EndScene()
|
||||||
|
@ -267,8 +225,6 @@ public:
|
||||||
m_vb->bind();
|
m_vb->bind();
|
||||||
m_ib->bind();
|
m_ib->bind();
|
||||||
|
|
||||||
m_vb->allocate();
|
|
||||||
m_ib->allocate();
|
|
||||||
set_internal_format(layout, layout_nbr);
|
set_internal_format(layout, layout_nbr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ void GSWndGL::PopulateGlFunction()
|
||||||
GL_EXT_LOAD_OPT(glDebugMessageControl);
|
GL_EXT_LOAD_OPT(glDebugMessageControl);
|
||||||
// GL4.4
|
// GL4.4
|
||||||
GL_EXT_LOAD_OPT(glClearTexImage);
|
GL_EXT_LOAD_OPT(glClearTexImage);
|
||||||
GL_EXT_LOAD_OPT(glBufferStorage);
|
GL_EXT_LOAD(glBufferStorage);
|
||||||
|
|
||||||
// GL4.5
|
// GL4.5
|
||||||
GL_EXT_LOAD_OPT(glCreateTextures);
|
GL_EXT_LOAD_OPT(glCreateTextures);
|
||||||
|
|
Loading…
Reference in New Issue