From 1919a458e88fc1a06567b9496c6c47d34b9df5f2 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 15 Dec 2012 17:28:58 +0100 Subject: [PATCH] only use one buffer, orphaning should do the rest --- .../Src/NativeVertexFormat.cpp | 92 +++++++++---------- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 2 +- .../Plugin_VideoOGL/Src/VertexManager.cpp | 76 +++++---------- .../Plugin_VideoOGL/Src/VertexManager.h | 8 +- 4 files changed, 72 insertions(+), 106 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index 8669d32711..506c1a707d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -66,8 +66,7 @@ GLVertexFormat::GLVertexFormat() GLVertexFormat::~GLVertexFormat() { - VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; - glDeleteVertexArrays(vm->m_buffers_count, VAO); + glDeleteVertexArrays(1, &VAO); } inline GLuint VarToGL(VarType t) @@ -89,57 +88,54 @@ void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; - VAO = new GLuint[vm->m_buffers_count]; - glGenVertexArrays(vm->m_buffers_count, VAO); - for(u32 i=0; im_buffers_count; i++) { - glBindVertexArray(VAO[i]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers[i]); - glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[i]); + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (u8*)NULL); - - if (vtx_decl.num_normals >= 1) { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[0]); - if (vtx_decl.num_normals == 3) { - glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); - glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); - glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[1]); - glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[2]); - } - } + // the element buffer is bound directly to the vao, so we must it set for every vao + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers); - for (int i = 0; i < 2; i++) { - if (vtx_decl.color_offset[i] != -1) { - if (i == 0) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); - } else { - glEnableClientState(GL_SECONDARY_COLOR_ARRAY); - glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); - } - } - } - - for (int i = 0; i < 8; i++) { - if (vtx_decl.texcoord_offset[i] != -1) { - int id = GL_TEXTURE0 + i; - glClientActiveTexture(id); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), - vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]); - } - } - - if (vtx_decl.posmtx_offset != -1) { - glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); - glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (u8*)NULL); + + if (vtx_decl.num_normals >= 1) { + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[0]); + if (vtx_decl.num_normals == 3) { + glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); + glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); + glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[1]); + glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[2]); } } + + for (int i = 0; i < 2; i++) { + if (vtx_decl.color_offset[i] != -1) { + if (i == 0) { + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); + } else { + glEnableClientState(GL_SECONDARY_COLOR_ARRAY); + glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); + } + } + } + + for (int i = 0; i < 8; i++) { + if (vtx_decl.texcoord_offset[i] != -1) { + int id = GL_TEXTURE0 + i; + glClientActiveTexture(id); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), + vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]); + } + } + + if (vtx_decl.posmtx_offset != -1) { + glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); + glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset); + } - glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[vm->m_current_buffer]); + vm->m_last_vao = VAO; } void GLVertexFormat::SetupVertexPointers() { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index d4b945199c..a03ac84b8a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1453,7 +1453,7 @@ void Renderer::RestoreAPIState() PixelShaderCache::SetCurrentShader(0); VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; - glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers[vm->m_current_buffer]); + glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers); vm->m_last_vao = 0; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index ceb04daeca..29cf903c04 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -53,7 +53,6 @@ const u32 MAX_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); const u32 MAX_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; const u32 MIN_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 1 * sizeof(u16); const u32 MIN_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 1; -const u32 MAX_VBUFFER_COUNT = 2; VertexManager::VertexManager() { @@ -67,10 +66,6 @@ VertexManager::~VertexManager() void VertexManager::CreateDeviceObjects() { - m_buffers_count = 0; - m_vertex_buffers = NULL; - m_index_buffers = NULL; - glEnableClientState(GL_VERTEX_ARRAY); GL_REPORT_ERRORD(); u32 max_Index_size = 0; u32 max_Vertex_size = 0; @@ -90,31 +85,18 @@ void VertexManager::CreateDeviceObjects() ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_VERTICES to small, so try it anyway. good luck\n"); } - //TODO: find out, how many buffers fit in gpu memory - m_buffers_count = MAX_VBUFFER_COUNT; - - m_vertex_buffers = new GLuint[m_buffers_count]; - m_index_buffers = new GLuint[m_buffers_count]; - - glGenBuffers(m_buffers_count, m_vertex_buffers); + glGenBuffers(1, &m_vertex_buffers); GL_REPORT_ERROR(); - glGenBuffers(m_buffers_count, m_index_buffers); + glGenBuffers(1, &m_index_buffers); + GL_REPORT_ERROR(); + glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers ); + GL_REPORT_ERROR(); + glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW ); + GL_REPORT_ERROR(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers ); + GL_REPORT_ERROR(); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW ); GL_REPORT_ERROR(); - for (u32 i = 0; i < m_buffers_count; i++) - { - glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[i] ); - GL_REPORT_ERROR(); - glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW ); - GL_REPORT_ERROR(); - } - for (u32 i = 0; i < m_buffers_count; i++) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[i] ); - GL_REPORT_ERROR(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW ); - GL_REPORT_ERROR(); - } - m_current_buffer = 0; m_index_buffer_cursor = 0; m_vertex_buffer_cursor = 0; m_CurrentVertexFmt = NULL; @@ -122,23 +104,16 @@ void VertexManager::CreateDeviceObjects() } void VertexManager::DestroyDeviceObjects() { - glDisableClientState(GL_VERTEX_ARRAY); GL_REPORT_ERRORD(); glBindBuffer(GL_ARRAY_BUFFER, 0 ); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0 ); GL_REPORT_ERROR(); - glDeleteBuffers(m_buffers_count, m_vertex_buffers); + glDeleteBuffers(1, &m_vertex_buffers); GL_REPORT_ERROR(); - delete [] m_vertex_buffers; - glDeleteBuffers(m_buffers_count, m_index_buffers); + glDeleteBuffers(1, &m_index_buffers); GL_REPORT_ERROR(); - delete [] m_index_buffers; - - m_vertex_buffers = NULL; - m_index_buffers = NULL; - m_buffers_count = 0; } void VertexManager::PrepareDrawBuffers(u32 stride) @@ -150,7 +125,6 @@ void VertexManager::PrepareDrawBuffers(u32 stride) int line_index_size = IndexGenerator::GetLineindexLen(); int point_index_size = IndexGenerator::GetPointindexLen(); int index_data_size = (triangle_index_size + line_index_size + point_index_size) * sizeof(u16); - GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt; GLbitfield LockMode = GL_MAP_WRITE_BIT; m_vertex_buffer_cursor--; @@ -158,22 +132,14 @@ void VertexManager::PrepareDrawBuffers(u32 stride) if (m_vertex_buffer_cursor >= m_vertex_buffer_size - vertex_data_size || m_index_buffer_cursor >= m_index_buffer_size - index_data_size) { - // do we really want to set this? this require a reallocation. usualy only one buffer with reallocation, or much buffers without it LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; m_vertex_buffer_cursor = 0; m_index_buffer_cursor = 0; - m_current_buffer = (m_current_buffer + 1) % m_buffers_count; - glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_buffer]); } else { LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; } - - // this replaces SetupVertexPointers and must be called after switching buffer and befor uploading indexes - // but could be deleted, if we only use one buffer with orphaning - if(m_last_vao != nativeVertexFmt->VAO[m_current_buffer]) - glBindVertexArray(nativeVertexFmt->VAO[m_current_buffer]); pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode); if(pVertices) @@ -284,9 +250,16 @@ void VertexManager::vFlush() (void)GL_REPORT_ERROR(); - u32 stride = g_nativeVertexFmt->GetVertexStride(); + GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt; + u32 stride = nativeVertexFmt->GetVertexStride(); + + if(m_last_vao != nativeVertexFmt->VAO) { + glBindVertexArray(nativeVertexFmt->VAO); + m_last_vao = nativeVertexFmt->VAO; + } PrepareDrawBuffers(stride); + GL_REPORT_ERRORD(); u32 usedtextures = 0; @@ -385,11 +358,10 @@ void VertexManager::vFlush() glEnable(GL_BLEND); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); - if(m_buffers_count) - { - m_index_buffer_cursor += (IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen()) * sizeof(u16); - m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; - } + + m_index_buffer_cursor += (IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen()) * sizeof(u16); + m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; + ResetBuffer(); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index 91319b54f2..4d820692b9 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -35,7 +35,7 @@ namespace OGL virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); virtual void SetupVertexPointers(); - GLuint *VAO; + GLuint VAO; }; // Handles the OpenGL details of drawing lots of vertices quickly. @@ -50,10 +50,8 @@ public: void DestroyDeviceObjects(); // NativeVertexFormat use this - u32 m_buffers_count; - u32 m_current_buffer; - GLuint* m_vertex_buffers; - GLuint* m_index_buffers; + GLuint m_vertex_buffers; + GLuint m_index_buffers; GLuint m_last_vao; private: void Draw(u32 stride);