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