diff options
author | Steven Bennetts <steve@lindenlab.com> | 2007-03-02 21:25:50 +0000 |
---|---|---|
committer | Steven Bennetts <steve@lindenlab.com> | 2007-03-02 21:25:50 +0000 |
commit | 4dabd9c0472deb49573fdafef2fa413e59703f19 (patch) | |
tree | 06c680d6a2047e03838d6548bccd26c7baf9d652 /indra/newview/lldrawpool.cpp | |
parent | d4462963c6ba5db2088723bbedc7b60f1184c594 (diff) |
merge release@58699 beta-1-14-0@58707 -> release
Diffstat (limited to 'indra/newview/lldrawpool.cpp')
-rw-r--r-- | indra/newview/lldrawpool.cpp | 1261 |
1 files changed, 221 insertions, 1040 deletions
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 899d49f380..9ab6c700ab 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -13,7 +13,6 @@ #include "llfasttimer.h" #include "llviewercontrol.h" -#include "llagparray.h" #include "lldrawable.h" #include "lldrawpoolalpha.h" #include "lldrawpoolavatar.h" @@ -24,53 +23,38 @@ #include "lldrawpoolsky.h" #include "lldrawpoolstars.h" #include "lldrawpooltree.h" -#include "lldrawpooltreenew.h" #include "lldrawpoolterrain.h" #include "lldrawpoolwater.h" -#include "lldrawpoolhud.h" #include "llface.h" #include "llviewerobjectlist.h" // For debug listing. -#include "llvotreenew.h" #include "pipeline.h" -#include "llagparray.inl" - -U32 LLDrawPool::sDataSizes[LLDrawPool::DATA_MAX_TYPES] = -{ - 12, // DATA_VERTICES - 8, // DATA_TEX_COORDS0 - 8, // DATA_TEX_COORDS1 - 8, // DATA_TEX_COORDS2 - 8, // DATA_TEX_COORDS3 - 12, // DATA_NORMALS - 4, // DATA_VERTEX_WEIGHTS, - 16, // DATA_CLOTHING_WEIGHTS - 12, // DATA_BINORMALS - 4, // DATA_COLORS -}; - S32 LLDrawPool::sNumDrawPools = 0; + +//============================= +// Draw Pool Implementation +//============================= LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) { LLDrawPool *poolp = NULL; switch (type) { case POOL_SIMPLE: - poolp = new LLDrawPoolSimple(tex0); + poolp = new LLDrawPoolSimple(); break; case POOL_ALPHA: poolp = new LLDrawPoolAlpha(); break; + case POOL_ALPHA_POST_WATER: + poolp = new LLDrawPoolAlphaPostWater(); + break; case POOL_AVATAR: poolp = new LLDrawPoolAvatar(); break; case POOL_TREE: poolp = new LLDrawPoolTree(tex0); break; - case POOL_TREE_NEW: - poolp = new LLDrawPoolTreeNew(tex0); - break; case POOL_TERRAIN: poolp = new LLDrawPoolTerrain(tex0); break; @@ -80,9 +64,6 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) case POOL_STARS: poolp = new LLDrawPoolStars(); break; - case POOL_CLOUDS: - poolp = new LLDrawPoolClouds(); - break; case POOL_WATER: poolp = new LLDrawPoolWater(); break; @@ -90,10 +71,7 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) poolp = new LLDrawPoolGround(); break; case POOL_BUMP: - poolp = new LLDrawPoolBump(tex0); - break; - case POOL_HUD: - poolp = new LLDrawPoolHUD(); + poolp = new LLDrawPoolBump(); break; default: llerrs << "Unknown draw pool type!" << llendl; @@ -104,183 +82,86 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) return poolp; } -LLDrawPool::LLDrawPool(const U32 type, const U32 data_mask_il, const U32 data_mask_nil) +LLDrawPool::LLDrawPool(const U32 type) { - llassert(data_mask_il & DATA_VERTICES_MASK); - S32 i; mType = type; sNumDrawPools++; mId = sNumDrawPools; - - mDataMaskIL = data_mask_il; - mDataMaskNIL = data_mask_nil; - - U32 cur_mask = 0x01; - U32 cur_offset = 0; - for (i = 0; i < DATA_MAX_TYPES; i++) - { - mDataOffsets[i] = cur_offset; - if (cur_mask & mDataMaskIL) - { - cur_offset += sDataSizes[i]; - } - cur_mask <<= 1; - } - - mStride = cur_offset; - - mCleanupUnused = FALSE; + mVertexShaderLevel = 0; mIndicesDrawn = 0; - mRebuildFreq = 128 + rand() % 5; - mRebuildTime = 0; - mGeneration = 1; - mSkippedVertices = 0; - - resetDrawOrders(); - resetVertexData(0); - - if (gGLManager.mHasATIVAO && !gGLManager.mIsRadeon9700) - { - // ATI 8500 doesn't like indices > 15 bit. - mMaxVertices = DEFAULT_MAX_VERTICES/2; - } - else - { - mMaxVertices = DEFAULT_MAX_VERTICES; - } +} - // JC: This must happen last, as setUseAGP reads many of the - // above variables. - mUseAGP = FALSE; - setUseAGP(gPipeline.usingAGP()); +LLDrawPool::~LLDrawPool() +{ - for (i=0; i<NUM_BUCKETS; i++) - { - mFreeListGeomHead[i] = -1; - mFreeListIndHead[i] = -1; - } - mVertexShaderLevel = 0; } -void LLDrawPool::destroy() +LLViewerImage *LLDrawPool::getDebugTexture() { - if (!mReferences.empty()) - { - llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl; - } + return NULL; } - -LLDrawPool::~LLDrawPool() +//virtual +void LLDrawPool::beginRenderPass( S32 pass ) { - destroy(); - - llassert( gPipeline.findPool( getType(), getTexture() ) == NULL ); } -BOOL LLDrawPool::setUseAGP(BOOL use_agp) +//virtual +void LLDrawPool::endRenderPass( S32 pass ) { - BOOL ok = TRUE; - S32 vertex_count = mMemory.count() / mStride; - if (vertex_count > mMaxVertices && use_agp) - { -#ifdef DEBUG_AGP - llwarns << "Allocating " << vertex_count << " vertices in pool type " << getType() << ", disabling AGP!" << llendl -#endif - use_agp = FALSE; - ok = FALSE; - } - - if (mUseAGP != use_agp) - { - mUseAGP = use_agp; - - BOOL ok = TRUE; - ok &= mMemory.setUseAGP(use_agp); - - if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK) - { - ok &= mWeights.setUseAGP(use_agp); - } - if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) - { - ok &= mClothingWeights.setUseAGP(use_agp); - } - - if (!ok) - { - // Disable AGP if any one of these doesn't have AGP, we don't want to try - // mixing AGP and non-agp arrays in a single pool. -#ifdef DEBUG_AGP - llinfos << "Aborting using AGP because set failed on a mem block!" << llendl; -#endif - setUseAGP(FALSE); - ok = FALSE; - } - } - return ok; + glDisableClientState ( GL_TEXTURE_COORD_ARRAY ); + glDisableClientState ( GL_COLOR_ARRAY ); + glDisableClientState ( GL_NORMAL_ARRAY ); } -void LLDrawPool::flushAGP() +U32 LLDrawPool::getTrianglesDrawn() const { - mMemory.flushAGP(); - - if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK) - { - mWeights.flushAGP(); - } - if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) - { - mClothingWeights.flushAGP(); - } + return mIndicesDrawn / 3; } -void LLDrawPool::syncAGP() +void LLDrawPool::resetTrianglesDrawn() { - if (!getVertexCount()) - { - return; - } - setUseAGP(gPipeline.usingAGP()); + mIndicesDrawn = 0; +} - BOOL all_agp_on = TRUE; - mMemory.sync(); - all_agp_on &= mMemory.isAGP(); +void LLDrawPool::addIndicesDrawn(const U32 indices) +{ + mIndicesDrawn += indices; +} - if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK) - { - mWeights.sync(); - all_agp_on &= mWeights.isAGP(); - } +//============================= +// Face Pool Implementation +//============================= +LLFacePool::LLFacePool(const U32 type) +: LLDrawPool(type) +{ + resetDrawOrders(); +} - if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) - { - mClothingWeights.sync(); - all_agp_on &= mClothingWeights.isAGP(); - } +LLFacePool::~LLFacePool() +{ + destroy(); +} - // Since sometimes AGP allocation is done during syncs, we need - // to make sure that if AGP allocation fails, we fallback to non-agp. - if (mUseAGP && !all_agp_on) +void LLFacePool::destroy() +{ + if (!mReferences.empty()) { -#ifdef DEBUG_AGP - llinfos << "setUseAGP false because of AGP sync failure!" << llendl; -#endif - setUseAGP(FALSE); + llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl; } } -void LLDrawPool::dirtyTexture(const LLViewerImage *imagep) +void LLFacePool::dirtyTextures(const std::set<LLViewerImage*>& textures) { } -BOOL LLDrawPool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data) +BOOL LLFacePool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data) { return TRUE; } // static -S32 LLDrawPool::drawLoop(face_array_t& face_list, const U32* index_array) +S32 LLFacePool::drawLoop(face_array_t& face_list) { S32 res = 0; if (!face_list.empty()) @@ -289,19 +170,15 @@ S32 LLDrawPool::drawLoop(face_array_t& face_list, const U32* index_array) iter != face_list.end(); iter++) { LLFace *facep = *iter; - if (facep->mSkipRender) - { - continue; - } - facep->enableLights(); - res += facep->renderIndexed(index_array); + //facep->enableLights(); + res += facep->renderIndexed(); } } return res; } // static -S32 LLDrawPool::drawLoopSetTex(face_array_t& face_list, const U32* index_array, S32 stage) +S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage) { S32 res = 0; if (!face_list.empty()) @@ -310,117 +187,30 @@ S32 LLDrawPool::drawLoopSetTex(face_array_t& face_list, const U32* index_array, iter != face_list.end(); iter++) { LLFace *facep = *iter; - if (facep->mSkipRender) - { - continue; - } facep->bindTexture(stage); facep->enableLights(); - res += facep->renderIndexed(index_array); + res += facep->renderIndexed(); } } return res; } -void LLDrawPool::drawLoop() +void LLFacePool::drawLoop() { - const U32* index_array = getRawIndices(); if (!mDrawFace.empty()) { - mIndicesDrawn += drawLoop(mDrawFace, index_array); + mIndicesDrawn += drawLoop(mDrawFace); } } -BOOL LLDrawPool::getVertexStrider(LLStrider<LLVector3> &vertices, const U32 index) -{ - llassert(mDataMaskIL & LLDrawPool::DATA_VERTICES_MASK); - vertices = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_VERTICES] + index * mStride); - vertices.setStride(mStride); - return TRUE; -} - -BOOL LLDrawPool::getTexCoordStrider(LLStrider<LLVector2> &tex_coords, const U32 index, const U32 pass) -{ - llassert(mDataMaskIL & (LLDrawPool::DATA_TEX_COORDS0_MASK << pass)); - tex_coords = (LLVector2*)(mMemory.getMem() + mDataOffsets[DATA_TEX_COORDS0 + pass] + index * mStride); - tex_coords.setStride(mStride); - return TRUE; -} - - -BOOL LLDrawPool::getVertexWeightStrider(LLStrider<F32> &vertex_weights, const U32 index) -{ - llassert(mDataMaskNIL & LLDrawPool::DATA_VERTEX_WEIGHTS_MASK); - - vertex_weights = &mWeights[index]; - vertex_weights.setStride( 0 ); - return TRUE; -} - -BOOL LLDrawPool::getClothingWeightStrider(LLStrider<LLVector4> &clothing_weights, const U32 index) -{ - llassert(mDataMaskNIL & LLDrawPool::DATA_CLOTHING_WEIGHTS_MASK); - - clothing_weights= &mClothingWeights[index]; - clothing_weights.setStride( 0 ); - - return TRUE; -} - -BOOL LLDrawPool::getNormalStrider(LLStrider<LLVector3> &normals, const U32 index) -{ - llassert((mDataMaskIL) & LLDrawPool::DATA_NORMALS_MASK); - - normals = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_NORMALS] + index * mStride); - - normals.setStride( mStride ); - - return TRUE; -} - - -BOOL LLDrawPool::getBinormalStrider(LLStrider<LLVector3> &binormals, const U32 index) -{ - llassert((mDataMaskIL) & LLDrawPool::DATA_BINORMALS_MASK); - - binormals = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_BINORMALS] + index * mStride); - - binormals.setStride( mStride ); - - return TRUE; -} - -BOOL LLDrawPool::getColorStrider(LLStrider<LLColor4U> &colors, const U32 index) -{ - llassert((mDataMaskIL) & LLDrawPool::DATA_COLORS_MASK); - - colors = (LLColor4U*)(mMemory.getMem() + mDataOffsets[DATA_COLORS] + index * mStride); - - colors.setStride( mStride ); - - return TRUE; -} - -//virtual -void LLDrawPool::beginRenderPass( S32 pass ) -{ -} - -//virtual -void LLDrawPool::endRenderPass( S32 pass ) -{ - glDisableClientState ( GL_TEXTURE_COORD_ARRAY ); - glDisableClientState ( GL_COLOR_ARRAY ); - glDisableClientState ( GL_NORMAL_ARRAY ); -} -void LLDrawPool::renderFaceSelected(LLFace *facep, +void LLFacePool::renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color, const S32 index_offset, const S32 index_count) { } -void LLDrawPool::renderVisibility() +void LLFacePool::renderVisibility() { if (mDrawFace.empty()) { @@ -506,893 +296,284 @@ void LLDrawPool::renderVisibility() } -void LLDrawPool::enqueue(LLFace* facep) -{ - if (facep->isState(LLFace::BACKLIST)) - { - mMoveFace.put(facep); - } - else - { -#if ENABLE_FACE_LINKING - facep->mSkipRender = FALSE; - facep->mNextFace = NULL; - - if (mDrawFace.size() > 0) - { - LLFace* last_face = mDrawFace[mDrawFace.size()-1]; - if (match(last_face, facep)) - { - last_face->link(facep); - } - } -#endif - mDrawFace.put(facep); - } -} - -void LLDrawPool::bindGLVertexPointer() -{ - mMemory.bindGLVertexPointer(getStride(DATA_VERTICES), mDataOffsets[DATA_VERTICES]); -} - -void LLDrawPool::bindGLTexCoordPointer(const U32 pass) -{ - mMemory.bindGLTexCoordPointer(getStride(DATA_TEX_COORDS0+pass), mDataOffsets[DATA_TEX_COORDS0+pass]); -} - -void LLDrawPool::bindGLNormalPointer() -{ - mMemory.bindGLNormalPointer(getStride(DATA_NORMALS), mDataOffsets[DATA_NORMALS]); -} - -void LLDrawPool::bindGLBinormalPointer(S32 index) -{ - mMemory.bindGLBinormalPointer(index, getStride(DATA_BINORMALS), mDataOffsets[DATA_BINORMALS]); -} - -void LLDrawPool::bindGLColorPointer() +void LLFacePool::enqueue(LLFace* facep) { - mMemory.bindGLColorPointer(getStride(DATA_COLORS), mDataOffsets[DATA_COLORS]); + mDrawFace.push_back(facep); } -void LLDrawPool::bindGLVertexWeightPointer(S32 index) -{ - mWeights.bindGLVertexWeightPointer(index, 0, 0); -} - -void LLDrawPool::bindGLVertexClothingWeightPointer(S32 index) -{ - mClothingWeights.bindGLVertexClothingWeightPointer(index, 0, 0); -} - - -U32* LLDrawPool::getIndices(S32 index) -{ - return &mIndices[index]; -} - -const LLVector3& LLDrawPool::getVertex(const S32 index) -{ - llassert(mDataMaskIL & DATA_VERTICES_MASK); - llassert(index < mMemory.count()); - llassert(mMemory.getMem()); - return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_VERTICES] + index * mStride); -} - -const LLVector2& LLDrawPool::getTexCoord(const S32 index, const U32 pass) +// virtual +BOOL LLFacePool::addFace(LLFace *facep) { - llassert(mDataMaskIL & (LLDrawPool::DATA_TEX_COORDS0_MASK << pass)); - llassert(index < mMemory.count()); - return *(LLVector2*)(mMemory.getMem() + mDataOffsets[DATA_TEX_COORDS0 + pass] + index * mStride); + addFaceReference(facep); + return TRUE; } -const LLVector3& LLDrawPool::getNormal(const S32 index) +// virtual +BOOL LLFacePool::removeFace(LLFace *facep) { - llassert(mDataMaskIL & DATA_NORMALS_MASK); - llassert(index < mMemory.count()); - return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_NORMALS] + index * mStride); -} + removeFaceReference(facep); -const LLVector3& LLDrawPool::getBinormal(const S32 index) -{ - llassert(mDataMaskIL & DATA_BINORMALS_MASK); - llassert(index < mMemory.count()); - return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_BINORMALS] + index * mStride); -} + vector_replace_with_last(mDrawFace, facep); -const LLColor4U& LLDrawPool::getColor(const S32 index) -{ - llassert(mDataMaskIL & DATA_COLORS_MASK); - llassert(index < mMemory.count()); - return *(LLColor4U*)(mMemory.getMem() + mDataOffsets[DATA_COLORS] + index * mStride); + return TRUE; } -const F32& LLDrawPool::getVertexWeight(const S32 index) +// Not absolutely sure if we should be resetting all of the chained pools as well - djs +void LLFacePool::resetDrawOrders() { - llassert(mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK); - llassert(index < mWeights.count()); - llassert(mWeights.getMem()); - return mWeights[index]; + mDrawFace.resize(0); } -const LLVector4& LLDrawPool::getClothingWeight(const S32 index) +LLViewerImage *LLFacePool::getTexture() { - llassert(mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK); - llassert(index < mClothingWeights.count()); - llassert(mClothingWeights.getMem()); - return mClothingWeights[index]; + return NULL; } -////////////////////////////////////////////////////////////////////////////// - -#define USE_FREE_LIST 0 -#define DEBUG_FREELIST 0 - -struct tFreeListNode +void LLFacePool::removeFaceReference(LLFace *facep) { - U32 count; - S32 next; -}; - -#if DEBUG_FREELIST -static void check_list(U8 *pool, S32 stride, S32 head, S32 max) -{ - int count = 0; - - while (head >= 0) + if (facep->getReferenceIndex() != -1) { - tFreeListNode *node = (tFreeListNode *)(pool + head*stride); - count++; - if ((count > max) || ((node->count>>20) != 0xabc) || ((node->count&0xfffff) < 2)) - llerrs << "Bad Ind List" << llendl; - head = node->next; + if (facep->getReferenceIndex() != (S32)mReferences.size()) + { + LLFace *back = mReferences.back(); + mReferences[facep->getReferenceIndex()] = back; + back->setReferenceIndex(facep->getReferenceIndex()); + } + mReferences.pop_back(); } + facep->setReferenceIndex(-1); } -#define CHECK_LIST(x) check_list##x -#else -#define CHECK_LIST(x) -#endif -// DEBUG! -void LLDrawPool::CheckIntegrity() +void LLFacePool::addFaceReference(LLFace *facep) { -#if DEBUG_FREELIST - int bucket; - for (bucket=0; bucket<NUM_BUCKETS; bucket++) + if (-1 == facep->getReferenceIndex()) { - CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[bucket], mMemory.count() / mStride)); - CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[bucket], mIndices.count())); + facep->setReferenceIndex(mReferences.size()); + mReferences.push_back(facep); } -#endif } -int LLDrawPool::freeListBucket(U32 count) +BOOL LLFacePool::verify() const { - int bucket; - - // llassert(NUM_BUCKETS == 8) + BOOL ok = TRUE; - if (count & ~511) // >= 512 - bucket = 7; - else if (count & 256) // 256-511 - bucket = 6; - else if (count & 128) - bucket = 5; - else if (count & 64) - bucket = 4; - else if (count & 32) - bucket = 3; - else if (count & 16) - bucket = 2; - else if (count & 8) // 8-15 - bucket = 1; - else // 0-7 - bucket = 0; - return bucket; -} - -void remove_node(int nodeidx, int pidx, U8 *membase, int stride, int *head) -{ - LLDrawPool::FreeListNode *node = (LLDrawPool::FreeListNode *)(membase + nodeidx*stride); - if (pidx >= 0) - { - LLDrawPool::FreeListNode *pnode = (LLDrawPool::FreeListNode *)(membase + pidx*stride); - pnode->next = node->next; - } - else - { - *head = node->next; - } -} - -void LLDrawPool::freeListAddGeom(S32 index, U32 count) -{ -#if USE_FREE_LIST - int i; - U8 *membase = (U8*)mMemory.getMem(); - // See if next block or previous block is free, if so combine them - for (i=0; i<NUM_BUCKETS; i++) - { - int pidx = -1; - int nodeidx = mFreeListGeomHead[i]; - while(nodeidx >= 0) - { - int change = 0; - FreeListNode *node = (FreeListNode *)(membase + nodeidx*mStride); - int nodecount = node->count & 0xffff; - // Check for prev block - if (nodeidx + nodecount == index) - { - remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]); - // Combine nodes - index = nodeidx; - count += nodecount; - i = 0; // start over ; i = NUM_BUCKETS // done - change = 1; - //break; - } - // Check for next block - if (nodeidx == index + count) - { - remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]); - // Combine nodes - count += nodecount; - i = 0; // start over ; i = NUM_BUCKETS // done - change = 1; - //break; - } - if (change) - break; - pidx = nodeidx; - nodeidx = node->next; - } - } - // Add (extended) block to free list - if (count >= 2) // need 2 words to store free list (theoreticly mStride could = 4) + for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) { - CheckIntegrity(); - if ((index + count)*mStride >= mMemory.count()) + const LLFace* facep = *iter; + if (facep->getPool() != this) { - mMemory.shrinkTo(index*mStride); + llinfos << "Face in wrong pool!" << llendl; + facep->printDebugInfo(); + ok = FALSE; } - else + else if (!facep->verify()) { - int bucket = freeListBucket(count); - FreeListNode *node = (FreeListNode *)(membase + index*mStride); - node->count = count | (0xabc<<20); - node->next = mFreeListGeomHead[bucket]; - mFreeListGeomHead[bucket] = index; + ok = FALSE; } - CheckIntegrity(); } -#endif -} -void LLDrawPool::freeListAddInd(S32 index, U32 count) -{ -#if USE_FREE_LIST - int i; - const U32 *membase = mIndices.getMem(); - // See if next block or previous block is free, if so combine them - for (i=0; i<NUM_BUCKETS; i++) - { - int pidx = -1; - int nodeidx = mFreeListIndHead[i]; - while(nodeidx >= 0) - { - int change = 0; - FreeListNode *node = (FreeListNode *)(membase + nodeidx); - int nodecount = node->count & 0xffff; - // Check for prev block - if (nodeidx + nodecount == index) - { - remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]); - // Combine nodes - index = nodeidx; - count += nodecount; - i = 0; // start over ; i = NUM_BUCKETS // done - change = 1; - //break; - } - // Check for next block - if (nodeidx == index + count) - { - remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]); - // Combine nodes - count += nodecount; - i = 0; // start over ; i = NUM_BUCKETS // done - change = 1; - //break; - } - if (change) - break; - pidx = nodeidx; - nodeidx = node->next; - } - } - // Add (extended) block to free list - if (count >= 2) // need 2 words to store free list - { - CheckIntegrity(); - if (index + count >= mIndices.count()) - { - mIndices.shrinkTo(index); - } - else - { - int bucket = freeListBucket(count); - FreeListNode *node = (FreeListNode *)(membase + index); - node->count = count | (0xabc<<20); - node->next = mFreeListIndHead[bucket]; - mFreeListIndHead[bucket] = index; - } - CheckIntegrity(); - } -#endif + return ok; } -S32 LLDrawPool::freeListFindGeom(U32 count) +void LLFacePool::printDebugInfo() const { -#if USE_FREE_LIST - int i, nodeidx, pidx; - int firstbucket = freeListBucket(count); - U8 *membase = (U8*)mMemory.getMem(); - for (i=firstbucket; i<NUM_BUCKETS; i++) - { - pidx = -1; - nodeidx = mFreeListGeomHead[i]; - CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[i], mMemory.count() / mStride)); - while(nodeidx >= 0) - { - FreeListNode *node = (FreeListNode *)(membase + nodeidx*mStride); - int nodecount = node->count & 0xffff; - llassert((node->count>>20) == 0xabc); - if (nodecount >= count) - { - remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]); -#if 1 - if (nodecount > count) - { - int leftover = nodecount - count; - freeListAddGeom(nodeidx + count, leftover); - } -#endif - return nodeidx; - } - pidx = nodeidx; - nodeidx = node->next; - } - } -#endif // USE_FREE_LIST - return -1; + llinfos << "Pool " << this << " Type: " << getType() << llendl; } -S32 LLDrawPool::freeListFindInd(U32 count) +BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE; + +void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color) { -#if USE_FREE_LIST - int i, nodeidx, pidx; - int firstbucket = freeListBucket(count); - U32 *membase = (U32 *)mIndices.getMem(); - for (i=firstbucket; i<NUM_BUCKETS; i++) + if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) { - pidx = -1; - nodeidx = mFreeListIndHead[i]; - CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[i], mIndices.count())); - while(nodeidx >= 0) - { - FreeListNode *node = (FreeListNode *)(membase + nodeidx); - int nodecount = node->count & 0xffff; - llassert((node->count>>20) == 0xabc); - if (nodecount >= count) - { - remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]); -#if 1 - if (nodecount > count) - { - int leftover = nodecount - count; - freeListAddInd(nodeidx + count, leftover); - } -#endif - return nodeidx; - } - pidx = nodeidx; - nodeidx = node->next; - } + glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV); } -#endif // USE_FREE_LIST - return -1; -} - -////////////////////////////////////////////////////////////////////////////// - -S32 LLDrawPool::reserveGeom(const U32 geom_count) -{ - LLFastTimer t(LLFastTimer::FTM_GEO_RESERVE); - - S32 index; - index = freeListFindGeom(geom_count); - if (index < 0) + else { - index = mMemory.count() / mStride; - if (!geom_count) - { - llwarns << "Attempting to reserve zero bytes!" << llendl; - return index; - } - - S32 bytes = geom_count * mStride; - - if ((index + (S32)geom_count) > (S32)mMaxVertices) - { - // - // Various drivers have issues with the number of indices being greater than a certain number. - // if you're using AGP. Disable AGP if we've got more vertices than in the pool. - // -#ifdef DEBUG_AGP - llinfos << "setUseAGP false because of large vertex count in reserveGeom" << llendl; -#endif - setUseAGP(FALSE); - } - - mMemory.reserve_block(bytes); - if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK) - { - mWeights.reserve_block(geom_count); - } - if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) - { - mClothingWeights.reserve_block(geom_count); - } + glColor4fv(color.mV); } - CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[0], mMemory.count() / mStride)); - return index; } -S32 LLDrawPool::reserveInd(U32 indCount) +void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color) { - S32 index; - index = freeListFindInd(indCount); - if (index < 0) + if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) { - index = mIndices.count(); - - if (indCount) - { - mIndices.reserve_block(indCount); - } + glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV); } - for (U32 i=0;i<indCount;i++) + else { - mIndices[index+i]=0; + glColor4ubv(color.mV); } - CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[0], mIndices.count())); - return index; } -S32 LLDrawPool::unReserveGeom(const S32 index, const U32 count) +void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a) { - if (index < 0 || count == 0) - return -1; - - freeListAddGeom(index, count); - -#if 0 - int i; - S32 bytes,words; - U32 *memp; - // Fill mem with bad data (for testing only) - bytes = count * mStride; - bytes -= sizeof(FreeListNode); - memp = (U32*)(mMemory.getMem() + index * mStride); - memp += sizeof(FreeListNode)>>2; - words = bytes >> 2; - for (i=0; i<words; i++) - *memp++ = 0xffffffff; - - words = count; // (sizeof each array is a word) - if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK) + if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) { - memp = (U32*)(&mWeights[index]); - for (i=0; i<words; i++) - *memp++ = 0xffffffff; + glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a); } - if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) + else { - memp = (U32*)(&mClothingWeights[index]); - for (i=0; i<count; i++) - *memp++ = 0xffffffff; + glColor4f(r,g,b,a); } -#endif - return -1; } -S32 LLDrawPool::unReserveInd(const S32 index, const U32 count) -{ - if (index < 0 || count == 0) - return -1; - freeListAddInd(index, count); - -#if 0 - int i; - U32 *memp = &mIndices[index]; - for (i=0; i<count; i++) - *memp++ = 0xffffffff; -#endif - return -1; -} - -////////////////////////////////////////////////////////////////////////////// - -const U32 LLDrawPool::getIndexCount() const +//============================= +// Render Pass Implementation +//============================= +LLRenderPass::LLRenderPass(const U32 type) +: LLDrawPool(type) { - return mIndices.count(); -} -const U32 LLDrawPool::getVertexCount() const -{ - return mMemory.count() / mStride; } -const U32 LLDrawPool::getTexCoordCount(U32 pass) const +LLRenderPass::~LLRenderPass() { - return mMemory.count() / mStride; -} - -const U32 LLDrawPool::getNormalCount() const -{ - return mMemory.count() / mStride; } - -const U32 LLDrawPool::getBinormalCount() const +LLDrawPool* LLRenderPass::instancePool() { - return mMemory.count() / mStride; -} - -const U32 LLDrawPool::getColorCount() const -{ - return mMemory.count() / mStride; -} - -const U32 LLDrawPool::getVertexWeightCount() const -{ - return mWeights.count(); +#if LL_RELEASE_FOR_DOWNLOAD + llwarns << "Attempting to instance a render pass. Invalid operation." << llendl; +#else + llerrs << "Attempting to instance a render pass. Invalid operation." << llendl; +#endif + return NULL; } -// virtual -BOOL LLDrawPool::addFace(LLFace *facep) -{ - addFaceReference(facep); - return TRUE; +void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) +{ + std::vector<LLDrawInfo*>& draw_info = group->mDrawMap[type]; + + for (std::vector<LLDrawInfo*>::const_iterator k = draw_info.begin(); k != draw_info.end(); ++k) + { + LLDrawInfo& params = **k; + pushBatch(params, mask, texture); + } } -// virtual -BOOL LLDrawPool::removeFace(LLFace *facep) +void LLRenderPass::renderInvisible(U32 mask) { - removeFaceReference(facep); - - vector_replace_with_last(mDrawFace, facep); - - facep->unReserve(); +#if !LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkClientArrays(mask); +#endif - return TRUE; -} + std::vector<LLDrawInfo*>& draw_info = gPipeline.mRenderMap[LLRenderPass::PASS_INVISIBLE]; -// Not absolutely sure if we should be resetting all of the chained pools as well - djs -void LLDrawPool::resetDrawOrders() -{ - mDrawFace.resize(0); + U32* indices_pointer = NULL; + for (std::vector<LLDrawInfo*>::iterator i = draw_info.begin(); i != draw_info.end(); ++i) + { + LLDrawInfo& params = **i; + params.mVertexBuffer->setBuffer(mask); + indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); + glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, + GL_UNSIGNED_INT, indices_pointer+params.mOffset); + gPipeline.mTrianglesDrawn += params.mCount/3; + } } -void LLDrawPool::resetIndices(S32 indices_count) +void LLRenderPass::renderTexture(U32 type, U32 mask) { - mIndices.reset(indices_count); - for (S32 i=0; i<NUM_BUCKETS; i++) - mFreeListIndHead[i] = -1; -} +#if !LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkClientArrays(mask); +#endif -void LLDrawPool::resetVertexData(S32 reserve_count) -{ - mMemory.reset(reserve_count*mStride); - - for (S32 i=0; i<NUM_BUCKETS; i++) - { - mFreeListGeomHead[i] = -1; - } - if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK) - { - mWeights.reset(reserve_count); - } + std::vector<LLDrawInfo*>& draw_info = gPipeline.mRenderMap[type]; - if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) + for (std::vector<LLDrawInfo*>::iterator i = draw_info.begin(); i != draw_info.end(); ++i) { - mClothingWeights.reset(reserve_count); + LLDrawInfo& params = **i; + pushBatch(params, mask, TRUE); } } -void LLDrawPool::resetAll() -{ - resetDrawOrders(); - resetVertexData(0); - mGeneration++; - -} - -S32 LLDrawPool::rebuild() +void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { - mRebuildTime++; - - BOOL needs_rebuild = FALSE; - S32 rebuild_cost = 0; - - if (mUseAGP) - { - if (getVertexCount() > 0.75f*DEFAULT_MAX_VERTICES) - { - if (mRebuildTime > 8) - { - needs_rebuild = TRUE; - } -#ifdef DEBUG_AGP - llwarns << "More than " << DEFAULT_MAX_VERTICES << " in pool type " << (S32)mType << " at rebuild!" << llendl; -#endif - } - } - - // rebuild de-allocates 'stale' objects, so we still need to do a rebuild periodically - if (mRebuildFreq > 0 && mRebuildTime >= mRebuildFreq) + if (params.mVertexBuffer.isNull()) { - needs_rebuild = TRUE; + return; } - if (needs_rebuild) + if (texture) { - mGeneration++; - - if (mReferences.empty()) + if (params.mTexture.notNull()) { - resetIndices(0); - resetVertexData(0); - } - else - { - for (std::vector<LLFace*>::iterator iter = mReferences.begin(); - iter != mReferences.end(); iter++) - { - LLFace *facep = *iter; - if (facep->hasGeometry() && !facep->isState(LLFace::BACKLIST | LLFace::SHARED_GEOM)) - { - facep->backup(); - } - } - S32 tot_verts = 0; - S32 tot_indices = 0; - for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *facep = *iter; - if (facep->isState(LLFace::BACKLIST)) - { - tot_verts += facep->getGeomCount(); - tot_indices += facep->getIndicesCount(); - } - } - for (std::vector<LLFace*>::iterator iter = mMoveFace.begin(); - iter != mMoveFace.end(); iter++) + params.mTexture->bind(); + if (params.mTextureMatrix) { - LLFace *facep = *iter; - if (facep->isState(LLFace::BACKLIST)) - { - tot_verts += facep->getGeomCount(); - tot_indices += facep->getIndicesCount(); - } - } - - resetIndices(tot_indices); - flushAGP(); - resetVertexData(tot_verts); - - for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *facep = *iter; - llassert(facep->getPool() == this); - facep->restore(); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); } + params.mTexture->addTextureStats(params.mVSize); } - mRebuildTime = 0; - setDirty(); - } - - if (!mMoveFace.empty()) - { - for (std::vector<LLFace*>::iterator iter = mMoveFace.begin(); - iter != mMoveFace.end(); iter++) - { - LLFace *facep = *iter; - facep->restore(); - enqueue(facep); - } - setDirty(); - mMoveFace.reset(); - rebuild_cost++; - } - return rebuild_cost; -} - -LLViewerImage *LLDrawPool::getTexture() -{ - return NULL; -} - -LLViewerImage *LLDrawPool::getDebugTexture() -{ - return NULL; -} - -void LLDrawPool::removeFaceReference(LLFace *facep) -{ - if (facep->getReferenceIndex() != -1) - { - if (facep->getReferenceIndex() != (S32)mReferences.size()) + else { - LLFace *back = mReferences.back(); - mReferences[facep->getReferenceIndex()] = back; - back->setReferenceIndex(facep->getReferenceIndex()); + LLImageGL::unbindTexture(0); } - mReferences.pop_back(); } - facep->setReferenceIndex(-1); -} + + params.mVertexBuffer->setBuffer(mask); + U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); + glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, + GL_UNSIGNED_INT, indices_pointer+params.mOffset); + gPipeline.mTrianglesDrawn += params.mCount/3; -void LLDrawPool::addFaceReference(LLFace *facep) -{ - if (-1 == facep->getReferenceIndex()) + if (params.mTextureMatrix && texture && params.mTexture.notNull()) { - facep->setReferenceIndex(mReferences.size()); - mReferences.push_back(facep); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); } } -U32 LLDrawPool::getTrianglesDrawn() const +void LLRenderPass::renderActive(U32 type, U32 mask, BOOL texture) { - return mIndicesDrawn / 3; -} - -void LLDrawPool::resetTrianglesDrawn() -{ - mIndicesDrawn = 0; -} - -void LLDrawPool::addIndicesDrawn(const U32 indices) -{ - mIndicesDrawn += indices; -} +#if !LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkClientArrays(mask); +#endif -BOOL LLDrawPool::verify() const -{ - BOOL ok = TRUE; - // Verify all indices in the pool are in the right range - const U32 *indicesp = getRawIndices(); - for (U32 i = 0; i < getIndexCount(); i++) + LLSpatialBridge* last_bridge = NULL; + glPushMatrix(); + + for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i) { - if (indicesp[i] > getVertexCount()) + LLSpatialGroup* group = *i; + if (!group->isDead() && + gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && + group->mDrawMap.find(type) != group->mDrawMap.end()) { - ok = FALSE; - llinfos << "Bad index in tree pool!" << llendl; - } - } + LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition; + if (bridge != last_bridge) + { + glPopMatrix(); + glPushMatrix(); + glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); + last_bridge = bridge; + } - for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - const LLFace* facep = *iter; - if (facep->getPool() != this) - { - llinfos << "Face in wrong pool!" << llendl; - facep->printDebugInfo(); - ok = FALSE; - } - else if (!facep->verify()) - { - ok = FALSE; + renderGroup(group,type,mask,texture); } } - - return ok; -} - -void LLDrawPool::printDebugInfo() const -{ - llinfos << "Pool " << this << " Type: " << getType() << llendl; - llinfos << "--------------------" << llendl; - llinfos << "Vertex count: " << getVertexCount() << llendl; - llinfos << "Normal count: " << getNormalCount() << llendl; - llinfos << "Indices count: " << getIndexCount() << llendl; - llinfos << llendl; -} - - -S32 LLDrawPool::getMemUsage(const BOOL print) -{ - S32 mem_usage = 0; - - mem_usage += sizeof(this); - - // Usage beyond the pipeline allocated data (color and mMemory) - mem_usage += mIndices.getMax() * sizeof(U32); - mem_usage += mDrawFace.capacity() * sizeof(LLFace *); - mem_usage += mMoveFace.capacity() * sizeof(LLFace *); - mem_usage += mReferences.capacity() * sizeof(LLFace *); - - mem_usage += mMemory.getSysMemUsage(); - mem_usage += mWeights.getSysMemUsage(); - mem_usage += mClothingWeights.getSysMemUsage(); - - return mem_usage; -} - -LLColor3 LLDrawPool::getDebugColor() const -{ - return LLColor3(0.f, 0.f, 0.f); -} - -void LLDrawPool::setDirty() -{ - mMemory.setDirty(); - mWeights.setDirty(); - mClothingWeights.setDirty(); -} - -BOOL LLDrawPool::LLOverrideFaceColor::sOverrideFaceColor = FALSE; - -void LLDrawPool::LLOverrideFaceColor::setColor(const LLColor4& color) -{ - if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0) - { - glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV); - } - else - { - glColor4fv(color.mV); - } + + glPopMatrix(); } -void LLDrawPool::LLOverrideFaceColor::setColor(const LLColor4U& color) +void LLRenderPass::renderStatic(U32 type, U32 mask, BOOL texture) { - if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0) - { - glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV); - } - else - { - glColor4ubv(color.mV); - } -} +#if !LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkClientArrays(mask); +#endif -void LLDrawPool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a) -{ - if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0) - { - glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a); - } - else + for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mVisibleGroups.begin(); i != gPipeline.mVisibleGroups.end(); ++i) { - glColor4f(r,g,b,a); + LLSpatialGroup* group = *i; + if (!group->isDead() && + gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && + group->mDrawMap.find(type) != group->mDrawMap.end()) + { + renderGroup(group,type,mask,texture); + } } } - -// virtual -void LLDrawPool::enableShade() -{ } - -// virtual -void LLDrawPool::disableShade() -{ } - -// virtual -void LLDrawPool::setShade(F32 shade) -{ } |