Merge remote branch 'shyotl/V2Renderer'

Conflicts:
	indra/cmake/00-Common.cmake
This commit is contained in:
siana
2011-03-20 04:55:56 +01:00
90 changed files with 2917 additions and 1147 deletions

View File

@@ -59,11 +59,13 @@
BOOL gDebugGL = FALSE;
BOOL gClothRipple = FALSE;
BOOL gNoRender = FALSE;
BOOL gGLActive = FALSE;
LLMatrix4 gGLObliqueProjectionInverse;
#define LL_GL_NAME_POOLING 0
LLGLNamePool::pool_list_t LLGLNamePool::sInstances;
std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
// ATI prototypes

View File

@@ -361,6 +361,35 @@ protected:
virtual void releaseName(GLuint name) = 0;
};
/*
Interface for objects that need periodic GL updates applied to them.
Used to synchronize GL updates with GL thread.
*/
class LLGLUpdate
{
public:
static std::list<LLGLUpdate*> sGLQ;
BOOL mInQ;
LLGLUpdate()
: mInQ(FALSE)
{
}
virtual ~LLGLUpdate()
{
if (mInQ)
{
std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this);
if (iter != sGLQ.end())
{
sGLQ.erase(iter);
}
}
}
virtual void updateGL() = 0;
};
extern LLMatrix4 gGLObliqueProjectionInverse;
#include "llglstates.h"
@@ -379,4 +408,6 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
extern BOOL gClothRipple;
extern BOOL gNoRender;
extern BOOL gGLActive;
#endif // LL_LLGL_H

View File

@@ -352,8 +352,21 @@ void LLImageGL::restoreGL()
}
}
//static
void LLImageGL::dirtyTexOptions()
{
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
iter != sImageList.end(); iter++)
{
LLImageGL* glimage = *iter;
glimage->mTexOptionsDirty = true;
stop_glerror();
}
}
//----------------------------------------------------------------------------
//for server side use only.
//static
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
{
@@ -361,12 +374,14 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
return TRUE;
}
//for server side use only.
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps)
{
dest = new LLImageGL(width, height, components, usemipmaps);
return TRUE;
}
//for server side use only.
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps)
{
dest = new LLImageGL(imageraw, usemipmaps);

View File

@@ -68,6 +68,7 @@ public:
// Save off / restore GL textures
static void destroyGL(BOOL save_state = TRUE);
static void restoreGL();
static void dirtyTexOptions();
// Sometimes called externally for textures not using LLImageGL (should go away...)
static S32 updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) ;
@@ -137,6 +138,7 @@ public:
BOOL getBoundRecently() const;
BOOL isJustBound() const;
LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
LLGLenum getFormatType() const { return mFormatType; }
BOOL getHasGLTexture() const { return mTexName != 0; }
LLGLuint getTexName() const { return mTexName; }

View File

