From fc80ebbbcb73b04d65cb1aa43aa77a2237625f6a Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 29 Aug 2014 02:39:55 +0200 Subject: [PATCH] Use storage buffer for vao manager --- src/graphics/glwrap.cpp | 11 ++++++++++- src/graphics/glwrap.hpp | 2 ++ src/graphics/irr_driver.cpp | 7 +++++++ src/graphics/irr_driver.hpp | 6 ++++++ src/graphics/stkanimatedmesh.cpp | 31 ++++++++++++++++++++++--------- 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 15c674841..dabd4a83c 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -645,7 +645,16 @@ void VAOManager::regenerateBuffer(enum VTXTYPE tp) glDeleteBuffers(1, &vbo[tp]); glGenBuffers(1, &vbo[tp]); glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]); - glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW); +#ifdef Buffer_Storage + if (irr_driver->hasBufferStorageExtension()) + { + glBufferStorage(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); + VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, vtx_cnt[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); + } + else +#endif + glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW); + if (ibo[tp]) glDeleteBuffers(1, &ibo[tp]); diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 62f192864..d973321d3 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -183,6 +183,7 @@ class VAOManager : public Singleton GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT]; GLuint instance_vbo[1]; size_t instance_count[1]; + void *VBOPtr[VTXTYPE_COUNT]; std::vector storedCPUBuffer[VTXTYPE_COUNT]; void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT]; size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT]; @@ -201,6 +202,7 @@ public: std::pair getBase(scene::IMeshBuffer *); size_t appendInstance(enum InstanceType, const std::vector &instance_data); unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; } + void *getVBOPtr(video::E_VERTEX_TYPE type) { return VBOPtr[getVTXTYPE(type)]; } unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; } unsigned getInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return InstanceVAO[std::pair(vt, it)]; } unsigned getShadowInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return ShadowInstanceVAO[std::pair(vt, it)]; } diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index ad1a834c1..b20cc1cc0 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -489,6 +489,7 @@ void IrrDriver::initDevice() // Parse extensions hasVSLayer = false; hasBaseInstance = false; + hasBuffserStorage = false; // Default false value for hasVSLayer if --no-graphics argument is used if (!ProfileWorld::isNoGraphics()) { @@ -496,6 +497,12 @@ void IrrDriver::initDevice() hasVSLayer = true; Log::info("GLDriver", "AMD Vertex Shader Layer enabled"); } +#ifdef Buffer_Storage + if (hasGLExtension("GL_ARB_buffer_storage")) { + hasBuffserStorage = true; + Log::info("GLDriver", "ARB Buffer Storage enabled"); + } +#endif #ifdef Base_Instance_Support if (hasGLExtension("GL_ARB_base_instance")) { hasBaseInstance = true; diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 5dceba6c2..76a6e86e7 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -200,6 +200,7 @@ private: int GLMajorVersion, GLMinorVersion; bool hasVSLayer; bool hasBaseInstance; + bool hasBuffserStorage; bool m_need_ubo_workaround; bool m_need_rh_workaround; bool m_need_srgb_workaround; @@ -310,6 +311,11 @@ public: return hasVSLayer; } + bool hasBufferStorageExtension() const + { + return hasBuffserStorage; + } + video::SColorf getAmbientLight() const; struct GlowData { diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp index 257e97a49..ba5d15c17 100644 --- a/src/graphics/stkanimatedmesh.cpp +++ b/src/graphics/stkanimatedmesh.cpp @@ -135,17 +135,30 @@ void STKAnimatedMesh::update() const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; if (isObject(material.MaterialType)) { - glBindVertexArray(0); - size_t size = mb->getVertexCount() * GLmeshes[i].Stride; - if (irr_driver->hasARB_base_instance()) - glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType())); + + size_t size = mb->getVertexCount() * GLmeshes[i].Stride, offset = GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride; + void *buf; + if (irr_driver->hasBufferStorageExtension()) + { + buf = VAOManager::getInstance()->getVBOPtr(mb->getVertexType()); + buf = (char *)buf + offset; + } else - glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer); - GLbitfield bitfield = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; - void * buf = glMapBufferRange(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, size, bitfield); + { + glBindVertexArray(0); + if (irr_driver->hasARB_base_instance()) + glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType())); + else + glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer); + GLbitfield bitfield = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + buf = glMapBufferRange(GL_ARRAY_BUFFER, offset, size, bitfield); + } memcpy(buf, mb->getVertices(), size); - glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); + if (!irr_driver->hasBufferStorageExtension()) + { + glUnmapBuffer(GL_ARRAY_BUFFER); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } } if (mb) GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);