Implement volatile vertex buffer for opengl driver, should provide considerable performance improvements for particle systems. Needs additional testing.
This commit is contained in:
parent
0d67c420cd
commit
766cace955
4 changed files with 70 additions and 17 deletions
|
@ -372,6 +372,10 @@ PFNGLUNMAPBUFFERARBPROC nglUnmapBufferARB;
|
||||||
PFNGLGETBUFFERPARAMETERIVARBPROC nglGetBufferParameterivARB;
|
PFNGLGETBUFFERPARAMETERIVARBPROC nglGetBufferParameterivARB;
|
||||||
PFNGLGETBUFFERPOINTERVARBPROC nglGetBufferPointervARB;
|
PFNGLGETBUFFERPOINTERVARBPROC nglGetBufferPointervARB;
|
||||||
|
|
||||||
|
// GL_ARB_map_buffer_range
|
||||||
|
PFNGLMAPBUFFERRANGEPROC nglMapBufferRange;
|
||||||
|
PFNGLFLUSHMAPPEDBUFFERRANGEPROC nglFlushMappedBufferRange;
|
||||||
|
|
||||||
// GL_ARB_vertex_program
|
// GL_ARB_vertex_program
|
||||||
PFNGLVERTEXATTRIB1SARBPROC nglVertexAttrib1sARB;
|
PFNGLVERTEXATTRIB1SARBPROC nglVertexAttrib1sARB;
|
||||||
PFNGLVERTEXATTRIB1FARBPROC nglVertexAttrib1fARB;
|
PFNGLVERTEXATTRIB1FARBPROC nglVertexAttrib1fARB;
|
||||||
|
@ -1259,6 +1263,21 @@ static bool setupARBVertexBufferObject(const char *glext)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
static bool setupARBMapBufferRange(const char *glext)
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(setupARBMapBufferRange);
|
||||||
|
|
||||||
|
#ifndef USE_OPENGLES
|
||||||
|
CHECK_EXT("GL_ARB_map_buffer_range");
|
||||||
|
|
||||||
|
CHECK_ADDRESS(PFNGLMAPBUFFERRANGEPROC, glMapBufferRange);
|
||||||
|
CHECK_ADDRESS(PFNGLFLUSHMAPPEDBUFFERRANGEPROC, glFlushMappedBufferRange);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
static bool setupARBVertexProgram(const char *glext)
|
static bool setupARBVertexProgram(const char *glext)
|
||||||
{
|
{
|
||||||
|
@ -1695,6 +1714,7 @@ void registerGlExtensions(CGlExtensions &ext)
|
||||||
if(!ext.DisableHardwareVertexArrayAGP)
|
if(!ext.DisableHardwareVertexArrayAGP)
|
||||||
{
|
{
|
||||||
ext.ARBVertexBufferObject = setupARBVertexBufferObject(glext);
|
ext.ARBVertexBufferObject = setupARBVertexBufferObject(glext);
|
||||||
|
ext.ARBMapBufferRange = setupARBMapBufferRange(glext);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix for radeon 7200 -> disable agp
|
// fix for radeon 7200 -> disable agp
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct CGlExtensions
|
||||||
bool ARBTextureCompression;
|
bool ARBTextureCompression;
|
||||||
bool ARBFragmentProgram;
|
bool ARBFragmentProgram;
|
||||||
bool ARBVertexBufferObject;
|
bool ARBVertexBufferObject;
|
||||||
|
bool ARBMapBufferRange;
|
||||||
bool ARBVertexProgram;
|
bool ARBVertexProgram;
|
||||||
bool ARBTextureNonPowerOfTwo;
|
bool ARBTextureNonPowerOfTwo;
|
||||||
bool ARBMultisample;
|
bool ARBMultisample;
|
||||||
|
@ -262,6 +263,7 @@ public:
|
||||||
result += ATIVertexArrayObject ? "ATIVertexArrayObject " : "";
|
result += ATIVertexArrayObject ? "ATIVertexArrayObject " : "";
|
||||||
result += ATIVertexAttribArrayObject ? "ATIVertexAttribArrayObject " : "";
|
result += ATIVertexAttribArrayObject ? "ATIVertexAttribArrayObject " : "";
|
||||||
result += ARBVertexBufferObject ? "ARBVertexBufferObject " : "";
|
result += ARBVertexBufferObject ? "ARBVertexBufferObject " : "";
|
||||||
|
result += ARBMapBufferRange ? "ARBMapBufferRange " : "";
|
||||||
result += ATIMapObjectBuffer ? "ATIMapObjectBuffer " : "";
|
result += ATIMapObjectBuffer ? "ATIMapObjectBuffer " : "";
|
||||||
|
|
||||||
result += "\n FBO: ";
|
result += "\n FBO: ";
|
||||||
|
@ -654,7 +656,10 @@ extern PFNGLUNMAPBUFFERARBPROC nglUnmapBufferARB;
|
||||||
extern PFNGLGETBUFFERPARAMETERIVARBPROC nglGetBufferParameterivARB;
|
extern PFNGLGETBUFFERPARAMETERIVARBPROC nglGetBufferParameterivARB;
|
||||||
extern PFNGLGETBUFFERPOINTERVARBPROC nglGetBufferPointervARB;
|
extern PFNGLGETBUFFERPOINTERVARBPROC nglGetBufferPointervARB;
|
||||||
|
|
||||||
|
// GL_ARB_map_buffer_range
|
||||||
|
//==================================
|
||||||
|
extern PFNGLMAPBUFFERRANGEPROC nglMapBufferRange;
|
||||||
|
extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC nglFlushMappedBufferRange;
|
||||||
|
|
||||||
// GL_ARB_vertex_program
|
// GL_ARB_vertex_program
|
||||||
//==================================
|
//==================================
|
||||||
|
|
|
@ -147,9 +147,9 @@ bool CDriverGL::setupVertexBuffer(CVertexBuffer& VB)
|
||||||
CVBDrvInfosGL *info = new CVBDrvInfosGL(this, it, &VB);
|
CVBDrvInfosGL *info = new CVBDrvInfosGL(this, it, &VB);
|
||||||
*it= VB.DrvInfos = info;
|
*it= VB.DrvInfos = info;
|
||||||
|
|
||||||
// Preferred memory
|
// Preferred memory, AGPVolatile only goes through when ARBMapBufferRange is available
|
||||||
CVertexBuffer::TPreferredMemory preferred = VB.getPreferredMemory ();
|
CVertexBuffer::TPreferredMemory preferred = VB.getPreferredMemory ();
|
||||||
if ((preferred == CVertexBuffer::RAMVolatile) || (preferred == CVertexBuffer::AGPVolatile))
|
if ((preferred == CVertexBuffer::RAMVolatile) || (preferred == CVertexBuffer::AGPVolatile && !_Extensions.ARBMapBufferRange))
|
||||||
preferred = CVertexBuffer::RAMPreferred;
|
preferred = CVertexBuffer::RAMPreferred;
|
||||||
const uint size = VB.capacity()*VB.getVertexSize();
|
const uint size = VB.capacity()*VB.getVertexSize();
|
||||||
uint preferredMemory = _Extensions.DisableHardwareVertexArrayAGP ? CVertexBuffer::RAMPreferred : preferred;
|
uint preferredMemory = _Extensions.DisableHardwareVertexArrayAGP ? CVertexBuffer::RAMPreferred : preferred;
|
||||||
|
@ -159,6 +159,12 @@ bool CDriverGL::setupVertexBuffer(CVertexBuffer& VB)
|
||||||
info->_VBHard = createVertexBufferHard(size, VB.capacity(), (CVertexBuffer::TPreferredMemory)preferredMemory, &VB);
|
info->_VBHard = createVertexBufferHard(size, VB.capacity(), (CVertexBuffer::TPreferredMemory)preferredMemory, &VB);
|
||||||
if (info->_VBHard)
|
if (info->_VBHard)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if ((CVertexBuffer::TPreferredMemory)preferredMemory == CVertexBuffer::AGPVolatile)
|
||||||
|
{
|
||||||
|
preferredMemory = CVertexBuffer::RAMPreferred;
|
||||||
|
break;
|
||||||
|
}
|
||||||
preferredMemory--;
|
preferredMemory--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +176,7 @@ bool CDriverGL::setupVertexBuffer(CVertexBuffer& VB)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload the data
|
// Upload the data
|
||||||
VB.setLocation ((CVertexBuffer::TLocation)preferredMemory);
|
VB.setLocation(preferredMemory == CVertexBuffer::AGPVolatile ? CVertexBuffer::AGPResident : (CVertexBuffer::TLocation)preferredMemory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,7 +746,7 @@ bool CDriverGL::supportVertexBufferHard() const
|
||||||
bool CDriverGL::supportVolatileVertexBuffer() const
|
bool CDriverGL::supportVolatileVertexBuffer() const
|
||||||
{
|
{
|
||||||
H_AUTO_OGL(CDriverGL_supportVolatileVertexBuffer)
|
H_AUTO_OGL(CDriverGL_supportVolatileVertexBuffer)
|
||||||
return false;
|
return _Extensions.ARBMapBufferRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -769,6 +775,7 @@ IVertexBufferHardGL *CDriverGL::createVertexBufferHard(uint size, uint numVertic
|
||||||
IVertexArrayRange *vertexArrayRange= NULL;
|
IVertexArrayRange *vertexArrayRange= NULL;
|
||||||
switch(vbType)
|
switch(vbType)
|
||||||
{
|
{
|
||||||
|
case CVertexBuffer::AGPVolatile:
|
||||||
case CVertexBuffer::AGPPreferred:
|
case CVertexBuffer::AGPPreferred:
|
||||||
vertexArrayRange= _AGPVertexArrayRange;
|
vertexArrayRange= _AGPVertexArrayRange;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1174,6 +1174,9 @@ bool CVertexArrayRangeARB::allocate(uint32 size, CVertexBuffer::TPreferredMemory
|
||||||
|
|
||||||
switch(vbType)
|
switch(vbType)
|
||||||
{
|
{
|
||||||
|
case CVertexBuffer::AGPVolatile:
|
||||||
|
glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STREAM_DRAW_ARB);
|
||||||
|
break;
|
||||||
case CVertexBuffer::AGPPreferred:
|
case CVertexBuffer::AGPPreferred:
|
||||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||||
break;
|
break;
|
||||||
|
@ -1221,13 +1224,14 @@ IVertexBufferHardGL *CVertexArrayRangeARB::createVBHardGL(uint size, CVertexBuff
|
||||||
|
|
||||||
if (glGetError() != GL_NO_ERROR) return NULL;
|
if (glGetError() != GL_NO_ERROR) return NULL;
|
||||||
_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
|
_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
|
||||||
switch(_VBType)
|
CVertexBuffer::TPreferredMemory preferred = vb->getPreferredMemory();
|
||||||
|
switch (preferred)
|
||||||
{
|
{
|
||||||
case CVertexBuffer::AGPPreferred:
|
case CVertexBuffer::AGPVolatile:
|
||||||
#ifdef USE_OPENGLES
|
#ifdef USE_OPENGLES
|
||||||
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STREAM_DRAW);
|
||||||
#else
|
#else
|
||||||
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STREAM_DRAW_ARB);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case CVertexBuffer::StaticPreferred:
|
case CVertexBuffer::StaticPreferred:
|
||||||
|
@ -1244,8 +1248,13 @@ IVertexBufferHardGL *CVertexArrayRangeARB::createVBHardGL(uint size, CVertexBuff
|
||||||
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
// case CVertexBuffer::AGPPreferred:
|
||||||
default:
|
default:
|
||||||
nlassert(0);
|
#ifdef USE_OPENGLES
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
#else
|
||||||
|
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (glGetError() != GL_NO_ERROR)
|
if (glGetError() != GL_NO_ERROR)
|
||||||
|
@ -1259,7 +1268,7 @@ IVertexBufferHardGL *CVertexArrayRangeARB::createVBHardGL(uint size, CVertexBuff
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
CVertexBufferHardARB *newVbHard= new CVertexBufferHardARB(_Driver, vb);
|
CVertexBufferHardARB *newVbHard= new CVertexBufferHardARB(_Driver, vb);
|
||||||
newVbHard->initGL(vertexBufferID, this, _VBType);
|
newVbHard->initGL(vertexBufferID, this, preferred);
|
||||||
_Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
|
_Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
|
||||||
return newVbHard;
|
return newVbHard;
|
||||||
}
|
}
|
||||||
|
@ -1393,6 +1402,7 @@ void *CVertexBufferHardARB::lock()
|
||||||
H_AUTO_OGL(CVertexBufferHardARB_lock);
|
H_AUTO_OGL(CVertexBufferHardARB_lock);
|
||||||
|
|
||||||
if (_VertexPtr) return _VertexPtr; // already locked
|
if (_VertexPtr) return _VertexPtr; // already locked
|
||||||
|
const uint size = VB->getNumVertices() * VB->getVertexSize();
|
||||||
if (_Invalid)
|
if (_Invalid)
|
||||||
{
|
{
|
||||||
if (VB->getLocation() != CVertexBuffer::NotResident)
|
if (VB->getLocation() != CVertexBuffer::NotResident)
|
||||||
|
@ -1414,15 +1424,14 @@ void *CVertexBufferHardARB::lock()
|
||||||
_Driver->incrementResetCounter();
|
_Driver->incrementResetCounter();
|
||||||
return &_DummyVB[0];
|
return &_DummyVB[0];
|
||||||
}
|
}
|
||||||
const uint size = VB->getNumVertices() * VB->getVertexSize();
|
|
||||||
_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
|
_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
|
||||||
switch(_MemType)
|
switch(_MemType)
|
||||||
{
|
{
|
||||||
case CVertexBuffer::AGPPreferred:
|
case CVertexBuffer::AGPVolatile:
|
||||||
#ifdef USE_OPENGLES
|
#ifdef USE_OPENGLES
|
||||||
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STREAM_DRAW);
|
||||||
#else
|
#else
|
||||||
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STREAM_DRAW_ARB);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case CVertexBuffer::StaticPreferred:
|
case CVertexBuffer::StaticPreferred:
|
||||||
|
@ -1439,8 +1448,13 @@ void *CVertexBufferHardARB::lock()
|
||||||
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
// case CVertexBuffer::AGPPreferred:
|
||||||
default:
|
default:
|
||||||
nlassert(0);
|
#ifdef USE_OPENGLES
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
#else
|
||||||
|
nglBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (glGetError() != GL_NO_ERROR)
|
if (glGetError() != GL_NO_ERROR)
|
||||||
|
@ -1499,7 +1513,14 @@ void *CVertexBufferHardARB::lock()
|
||||||
_LastBufferSize = size;
|
_LastBufferSize = size;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
_VertexPtr = nglMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
if (_MemType == CVertexBuffer::AGPVolatile)
|
||||||
|
{
|
||||||
|
_VertexPtr = nglMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_VertexPtr = nglMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||||
|
}
|
||||||
if (!_VertexPtr)
|
if (!_VertexPtr)
|
||||||
{
|
{
|
||||||
nglUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
|
nglUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
|
||||||
|
|
Loading…
Reference in a new issue