Use storage buffer for vao manager

This commit is contained in:
vlj 2014-08-29 02:39:55 +02:00
parent 1e1ba34f45
commit fc80ebbbcb
5 changed files with 47 additions and 10 deletions

View File

@ -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]);

View File

@ -183,6 +183,7 @@ class VAOManager : public Singleton<VAOManager>
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<scene::IMeshBuffer *> 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<unsigned, unsigned> getBase(scene::IMeshBuffer *);
size_t appendInstance(enum InstanceType, const std::vector<InstanceData> &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<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
unsigned getShadowInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return ShadowInstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }

View File

@ -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;

View File

@ -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 {

View File

@ -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);