@@ -56,6 +56,7 @@ U32 LLVertexBuffer::sSetCount = 0;
S32 LLVertexBuffer::sCount = 0;
S32 LLVertexBuffer::sGLCount = 0;
S32 LLVertexBuffer::sMappedCount = 0;
BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
BOOL LLVertexBuffer::sEnableVBOs = TRUE;
U32 LLVertexBuffer::sGLRenderBuffer = 0;
U32 LLVertexBuffer::sGLRenderIndices = 0;
@@ -287,9 +288,21 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
}
//static
void LLVertexBuffer::initClass(bool use_vbo)
void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
{
sEnableVBOs = use_vbo;
sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ;
if(sEnableVBOs)
{
//llassert_always(glBindBufferARB) ; //double check the extention for VBO is loaded.
llinfos << "VBO is enabled." << llendl ;
}
else
{
llinfos << "VBO is disabled." << llendl ;
}
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
LLGLNamePool::registerPool(&sDynamicVBOPool);
LLGLNamePool::registerPool(&sDynamicIBOPool);
LLGLNamePool::registerPool(&sStreamVBOPool);
@@ -346,7 +359,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mGLBuffer(0),
mGLIndices(0),
mMappedData(NULL),
mMappedIndexData(NULL), mLocked(FALSE),
mMappedIndexData(NULL),
mVertexLocked(FALSE),
mIndexLocked(FALSE),
mFinal(FALSE),
mFilthy(FALSE),
mEmpty(TRUE),
@@ -544,6 +559,8 @@ void LLVertexBuffer::destroyGLBuffer()
{
if (useVBOs())
{
freeClientBuffer() ;
if (mMappedData || mMappedIndexData)
{
llerrs << "Vertex buffer destroyed while mapped!" << llendl;
@@ -571,6 +588,8 @@ void LLVertexBuffer::destroyGLIndices()
{
if (useVBOs())
{
freeClientBuffer() ;
if (mMappedData || mMappedIndexData)
{
llerrs << "Vertex buffer destroyed while mapped." << llendl;
@@ -768,6 +787,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
if (mResized && useVBOs())
{
freeClientBuffer() ;
setBuffer(0);
}
}
@@ -782,104 +802,228 @@ BOOL LLVertexBuffer::useVBOs() const
}
//----------------------------------------------------------------------------
void LLVertexBuffer::freeClientBuffer()
{
if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
{
delete[] mMappedData ;
delete[] mMappedIndexData ;
mMappedData = NULL ;
mMappedIndexData = NULL ;
}
}
void LLVertexBuffer::allocateClientVertexBuffer()
{
if(!mMappedData)
{
U32 size = getSize() ;
mMappedData = new U8[size];
memset((void*)mMappedData, 0, size);
}
}
void LLVertexBuffer::allocateClientIndexBuffer()
{
if(!mMappedIndexData)
{
U32 size = getIndicesSize();
mMappedIndexData = new U8[size];
memset((void*)mMappedIndexData, 0, size);
}
}
// Map for data access
volatile U8* LLVertexBuffer::mapBuffer(S32 access)
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
{
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
if (mFinal)
{
llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
}
if (!useVBOs() && !mMappedData && !mMappedIndexData)
{
llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl;
}
if (!mLocked && useVBOs())
if (!mVertexLocked && useVBOs())
{
setBuffer(0);
mLocked = TRUE;
stop_glerror();
mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
stop_glerror();
mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
stop_glerror();
{
setBuffer(0, type);
mVertexLocked = TRUE;
stop_glerror();
if(sDisableVBOMapping)
{
allocateClientVertexBuffer() ;
}
else
{
mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
stop_glerror();
}
if (!mMappedData)
{
//--------------------
//print out more debug info before crash
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
GLint size ;
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
//--------------------
GLint buff;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
if(!sDisableVBOMapping)
{
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
//--------------------
//print out more debug info before crash
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
GLint size ;
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
//--------------------
GLint buff;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
{
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
}
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
}
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
}
if (!mMappedIndexData)
{
GLint buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLIndices)
else
{
llerrs << "Invalid GL index buffer bound: " << buff << llendl;
llerrs << "memory allocation for vertex data failed." << llendl ;
}
llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
}
sMappedCount++;
}
return mMappedData;
}
void LLVertexBuffer::unmapBuffer()
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
{
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
if (mMappedData || mMappedIndexData)
if (mFinal)
{
if (useVBOs() && mLocked)
llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
}
if (!useVBOs() && !mMappedData && !mMappedIndexData)
{
llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
}
if (!mIndexLocked && useVBOs())
{
{
setBuffer(0, TYPE_INDEX);
mIndexLocked = TRUE;
stop_glerror();
if(sDisableVBOMapping)
{
allocateClientIndexBuffer() ;
}
else
{
mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
stop_glerror();
}
if (!mMappedIndexData)
{
if(!sDisableVBOMapping)
{
GLint buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLIndices)
{
llerrs << "Invalid GL index buffer bound: " << buff << llendl;
}
llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
}
else
{
llerrs << "memory allocation for Index data failed. " << llendl ;
}
}
sMappedCount++;
}
return mMappedIndexData ;
}
void LLVertexBuffer::unmapBuffer(S32 type)
{
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
if (!useVBOs())
{
return ; //nothing to unmap
}
bool updated_all = false ;
if (mMappedData && mVertexLocked && type != TYPE_INDEX)
{
updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating
if(sDisableVBOMapping)
{
stop_glerror();
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (void*)mMappedData);
stop_glerror();
}
else
{
stop_glerror();
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
stop_glerror();
mMappedData = NULL;
}
mVertexLocked = FALSE ;
sMappedCount--;
}
if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
{
if(sDisableVBOMapping)
{
stop_glerror();
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (void*)mMappedIndexData);
stop_glerror();
}
else
{
stop_glerror();
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
stop_glerror();
/*if (!sMapped)
{
llerrs << "Redundantly unmapped VBO!" << llendl;
}
sMapped = FALSE;*/
sMappedCount--;
mMappedIndexData = NULL ;
}
if (mUsage == GL_STATIC_DRAW_ARB)
{ //static draw buffers can only be mapped a single time
//throw out client data (we won't be using it again)
mEmpty = TRUE;
mFinal = TRUE;
}
else
{
mEmpty = FALSE;
}
mIndexLocked = FALSE ;
sMappedCount--;
}
mMappedIndexData = NULL;
mMappedData = NULL;
mLocked = FALSE;
if(updated_all)
{
if(mUsage == GL_STATIC_DRAW_ARB)
{
//static draw buffers can only be mapped a single time
//throw out client data (we won't be using it again)
mEmpty = TRUE;
mFinal = TRUE;
if(sDisableVBOMapping)
{
freeClientBuffer() ;
}
}
else
{
mEmpty = FALSE;
}
}
}
@@ -893,15 +1037,16 @@ template <class T,S32 type> struct VertexBufferStrider
strider_t& strider,
S32 index)
{
if (vbo.mapBuffer() == NULL)
{
llwarns << "mapBuffer failed!" << llendl;
return FALSE;
}
if (type == LLVertexBuffer::TYPE_INDEX)
{
S32 stride = sizeof(T);
if (vbo.mapIndexBuffer() == NULL)
{
llwarns << "mapIndexBuffer failed!" << llendl;
return FALSE;
}
strider = (T*)(vbo.getMappedIndices() + index*stride);
strider.setStride(0);
return TRUE;
@@ -909,6 +1054,13 @@ template <class T,S32 type> struct VertexBufferStrider
else if (vbo.hasDataType(type))
{
S32 stride = vbo.getStride();
if (vbo.mapVertexBuffer(type) == NULL)
{
llwarns << "mapVertexBuffer failed!" << llendl;
return FALSE;
}
strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride);
strider.setStride(stride);
return TRUE;
@@ -989,7 +1141,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride)
//----------------------------------------------------------------------------
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
{
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
//set up pointers if the data mask is different ...
@@ -1023,6 +1175,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
sIBOActive = TRUE;
}
BOOL error = FALSE;
if (gDebugGL)
{
GLint buff;
@@ -1085,7 +1238,11 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
}
unmapBuffer();
if (error)
{
llerrs << "LLVertexBuffer::mapBuffer failed" << llendl;
}
unmapBuffer(type);
}
else
{

View File

@@ -88,7 +88,7 @@ public:
static BOOL sUseStreamDraw;
static BOOL sOmitBlank;
static void initClass(bool use_vbo);
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
@@ -147,15 +147,20 @@ protected:
void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices);
virtual BOOL useVBOs() const;
void unmapBuffer();
void unmapBuffer(S32 type);
void freeClientBuffer() ;
void allocateClientVertexBuffer() ;
void allocateClientIndexBuffer() ;
public:
LLVertexBuffer(U32 typemask, S32 usage);
// map for data access
volatile U8* mapBuffer(S32 access = -1);
volatile U8* mapVertexBuffer(S32 type = -1, S32 access = -1);
volatile U8* mapIndexBuffer(S32 access = -1);
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0
// allocate buffer
void allocateBuffer(S32 nverts, S32 nindices, bool create);
virtual void resizeBuffer(S32 newnverts, S32 newnindices);
@@ -178,7 +183,7 @@ public:
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
BOOL isEmpty() const { return mEmpty; }
BOOL isLocked() const { return mLocked; }
BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
S32 getNumVerts() const { return mNumVerts; }
S32 getNumIndices() const { return mNumIndices; }
S32 getRequestedVerts() const { return mRequestedNumVerts; }
@@ -217,13 +222,14 @@ protected:
U32 mGLIndices; // GL IBO handle
volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory
BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory
BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory
BOOL mFinal; // if TRUE, buffer can not be mapped again
BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
S32 mOffsets[TYPE_MAX];
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not
BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
S32 mOffsets[TYPE_MAX];
class DirtyRegion
{
@@ -248,13 +254,14 @@ public:
static std::vector<U32> sDeleteList;
typedef std::list<LLVertexBuffer*> buffer_list_t;
static BOOL sDisableVBOMapping; //disable glMapBufferARB
static BOOL sEnableVBOs;
static BOOL sVBOActive;
static BOOL sIBOActive;
static S32 sTypeOffsets[TYPE_MAX];
static U32 sGLMode[LLRender::NUM_MODES];
static U32 sGLRenderBuffer;
static U32 sGLRenderIndices;
static BOOL sVBOActive;
static BOOL sIBOActive;
static U32 sGLRenderIndices;
static U32 sLastMask;
static U32 sAllocatedBytes;
static U32 sBindCount;