GL3: Refactor vertex buffers

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 11 years ago
parent 46ac4541f9
commit b6ac857074

@ -234,13 +234,13 @@ CDriverGL3::CDriverGL3()
_ForceNormalize= false;
_AGPVertexArrayRange= NULL;
/*_AGPVertexArrayRange= NULL;
_VRAMVertexArrayRange= NULL;
_CurrentVertexArrayRange= NULL;
_CurrentVertexBufferHard= NULL;
_NVCurrentVARPtr= NULL;
_NVCurrentVARSize= 0;
_SlowUnlockVBHard= false;
_CurrentVertexArrayRange= NULL;*/
_CurrentVertexBufferGL= NULL;
/*_NVCurrentVARPtr= NULL;
_NVCurrentVARSize= 0;*/
_SlowUnlockVBHard= true;
_AllocatedTextureMemory= 0;
@ -387,16 +387,14 @@ bool CDriverGL3::setupDisplay()
_PZBCameraPos = CVector::Null;
// Init VertexArrayRange according to supported extenstion.
_SlowUnlockVBHard = false;
_AGPVertexArrayRange = new CVertexArrayRange(this);
/*_AGPVertexArrayRange = new CVertexArrayRange(this);
_VRAMVertexArrayRange = new CVertexArrayRange(this);
// Reset VertexArrayRange.
_CurrentVertexArrayRange = NULL;
_CurrentVertexBufferHard = NULL;
_CurrentVertexBufferGL = NULL;
_NVCurrentVARPtr = NULL;
_NVCurrentVARSize = 0;
_NVCurrentVARSize = 0;*/
initVertexBufferHard(NL3D_DRV_VERTEXARRAY_AGP_INIT_SIZE, 0);
@ -581,8 +579,7 @@ bool CDriverGL3::swapBuffers()
if (!_WndActive)
{
if (_AGPVertexArrayRange) _AGPVertexArrayRange->updateLostBuffers();
if (_VRAMVertexArrayRange) _VRAMVertexArrayRange->updateLostBuffers();
updateLostBuffers();
}
#if defined(NL_OS_WINDOWS)
@ -641,9 +638,10 @@ bool CDriverGL3::swapBuffers()
_CurVBHardLockCount= 0;
_NumVBHardProfileFrame++;
}
// on ati, if the window is inactive, check all vertex buffer to see which one are lost
if (_AGPVertexArrayRange) _AGPVertexArrayRange->updateLostBuffers();
if (_VRAMVertexArrayRange) _VRAMVertexArrayRange->updateLostBuffers();
// Check all vertex buffer to see which one are lost
updateLostBuffers();
return true;
}
@ -688,14 +686,8 @@ bool CDriverGL3::release()
// release caustic cube map
// _CauticCubeMap = NULL;
// Reset VertexArrayRange.
resetVertexArrayRange();
// delete containers
delete _AGPVertexArrayRange;
delete _VRAMVertexArrayRange;
_AGPVertexArrayRange= NULL;
_VRAMVertexArrayRange= NULL;
// Make sure vertex buffers are really all gone
// FIXME VERTEXBUFFER
// destroy window and associated ressources
destroyWindow();
@ -1432,13 +1424,13 @@ void CDriverGL3::profileVBHardAllocation(std::vector<std::string> &result)
result.reserve(1000);
result.push_back(toString("Memory Allocated: %4d Ko in AGP / %4d Ko in VRAM",
getAvailableVertexAGPMemory()/1000, getAvailableVertexVRAMMemory()/1000));
result.push_back(toString("Num VBHard: %d", _VertexBufferHardSet.Set.size()));
result.push_back(toString("Num VBHard: %d", _VertexBufferGLSet.Set.size()));
uint totalMemUsed= 0;
set<IVertexBufferHardGL*>::iterator it;
for (it= _VertexBufferHardSet.Set.begin(); it!=_VertexBufferHardSet.Set.end(); it++)
set<IVertexBufferGL*>::iterator it;
for (it= _VertexBufferGLSet.Set.begin(); it!=_VertexBufferGLSet.Set.end(); it++)
{
IVertexBufferHardGL *vbHard= *it;
IVertexBufferGL *vbHard= *it;
if (vbHard)
{
uint vSize= vbHard->VB->getVertexSize();
@ -1448,9 +1440,9 @@ void CDriverGL3::profileVBHardAllocation(std::vector<std::string> &result)
}
result.push_back(toString("Mem Used: %4d Ko", totalMemUsed/1000));
for (it= _VertexBufferHardSet.Set.begin(); it!=_VertexBufferHardSet.Set.end(); it++)
for (it= _VertexBufferGLSet.Set.begin(); it!=_VertexBufferGLSet.Set.end(); it++)
{
IVertexBufferHardGL *vbHard= *it;
IVertexBufferGL *vbHard= *it;
if (vbHard)
{
uint vSize= vbHard->VB->getVertexSize();

@ -88,7 +88,7 @@ namespace NLDRIVERGL3 {
class CDriverGL3;
class IVertexArrayRange;
class IVertexBufferHardGL;
class IVertexBufferGL;
class COcclusionQueryGL3;
void displayGLError(GLenum error);
@ -190,7 +190,7 @@ public:
CVBDrvInfosGL3(CDriverGL3 *drv, ItVBDrvInfoPtrList it, CVertexBuffer *vb);
// Verex buffer hard ?
IVertexBufferHardGL *_VBHard;
IVertexBufferGL *_VBHard;
CDriverGL3 *_DriverGL;
// From IVBDrvInfos
@ -250,7 +250,7 @@ public:
}
void setupVertexBuffer(CVertexBuffer &vb);
void setupVertexBufferHard(IVertexBufferHardGL &vb);
void setupVertexBufferHard(IVertexBufferGL &vb);
};
@ -690,7 +690,7 @@ public:
#endif
private:
virtual class IVertexBufferHardGL *createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb);
virtual class IVertexBufferGL *createVertexBufferGL(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb);
friend class CTextureDrvInfosGL3;
friend class CVertexProgamDrvInfosGL3;
@ -1123,31 +1123,19 @@ private:
void disableAllLights();
/// \name VertexBufferHard
/// \name Vertex Buffer
// @{
CPtrSet<IVertexBufferHardGL> _VertexBufferHardSet;
friend class CVertexArrayRange;
friend class CVertexBufferHard;
CPtrSet<IVertexBufferGL> _VertexBufferGLSet;
friend class CVertexBufferGL;
friend class CVBDrvInfosGL3;
// The VertexArrayRange activated.
IVertexArrayRange *_CurrentVertexArrayRange;
// The VertexBufferHardGL activated.
IVertexBufferHardGL *_CurrentVertexBufferHard;
// current setup passed to nglVertexArrayRangeNV()
void *_NVCurrentVARPtr;
uint32 _NVCurrentVARSize;
IVertexBufferGL *_CurrentVertexBufferGL;
bool _SlowUnlockVBHard;
// The AGP VertexArrayRange.
IVertexArrayRange *_AGPVertexArrayRange;
// The VRAM VertexArrayRange.
IVertexArrayRange *_VRAMVertexArrayRange;
void resetVertexArrayRange();
// Handle lost buffers
void updateLostBuffers();
std::list<CVertexBufferGL *> _LostVBList;
// @}
@ -1341,7 +1329,7 @@ protected:
public:
void incrementResetCounter() { ++_ResetCounter; }
bool isWndActive() const { return _WndActive; }
const IVertexBufferHardGL *getCurrentVertexBufferHard() const { return _CurrentVertexBufferHard; }
const IVertexBufferGL *getCurrentVertexBufferHard() const { return _CurrentVertexBufferGL; }
// For debug : dump list of mapped buffers
#ifdef NL_DEBUG
void dumpMappedBuffers();

@ -353,8 +353,8 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
}*/
// NOTE: A vertex buffer MUST be enabled before calling setupMaterial!
nlassert(_CurrentVertexBufferHard);
uint16 vertexFormat = _CurrentVertexBufferHard->VB->getVertexFormat();
nlassert(_CurrentVertexBufferGL);
uint16 vertexFormat = _CurrentVertexBufferGL->VB->getVertexFormat();
// Activate the textures.
// Do not do it for Lightmap and per pixel lighting , because done in multipass in a very special fashion.

@ -576,7 +576,7 @@ void CDriverGL3::setUniformFog(TProgram program, uint index)
void CDriverGL3::generateShaderDesc(CShaderDesc &desc, CMaterial &mat)
{
desc.setShaderType(mat.getShader());
uint16 vbFlags = _CurrentVertexBufferHard->VB->getVertexFormat();
uint16 vbFlags = _CurrentVertexBufferGL->VB->getVertexFormat();
for (sint i = 0; i < IDRV_MAT_MAXTEXTURES; ++i)
{
if (m_VPBuiltinCurrent.TexGenMode[i] >= 0)

@ -36,7 +36,7 @@ bool CDriverGL3::renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines)
if (!setupMaterial(mat) || _LastIB._Values == NULL)
return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives.
//==============================
// start multipass.
@ -83,7 +83,7 @@ bool CDriverGL3::renderTriangles(CMaterial& mat, uint32 firstIndex, uint32 ntris
if (!setupMaterial(mat) || _LastIB._Values == NULL)
return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives.
//==============================
@ -132,7 +132,7 @@ bool CDriverGL3::renderSimpleTriangles(uint32 firstTri, uint32 ntris)
nlassert(ntris>0);
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// Don't setup any material here.
// render primitives.
@ -167,7 +167,7 @@ bool CDriverGL3::renderRawPoints(CMaterial& mat, uint32 startIndex, uint32 numPo
if (!setupMaterial(mat))
return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives.
//==============================
// start multipass.
@ -205,7 +205,7 @@ bool CDriverGL3::renderRawLines(CMaterial& mat, uint32 startIndex, uint32 numLin
if (!setupMaterial(mat))
return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives.
//==============================
// start multipass.
@ -243,7 +243,7 @@ bool CDriverGL3::renderRawTriangles(CMaterial& mat, uint32 startIndex, uint32 nu
if (!setupMaterial(mat))
return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives.
//==============================
// start multipass.
@ -284,7 +284,7 @@ bool CDriverGL3::renderRawQuads(CMaterial& mat, uint32 startIndex, uint32 numQua
if (!setupMaterial(mat))
return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
const uint32 QUAD_BATCH_SIZE = 2048;
static GLshort defaultIndices[QUAD_BATCH_SIZE * 6];

@ -76,7 +76,7 @@ CVBDrvInfosGL3::~CVBDrvInfosGL3()
if (_VBHard)
{
_VBHard->disable();
_DriverGL->_VertexBufferHardSet.erase(_VBHard);
_DriverGL->_VertexBufferGLSet.erase(_VBHard);
}
_VBHard = NULL;
@ -131,7 +131,7 @@ bool CDriverGL3::setupVertexBuffer(CVertexBuffer& VB)
const uint size = VB.capacity()*VB.getVertexSize();
// Vertex buffer hard
info->_VBHard = createVertexBufferHard(size, VB.capacity(), preferred, &VB);
info->_VBHard = createVertexBufferGL(size, VB.capacity(), preferred, &VB);
// Upload the data
VB.setLocation ((CVertexBuffer::TLocation)preferred);
@ -173,8 +173,8 @@ bool CDriverGL3::activeVertexBuffer(CVertexBuffer& VB)
if (info->_VBHard == NULL)
{
// Disable the current vertexBufferHard if setuped.
if (_CurrentVertexBufferHard)
_CurrentVertexBufferHard->disable();
if (_CurrentVertexBufferGL)
_CurrentVertexBufferGL->disable();
}
else
{
@ -209,7 +209,7 @@ bool CDriverGL3::activeIndexBuffer(CIndexBuffer& IB)
bool CDriverGL3::supportVolatileVertexBuffer() const
{
H_AUTO_OGL(CDriverGL3_supportVolatileVertexBuffer)
return false;
return false; // TODO VERTEXBUFFER PINNED
}
@ -231,50 +231,59 @@ uint CDriverGL3::getMaxVerticesByVertexBufferHard() const
// ***************************************************************************
IVertexBufferHardGL *CDriverGL3::createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb)
IVertexBufferGL *CDriverGL3::createVertexBufferGL(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb)
{
H_AUTO_OGL(CDriverGL3_createVertexBufferHard)
// choose the VertexArrayRange of good type
IVertexArrayRange *vertexArrayRange= NULL;
switch(vbType)
H_AUTO_OGL(CDriverGL3_createVertexBufferGL)
// Create a Vertex Buffer
GLuint vertexBufferID;
nglGenBuffers(1, &vertexBufferID);
_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
switch (vbType)
{
case CVertexBuffer::AGPPreferred:
vertexArrayRange= _AGPVertexArrayRange;
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break;
case CVertexBuffer::StaticPreferred:
if (getStaticMemoryToVRAM())
vertexArrayRange= _VRAMVertexArrayRange;
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
else
vertexArrayRange= _AGPVertexArrayRange;
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break;
default:
nlassert(0);
break;
}
CVertexBufferGL *newVbHard = new CVertexBufferGL(this, vb);
newVbHard->initGL(vertexBufferID, vbType);
_DriverGLStates.forceBindARBVertexBuffer(0);
return _VertexBufferGLSet.insert(newVbHard);
}
// If this one at least created (an extension support it).
if (!vertexArrayRange)
return NULL;
else
{
// Create a CVertexBufferHardGL
IVertexBufferHardGL *vbHard = NULL;
// let the VAR create the vbhard.
vbHard= vertexArrayRange->createVBHardGL(size, vb);
// if fails
if (!vbHard)
// ********************************************************************
void CDriverGL3::updateLostBuffers()
{
H_AUTO_OGL(CDriverGL3_updateLostBuffers)
// Put all vb that have been lost in the NotResident state so that they will be recomputed
// We do this only if the app is active, because if vb were lost, it is likely that there are no resources available.
if (isWndActive())
{
return NULL;
}
else
for (std::list<CVertexBufferGL *>::iterator it = _LostVBList.begin(); it != _LostVBList.end(); ++it)
{
// insert in list.
return _VertexBufferHardSet.insert(vbHard);
nlassert((*it)->VertexObjectId);
GLuint id = (GLuint) (*it)->VertexObjectId;
nlassert(nglIsBuffer(id));
nglDeleteBuffers(1, &id);
(*it)->VertexObjectId = 0;
(*it)->VB->setLocation(CVertexBuffer::NotResident);
}
_LostVBList.clear();
}
}
// ********************************************************************
// ***************************************************************************
const uint CDriverGL3::NumCoordinatesType[CVertexBuffer::NumType]=
{
1, // Double1
@ -471,35 +480,12 @@ void CVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb)
}
}
// ***************************************************************************
void CDriverGL3::resetVertexArrayRange()
{
H_AUTO_OGL(CDriverGL3_resetVertexArrayRange)
if (_CurrentVertexBufferHard)
{
// Must ensure it has ended any drawing
_CurrentVertexBufferHard->lock();
_CurrentVertexBufferHard->unlock();
// disable it
_CurrentVertexBufferHard->disable();
}
// Clear any VertexBufferHard created.
_VertexBufferHardSet.clear();
}
// ***************************************************************************
bool CDriverGL3::initVertexBufferHard(uint agpMem, uint vramMem)
{
H_AUTO_OGL(CDriverGL3_initVertexBufferHard)
// must be supported
if (!_AGPVertexArrayRange || !_VRAMVertexArrayRange)
return false;
// First, reset any VBHard created.
resetVertexArrayRange();
_SlowUnlockVBHard = true;
return true;
}

@ -31,185 +31,69 @@ namespace NLDRIVERGL3 {
#endif
// ***************************************************************************
IVertexArrayRange::IVertexArrayRange(CDriverGL3 *drv)
IVertexBufferGL::IVertexBufferGL(CDriverGL3 *drv, CVertexBuffer *vb) : VB (vb)
{
H_AUTO_OGL(IVertexArrayRange_IVertexArrayRange)
_Driver= drv;
H_AUTO_OGL(IVertexBufferGL_IVertexBufferGL)
m_Driver= drv;
m_Invalid = false;
}
// ***************************************************************************
IVertexArrayRange::~IVertexArrayRange()
IVertexBufferGL::~IVertexBufferGL()
{
H_AUTO_OGL(IVertexArrayRange_IVertexArrayRangeDtor)
H_AUTO_OGL(IVertexBufferGL_IVertexBufferGLDtor)
}
// ***************************************************************************
IVertexBufferHardGL::IVertexBufferHardGL(CDriverGL3 *drv, CVertexBuffer *vb) : VB (vb)
CVertexBufferGL::CVertexBufferGL(CDriverGL3 *drv, CVertexBuffer *vb)
: IVertexBufferGL(drv, vb),
m_VertexPtr(NULL),
VertexObjectId(0)
{
H_AUTO_OGL(IVertexBufferHardGL_IVertexBufferHardGL)
_Driver= drv;
_Invalid = false;
}
// ***************************************************************************
IVertexBufferHardGL::~IVertexBufferHardGL()
{
H_AUTO_OGL(IVertexBufferHardGL_IVertexBufferHardGLDtor)
}
// ***************************************************************************
// CVertexArrayRangeARB
// ***************************************************************************
// ***************************************************************************
CVertexArrayRange::CVertexArrayRange(CDriverGL3 *drv) : IVertexArrayRange(drv),
_VBType(CVertexBuffer::AGPPreferred)
{
H_AUTO_OGL(CVertexArrayRangeARB_CVertexArrayRangeARB)
}
// ***************************************************************************
IVertexBufferHardGL *CVertexArrayRange::createVBHardGL(uint size, CVertexBuffer *vb)
{
H_AUTO_OGL(CVertexArrayRange_createVBHardGL)
// create a ARB VBHard
GLuint vertexBufferID;
nglGenBuffers(1, &vertexBufferID);
_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
switch(_VBType)
{
case CVertexBuffer::AGPPreferred:
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break;
case CVertexBuffer::StaticPreferred:
if (_Driver->getStaticMemoryToVRAM())
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
else
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break;
default:
nlassert(0);
break;
}
CVertexBufferHard *newVbHard= new CVertexBufferHard(_Driver, vb);
newVbHard->initGL(vertexBufferID, this, _VBType);
// _Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
return newVbHard;
}
// ***************************************************************************
void CVertexArrayRange::enable()
{
H_AUTO_OGL(CVertexArrayRangeARB_enable)
if (_Driver->_CurrentVertexArrayRange != this)
{
_Driver->_CurrentVertexArrayRange= this;
}
}
// ***************************************************************************
void CVertexArrayRange::disable()
{
H_AUTO_OGL(CVertexArrayRangeARB_disbale)
if (_Driver->_CurrentVertexBufferHard != NULL)
{
_Driver->_CurrentVertexBufferHard= NULL;
}
H_AUTO_OGL(CVertexBufferGLARB_CVertexBufferGLARB)
}
// ***************************************************************************
void CVertexArrayRange::updateLostBuffers()
CVertexBufferGL::~CVertexBufferGL()
{
H_AUTO_OGL(CVertexArrayRangeARB_updateLostBuffers)
// Put all vb that have been lost in the NotResident state so that they will be recomputed
// We do this only if the app is active, because if vb were lost, it is likely that there are no resources available.
nlassert(_Driver);
if (_Driver->isWndActive())
H_AUTO_OGL(CVertexBufferGLARB_CVertexBufferGLARBDtor)
if (m_Driver && VertexObjectId)
{
for (std::list<CVertexBufferHard *>::iterator it = _LostVBList.begin(); it != _LostVBList.end(); ++it)
if (m_Driver->_DriverGLStates.getCurrBoundARBVertexBuffer() == VertexObjectId)
{
nlassert((*it)->_VertexObjectId);
GLuint id = (GLuint) (*it)->_VertexObjectId;
nlassert(nglIsBuffer(id));
nglDeleteBuffers(1, &id);
(*it)->_VertexObjectId = 0;
(*it)->VB->setLocation(CVertexBuffer::NotResident);
m_Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
}
_LostVBList.clear();
}
}
// ***************************************************************************
// CVertexBufferHardARB
// ***************************************************************************
// ***************************************************************************
CVertexBufferHard::CVertexBufferHard(CDriverGL3 *drv, CVertexBuffer *vb) : IVertexBufferHardGL(drv, vb),
_VertexPtr(NULL),
_VertexObjectId(0)
{
H_AUTO_OGL(CVertexBufferHardARB_CVertexBufferHardARB)
_VertexArrayRange = NULL;
#ifdef NL_DEBUG
_Unmapping = false;
#endif
}
// ***************************************************************************
CVertexBufferHard::~CVertexBufferHard()
{
H_AUTO_OGL(CVertexBufferHardARB_CVertexBufferHardARBDtor)
if (_Driver && _VertexObjectId)
{
if (_Driver->_DriverGLStates.getCurrBoundARBVertexBuffer() == _VertexObjectId)
{
// _Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
}
}
if (_VertexObjectId)
if (VertexObjectId)
{
GLuint id = (GLuint) _VertexObjectId;
GLuint id = (GLuint) VertexObjectId;
nlassert(nglIsBuffer(id));
nglDeleteBuffers(1, &id);
}
if (_VertexArrayRange)
if (m_Driver)
{
if (_Invalid)
if (m_Invalid)
{
if (VB->getLocation() != CVertexBuffer::NotResident)
{
// when the vb is put in tthe NotResident state, it is removed from that list
_VertexArrayRange->_LostVBList.erase(_IteratorInLostVBList);
}
m_Driver->_LostVBList.erase(m_IteratorInLostVBList);
}
}
#ifdef NL_DEBUG
if (_VertexPtr)
{
_VertexArrayRange->_MappedVBList.erase(_IteratorInMappedVBList);
}
#endif
}
// ***************************************************************************
void *CVertexBufferHard::lock()
void *CVertexBufferGL::lock()
{
H_AUTO_OGL(CVertexBufferHardARB_lock);
H_AUTO_OGL(CVertexBufferGLARB_lock);
if (_VertexPtr) return _VertexPtr; // already locked
if (_Invalid)
if (m_VertexPtr) return m_VertexPtr; // already locked
if (m_Invalid)
{
if (VB->getLocation() != CVertexBuffer::NotResident)
{
nlassert(!_DummyVB.empty());
return &_DummyVB[0];
nlassert(!m_DummyVB.empty());
return &m_DummyVB[0];
}
// recreate a vb
GLuint vertexBufferID;
@ -219,18 +103,18 @@ void *CVertexBufferHard::lock()
if (glGetError() != GL_NO_ERROR)
{
_Driver->incrementResetCounter();
return &_DummyVB[0];
m_Driver->incrementResetCounter();
return &m_DummyVB[0];
}
const uint size = VB->getNumVertices() * VB->getVertexSize();
_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
switch(_MemType)
m_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
switch(m_MemType)
{
case CVertexBuffer::AGPPreferred:
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break;
case CVertexBuffer::StaticPreferred:
if (_Driver->getStaticMemoryToVRAM())
if (m_Driver->getStaticMemoryToVRAM())
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
else
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
@ -241,63 +125,63 @@ void *CVertexBufferHard::lock()
}
if (glGetError() != GL_NO_ERROR)
{
_Driver->incrementResetCounter();
m_Driver->incrementResetCounter();
nglDeleteBuffers(1, &vertexBufferID);
return &_DummyVB[0];;
return &m_DummyVB[0];;
}
_VertexObjectId = vertexBufferID;
NLMISC::contReset(_DummyVB); // free vector memory for real
nlassert(_VertexObjectId);
_Invalid = false;
_VertexArrayRange->_LostVBList.erase(_IteratorInLostVBList);
VertexObjectId = vertexBufferID;
NLMISC::contReset(m_DummyVB); // free vector memory for real
nlassert(VertexObjectId);
m_Invalid = false;
m_Driver->_LostVBList.erase(m_IteratorInLostVBList);
// continue to standard mapping code below ..
}
TTicks beforeLock = 0;
if (_Driver->_VBHardProfiling)
if (m_Driver->_VBHardProfiling)
{
beforeLock= CTime::getPerformanceTime();
}
_Driver->_DriverGLStates.bindARBVertexBuffer(_VertexObjectId);
m_Driver->_DriverGLStates.bindARBVertexBuffer(VertexObjectId);
_VertexPtr = nglMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (!_VertexPtr)
m_VertexPtr = nglMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (!m_VertexPtr)
{
nglUnmapBuffer(GL_ARRAY_BUFFER);
nlassert(nglIsBuffer((GLuint) _VertexObjectId));
nlassert(nglIsBuffer((GLuint) VertexObjectId));
invalidate();
return &_DummyVB[0];
return &m_DummyVB[0];
}
#ifdef NL_DEBUG
_VertexArrayRange->_MappedVBList.push_front(this);
_IteratorInMappedVBList = _VertexArrayRange->_MappedVBList.begin();
#endif
// _Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
m_Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
// Lock Profile?
if (_Driver->_VBHardProfiling)
if (m_Driver->_VBHardProfiling)
{
TTicks afterLock;
afterLock= CTime::getPerformanceTime();
_Driver->appendVBHardLockProfile(afterLock-beforeLock, VB);
m_Driver->appendVBHardLockProfile(afterLock-beforeLock, VB);
}
return _VertexPtr;
return m_VertexPtr;
}
// ***************************************************************************
void CVertexBufferHard::unlock()
void CVertexBufferGL::unlock()
{
H_AUTO_OGL(CVertexBufferHardARB_unlock);
H_AUTO_OGL(CVertexBufferGLARB_unlock);
_VertexPtr = NULL;
if (_Invalid) return;
if (!_VertexObjectId) return;
m_VertexPtr = NULL;
if (m_Invalid) return;
if (!VertexObjectId) return;
TTicks beforeLock = 0;
if (_Driver->_VBHardProfiling)
if (m_Driver->_VBHardProfiling)
{
beforeLock= CTime::getPerformanceTime();
}
_Driver->_DriverGLStates.bindARBVertexBuffer(_VertexObjectId);
m_Driver->_DriverGLStates.bindARBVertexBuffer(VertexObjectId);
// double start = CTime::ticksToSecond(CTime::getPerformanceTime());
#ifdef NL_DEBUG
_Unmapping = true;
@ -310,16 +194,16 @@ void CVertexBufferHard::unlock()
_Unmapping = false;
#endif
// Lock Profile?
if (_Driver->_VBHardProfiling)
if (m_Driver->_VBHardProfiling)
{
TTicks afterLock;
afterLock= CTime::getPerformanceTime();
_Driver->appendVBHardLockProfile(afterLock-beforeLock, VB);
m_Driver->appendVBHardLockProfile(afterLock-beforeLock, VB);
}
#ifdef NL_DEBUG
_VertexArrayRange->_MappedVBList.erase(_IteratorInMappedVBList);
#endif
// _Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
m_Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
if (!unmapOk)
{
invalidate();
@ -329,95 +213,80 @@ void CVertexBufferHard::unlock()
}
// ***************************************************************************
void *CVertexBufferHard::getPointer()
void *CVertexBufferGL::getPointer()
{
H_AUTO_OGL(CVertexBufferHardARB_getPointer)
return _VertexPtr;
H_AUTO_OGL(CVertexBufferGLARB_getPointer)
return m_VertexPtr;
}
// ***************************************************************************
void CVertexBufferHard::unlock(uint /* startVert */,uint /* endVert */)
void CVertexBufferGL::unlock(uint /* startVert */,uint /* endVert */)
{
H_AUTO_OGL(CVertexBufferHardARB_unlock)
H_AUTO_OGL(CVertexBufferGLARB_unlock)
unlock(); // can't do a lock on a range of the vb..
}
// ***************************************************************************
void CVertexBufferHard::enable()
void CVertexBufferGL::enable()
{
H_AUTO_OGL(CVertexBufferHardARB_enable)
if (_Driver->_CurrentVertexBufferHard != this)
H_AUTO_OGL(CVertexBufferGLARB_enable)
if (m_Driver->_CurrentVertexBufferGL != this)
{
/* nlassert(_VertexArrayRange);
_VertexArrayRange->enable(); */
_Driver->_CurrentVertexBufferHard= this;
m_Driver->_CurrentVertexBufferGL= this;
}
}
// ***************************************************************************
void CVertexBufferHard::disable()
void CVertexBufferGL::disable()
{
H_AUTO_OGL(CVertexBufferHardARB_disable)
if (_Driver->_CurrentVertexBufferHard != NULL)
H_AUTO_OGL(CVertexBufferGLARB_disable)
if (m_Driver->_CurrentVertexBufferGL != NULL)
{
/* nlassert(_VertexArrayRange);
_VertexArrayRange->disable(); */
_Driver->_CurrentVertexBufferHard= NULL;
m_Driver->_CurrentVertexBufferGL= NULL;
}
}
// ***************************************************************************
void CVertexBufferHard::initGL(uint vertexObjectID, CVertexArrayRange *var, CVertexBuffer::TPreferredMemory memType)
void CVertexBufferGL::initGL(uint vertexObjectID, CVertexBuffer::TPreferredMemory memType)
{
H_AUTO_OGL(CVertexBufferHardARB_initGL)
_VertexObjectId = vertexObjectID;
_MemType = memType;
_VertexArrayRange = var;
H_AUTO_OGL(CVertexBufferGLARB_initGL)
VertexObjectId = vertexObjectID;
m_MemType = memType;
}
// ***************************************************************************
void CVertexBufferHard::lockHintStatic(bool /* staticLock */)
void CVertexBufferGL::lockHintStatic(bool /* staticLock */)
{
H_AUTO_OGL(CVertexBufferHardARB_lockHintStatic)
H_AUTO_OGL(CVertexBufferGLARB_lockHintStatic)
// no op.
}
// ***************************************************************************
void CVertexBufferHard::setupVBInfos(CVertexBufferInfo &vb)
void CVertexBufferGL::setupVBInfos(CVertexBufferInfo &vb)
{
H_AUTO_OGL(CVertexBufferHardARB_setupVBInfos)
vb.VertexObjectId = _VertexObjectId;
H_AUTO_OGL(CVertexBufferGLARB_setupVBInfos)
vb.VertexObjectId = VertexObjectId;
}
// ***************************************************************************
void CVertexBufferHard::invalidate()
void CVertexBufferGL::invalidate()
{
H_AUTO_OGL(CVertexBufferHardARB_invalidate)
nlassert(!_Invalid);
H_AUTO_OGL(CVertexBufferGLARB_invalidate)
nlassert(!m_Invalid);
// Buffer is lost (maybe there was a alt-tab or fullscrren / windowed change)
// Buffer is deleted at end of frame only
_Invalid = true;
_Driver->incrementResetCounter();
_DummyVB.resize(VB->getNumVertices() * VB->getVertexSize(), 0);
m_Invalid = true;
m_Driver->incrementResetCounter();
m_DummyVB.resize(VB->getNumVertices() * VB->getVertexSize(), 0);
// insert in lost vb list
_VertexArrayRange->_LostVBList.push_front(this);
_IteratorInLostVBList = _VertexArrayRange->_LostVBList.begin();
m_Driver->_LostVBList.push_front(this);
m_IteratorInLostVBList = m_Driver->_LostVBList.begin();
}
// ***************************************************************************
#ifdef NL_DEBUG
void CVertexArrayRange::dumpMappedBuffers()
{
nlwarning("*****************************************************");
nlwarning("Mapped buffers :");
for (std::list<CVertexBufferHard *>::iterator it = _MappedVBList.begin(); it != _MappedVBList.end(); ++it)
{
CVertexBufferHard &vbarb = **it;
nlwarning("Buffer id = %u, size = %u, address = %p", vbarb._VertexObjectId, vbarb.VB->getVertexSize() * vbarb.VB->getNumVertices(), vbarb.getPointer());
}
}
#endif
#ifdef NL_STATIC
} // NLDRIVERGL3
#endif

@ -19,7 +19,6 @@
#include "nel/misc/types_nl.h"
namespace NL3D {
#ifdef NL_STATIC
@ -27,110 +26,40 @@ namespace NLDRIVERGL3 {
#endif
class CDriverGL;
class IVertexBufferHardGL;
class IVertexBufferGL;
class CVertexBufferInfo;
class CVertexBufferHard;
class CVertexBufferGL;
// ***************************************************************************
/** Interface to a Big block of video memory
*/
class IVertexArrayRange
class IVertexBufferGL
{
public:
IVertexArrayRange(CDriverGL3 *drv);
virtual ~IVertexArrayRange();
/// create a IVertexBufferHardGL
virtual IVertexBufferHardGL *createVBHardGL(uint size, CVertexBuffer *vb) =0;
// Check & invalidate lost buffers. Default assume they can't be lost
virtual void updateLostBuffers() {}
// Get driver
CDriverGL3* getDriver() const { return _Driver; }
// tmp, for debug
#ifdef NL_DEBUG
virtual void dumpMappedBuffers() {}
#endif
protected:
CDriverGL3 *_Driver;
};
class IVertexBufferHardGL
{
public:
IVertexBufferHardGL(CDriverGL3 *drv, CVertexBuffer *vb);
virtual ~IVertexBufferHardGL();
IVertexBufferGL(CDriverGL3 *drv, CVertexBuffer *vb);
virtual ~IVertexBufferGL();
virtual void *lock() = 0;
virtual void unlock() = 0;
virtual void unlock(uint start, uint end) = 0;
virtual void *getPointer() = 0;
virtual void enable() =0;
virtual void disable() =0;
virtual void enable() = 0;
virtual void disable() = 0;
virtual void setupVBInfos(CVertexBufferInfo &vb) = 0;
// test if buffer content is invalid. If so, no rendering should occurs (rendering should silently fail)
bool isInvalid() { return _Invalid; }
inline bool isInvalid() { return m_Invalid; }
public:
CVertexBuffer *VB;
protected:
CDriverGL3 *_Driver;
bool _Invalid;
};
// ***************************************************************************
// ***************************************************************************
// ARB_vertex_buffer_object implementation
// ***************************************************************************
// ***************************************************************************
class CVertexArrayRange : public IVertexArrayRange
{
public:
CVertexArrayRange(CDriverGL3 *drv);
virtual IVertexBufferHardGL *createVBHardGL(uint size, CVertexBuffer *vb);
// Those methods read/write in _Driver->_CurrentVertexArrayRange.
/** active this VertexArrayRange as the current vertex array range used. no-op if already setup.
* NB: no-op for ARB, but ensure correct _Driver->_CurrentVertexArrayRange value.
*/
void enable();
/** disable this VertexArrayRange. _Driver->_CurrentVertexArrayRange= NULL;
* NB: no-op for ARB, but ensure correct _Driver->_CurrentVertexArrayRange value.
*/
void disable();
// check & invalidate lost buffers
void updateLostBuffers();
//
#ifdef NL_DEBUG
virtual void dumpMappedBuffers();
#endif
// *************************
private:
CVertexBuffer::TPreferredMemory _VBType;
// for use by CVertexBufferHardARB
public:
std::list<CVertexBufferHard*> _LostVBList;
#ifdef NL_DEBUG
std::list<CVertexBufferHard*> _MappedVBList;
#endif
CDriverGL3 *m_Driver;
bool m_Invalid;
};
/** vb hard using the ARB_vertex_buffer_object extension. Buffer are kept separate rather than managed in a heap
*/
class CVertexBufferHard : public IVertexBufferHardGL
/* GL Core vertex buffer. */
class CVertexBufferGL : public IVertexBufferGL
{
public:
CVertexBufferHard(CDriverGL3 *drv, CVertexBuffer *vb);
virtual ~CVertexBufferHard();
CVertexBufferGL(CDriverGL3 *drv, CVertexBuffer *vb);
virtual ~CVertexBufferGL();
/// \name Implementation
// @{
@ -144,39 +73,26 @@ public:
virtual void setupVBInfos(CVertexBufferInfo &vb);
// @}
/** setup ptrs allocated by createVBHard()
*/
void initGL(uint vertexObjectID, CVertexArrayRange *var, CVertexBuffer::TPreferredMemory memType);
/// Setup ptrs allocated by createVBHard()
void initGL(uint vertexObjectID, CVertexBuffer::TPreferredMemory memType);
public:
/// Get Handle of the ARB buffer.
uint getARBVertexObjectId() const { return VertexObjectId;}
/// get Handle of the ARB buffer.
uint getARBVertexObjectId() const { return _VertexObjectId;}
// Invalidate the buffer (when it is lost, or when a lock fails)
/// Invalidate the buffer (when it is lost, or when a lock fails)
void invalidate();
// tmp
void checkMappedVBList();
// *************************
private:
CVertexArrayRange *_VertexArrayRange;
CVertexBuffer::TPreferredMemory _MemType;
void *_VertexPtr; // pointer on current datas. Null if not locked
CVertexBuffer::TPreferredMemory m_MemType;
void *m_VertexPtr; // pointer on current datas. Null if not locked
// if buffer has been invalidated, returns a dummy memory block and silently fails rendering
std::vector<uint8> _DummyVB;
std::vector<uint8> m_DummyVB;
// for use by CVertexArrayRange
std::list<CVertexBufferHard*>::iterator _IteratorInLostVBList;
std::list<CVertexBufferGL*>::iterator m_IteratorInLostVBList;
public:
uint _VertexObjectId;
// tmp for debug
#ifdef NL_DEBUG
bool _Unmapping;
std::list<CVertexBufferHard*>::iterator _IteratorInMappedVBList;
#endif
uint VertexObjectId;
};
#ifdef NL_STATIC
@ -185,7 +101,6 @@ public:
} // NL3D
#endif // NL_DRIVER_OPENGL_VERTEX_BUFFER_H
/* End of driver_opengl_vertex_buffer.h */

@ -379,7 +379,7 @@ void CDriverGL3::touchLightVP(int i)
void CDriverGL3::touchVertexFormatVP()
{
H_AUTO_OGL(CDriverGL3_touchLightVP)
uint16 format = _CurrentVertexBufferHard->VB->getVertexFormat();
uint16 format = _CurrentVertexBufferGL->VB->getVertexFormat();
if (m_VPBuiltinCurrent.VertexFormat != format)
{
m_VPBuiltinCurrent.VertexFormat = format;

Loading…
Cancel
Save