From 4dabd9c0472deb49573fdafef2fa413e59703f19 Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Fri, 2 Mar 2007 21:25:50 +0000 Subject: merge release@58699 beta-1-14-0@58707 -> release --- indra/newview/lldrawpool.cpp | 1295 ++++++++---------------------------------- 1 file changed, 238 insertions(+), 1057 deletions(-) (limited to 'indra/newview/lldrawpool.cpp') 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 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& 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 &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 &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 &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 &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 &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 &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 &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) +void LLFacePool::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); - } + mDrawFace.push_back(facep); } -void LLDrawPool::bindGLVertexPointer() +// virtual +BOOL LLFacePool::addFace(LLFace *facep) { - mMemory.bindGLVertexPointer(getStride(DATA_VERTICES), mDataOffsets[DATA_VERTICES]); + addFaceReference(facep); + return TRUE; } -void LLDrawPool::bindGLTexCoordPointer(const U32 pass) +// virtual +BOOL LLFacePool::removeFace(LLFace *facep) { - mMemory.bindGLTexCoordPointer(getStride(DATA_TEX_COORDS0+pass), mDataOffsets[DATA_TEX_COORDS0+pass]); -} + removeFaceReference(facep); -void LLDrawPool::bindGLNormalPointer() -{ - mMemory.bindGLNormalPointer(getStride(DATA_NORMALS), mDataOffsets[DATA_NORMALS]); -} + vector_replace_with_last(mDrawFace, facep); -void LLDrawPool::bindGLBinormalPointer(S32 index) -{ - mMemory.bindGLBinormalPointer(index, getStride(DATA_BINORMALS), mDataOffsets[DATA_BINORMALS]); + return TRUE; } -void LLDrawPool::bindGLColorPointer() +// Not absolutely sure if we should be resetting all of the chained pools as well - djs +void LLFacePool::resetDrawOrders() { - mMemory.bindGLColorPointer(getStride(DATA_COLORS), mDataOffsets[DATA_COLORS]); + mDrawFace.resize(0); } -void LLDrawPool::bindGLVertexWeightPointer(S32 index) +LLViewerImage *LLFacePool::getTexture() { - mWeights.bindGLVertexWeightPointer(index, 0, 0); + return NULL; } -void LLDrawPool::bindGLVertexClothingWeightPointer(S32 index) +void LLFacePool::removeFaceReference(LLFace *facep) { - mClothingWeights.bindGLVertexClothingWeightPointer(index, 0, 0); + if (facep->getReferenceIndex() != -1) + { + if (facep->getReferenceIndex() != (S32)mReferences.size()) + { + LLFace *back = mReferences.back(); + mReferences[facep->getReferenceIndex()] = back; + back->setReferenceIndex(facep->getReferenceIndex()); + } + mReferences.pop_back(); + } + facep->setReferenceIndex(-1); } - -U32* LLDrawPool::getIndices(S32 index) +void LLFacePool::addFaceReference(LLFace *facep) { - return &mIndices[index]; + if (-1 == facep->getReferenceIndex()) + { + facep->setReferenceIndex(mReferences.size()); + mReferences.push_back(facep); + } } -const LLVector3& LLDrawPool::getVertex(const S32 index) +BOOL LLFacePool::verify() const { - llassert(mDataMaskIL & DATA_VERTICES_MASK); - llassert(index < mMemory.count()); - llassert(mMemory.getMem()); - return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_VERTICES] + index * mStride); -} + BOOL ok = TRUE; + + for (std::vector::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; + } + } -const LLVector2& LLDrawPool::getTexCoord(const S32 index, const U32 pass) -{ - llassert(mDataMaskIL & (LLDrawPool::DATA_TEX_COORDS0_MASK << pass)); - llassert(index < mMemory.count()); - return *(LLVector2*)(mMemory.getMem() + mDataOffsets[DATA_TEX_COORDS0 + pass] + index * mStride); + return ok; } -const LLVector3& LLDrawPool::getNormal(const S32 index) +void LLFacePool::printDebugInfo() const { - llassert(mDataMaskIL & DATA_NORMALS_MASK); - llassert(index < mMemory.count()); - return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_NORMALS] + index * mStride); + llinfos << "Pool " << this << " Type: " << getType() << llendl; } -const LLVector3& LLDrawPool::getBinormal(const S32 index) +BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE; + +void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color) { - llassert(mDataMaskIL & DATA_BINORMALS_MASK); - llassert(index < mMemory.count()); - return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_BINORMALS] + index * mStride); + if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) + { + glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV); + } + else + { + glColor4fv(color.mV); + } } -const LLColor4U& LLDrawPool::getColor(const S32 index) +void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color) { - llassert(mDataMaskIL & DATA_COLORS_MASK); - llassert(index < mMemory.count()); - return *(LLColor4U*)(mMemory.getMem() + mDataOffsets[DATA_COLORS] + index * mStride); + if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) + { + glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV); + } + else + { + glColor4ubv(color.mV); + } } -const F32& LLDrawPool::getVertexWeight(const S32 index) +void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a) { - llassert(mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK); - llassert(index < mWeights.count()); - llassert(mWeights.getMem()); - return mWeights[index]; + if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) + { + glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a); + } + else + { + glColor4f(r,g,b,a); + } } -const LLVector4& LLDrawPool::getClothingWeight(const S32 index) + +//============================= +// Render Pass Implementation +//============================= +LLRenderPass::LLRenderPass(const U32 type) +: LLDrawPool(type) { - llassert(mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK); - llassert(index < mClothingWeights.count()); - llassert(mClothingWeights.getMem()); - return mClothingWeights[index]; + } -////////////////////////////////////////////////////////////////////////////// +LLRenderPass::~LLRenderPass() +{ -#define USE_FREE_LIST 0 -#define DEBUG_FREELIST 0 +} -struct tFreeListNode +LLDrawPool* LLRenderPass::instancePool() { - U32 count; - S32 next; -}; +#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; +} -#if DEBUG_FREELIST -static void check_list(U8 *pool, S32 stride, S32 head, S32 max) -{ - int count = 0; +void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) +{ + std::vector& draw_info = group->mDrawMap[type]; - while (head >= 0) + for (std::vector::const_iterator k = draw_info.begin(); k != draw_info.end(); ++k) { - 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; + LLDrawInfo& params = **k; + pushBatch(params, mask, texture); } } -#define CHECK_LIST(x) check_list##x -#else -#define CHECK_LIST(x) -#endif -// DEBUG! -void LLDrawPool::CheckIntegrity() +void LLRenderPass::renderInvisible(U32 mask) { -#if DEBUG_FREELIST - int bucket; - for (bucket=0; bucket& draw_info = gPipeline.mRenderMap[LLRenderPass::PASS_INVISIBLE]; + + U32* indices_pointer = NULL; + for (std::vector::iterator i = draw_info.begin(); i != draw_info.end(); ++i) { - CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[bucket], mMemory.count() / mStride)); - CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[bucket], mIndices.count())); + 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; } -#endif } -int LLDrawPool::freeListBucket(U32 count) +void LLRenderPass::renderTexture(U32 type, U32 mask) { - int bucket; +#if !LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkClientArrays(mask); +#endif - // llassert(NUM_BUCKETS == 8) - - 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; -} + std::vector& draw_info = gPipeline.mRenderMap[type]; -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 + for (std::vector::iterator i = draw_info.begin(); i != draw_info.end(); ++i) { - *head = node->next; + LLDrawInfo& params = **i; + pushBatch(params, mask, TRUE); } } -void LLDrawPool::freeListAddGeom(S32 index, U32 count) +void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { -#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= 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) - { - CheckIntegrity(); - if ((index + count)*mStride >= mMemory.count()) - { - mMemory.shrinkTo(index*mStride); - } - else - { - int bucket = freeListBucket(count); - FreeListNode *node = (FreeListNode *)(membase + index*mStride); - node->count = count | (0xabc<<20); - node->next = mFreeListGeomHead[bucket]; - mFreeListGeomHead[bucket] = index; - } - CheckIntegrity(); + return; } -#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= 0) + if (params.mTexture.notNull()) { - 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) + params.mTexture->bind(); + if (params.mTextureMatrix) { - remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]); - // Combine nodes - count += nodecount; - i = 0; // start over ; i = NUM_BUCKETS // done - change = 1; - //break; + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); } - 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); + params.mTexture->addTextureStats(params.mVSize); } else { - int bucket = freeListBucket(count); - FreeListNode *node = (FreeListNode *)(membase + index); - node->count = count | (0xabc<<20); - node->next = mFreeListIndHead[bucket]; - mFreeListIndHead[bucket] = index; - } - CheckIntegrity(); - } -#endif -} - -S32 LLDrawPool::freeListFindGeom(U32 count) -{ -#if USE_FREE_LIST - int i, nodeidx, pidx; - int firstbucket = freeListBucket(count); - U8 *membase = (U8*)mMemory.getMem(); - for (i=firstbucket; i= 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; -} - -S32 LLDrawPool::freeListFindInd(U32 count) -{ -#if USE_FREE_LIST - int i, nodeidx, pidx; - int firstbucket = freeListBucket(count); - U32 *membase = (U32 *)mIndices.getMem(); - for (i=firstbucket; i= 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; + LLImageGL::unbindTexture(0); } } -#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) - { - 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); - } - } - CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[0], mMemory.count() / mStride)); - return index; -} - -S32 LLDrawPool::reserveInd(U32 indCount) -{ - S32 index; - index = freeListFindInd(indCount); - if (index < 0) - { - index = mIndices.count(); - - if (indCount) - { - mIndices.reserve_block(indCount); - } - } - for (U32 i=0;isetBuffer(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; - 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; iunReserve(); - - return TRUE; -} - -// Not absolutely sure if we should be resetting all of the chained pools as well - djs -void LLDrawPool::resetDrawOrders() -{ - mDrawFace.resize(0); -} -void LLDrawPool::resetIndices(S32 indices_count) -{ - mIndices.reset(indices_count); - for (S32 i=0; i 0.75f*DEFAULT_MAX_VERTICES) + LLSpatialGroup* group = *i; + if (!group->isDead() && + gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && + group->mDrawMap.find(type) != group->mDrawMap.end()) { - 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) - { - needs_rebuild = TRUE; - } - - if (needs_rebuild) - { - mGeneration++; - - if (mReferences.empty()) - { - resetIndices(0); - resetVertexData(0); - } - else - { - for (std::vector::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::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) + LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition; + if (bridge != last_bridge) { - LLFace *facep = *iter; - if (facep->isState(LLFace::BACKLIST)) - { - tot_verts += facep->getGeomCount(); - tot_indices += facep->getIndicesCount(); - } + glPopMatrix(); + glPushMatrix(); + glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); + last_bridge = bridge; } - for (std::vector::iterator iter = mMoveFace.begin(); - iter != mMoveFace.end(); iter++) - { - 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::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *facep = *iter; - llassert(facep->getPool() == this); - facep->restore(); - } - } - mRebuildTime = 0; - setDirty(); - } - - if (!mMoveFace.empty()) - { - for (std::vector::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()) - { - LLFace *back = mReferences.back(); - mReferences[facep->getReferenceIndex()] = back; - back->setReferenceIndex(facep->getReferenceIndex()); + renderGroup(group,type,mask,texture); } - mReferences.pop_back(); - } - facep->setReferenceIndex(-1); -} - -void LLDrawPool::addFaceReference(LLFace *facep) -{ - if (-1 == facep->getReferenceIndex()) - { - facep->setReferenceIndex(mReferences.size()); - mReferences.push_back(facep); } + + glPopMatrix(); } -U32 LLDrawPool::getTrianglesDrawn() const -{ - return mIndicesDrawn / 3; -} - -void LLDrawPool::resetTrianglesDrawn() -{ - mIndicesDrawn = 0; -} - -void LLDrawPool::addIndicesDrawn(const U32 indices) -{ - mIndicesDrawn += indices; -} - -BOOL LLDrawPool::verify() const +void LLRenderPass::renderStatic(U32 type, U32 mask, BOOL texture) { - 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++) - { - if (indicesp[i] > getVertexCount()) - { - ok = FALSE; - llinfos << "Bad index in tree pool!" << llendl; - } - } +#if !LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkClientArrays(mask); +#endif - for (std::vector::const_iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) + for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mVisibleGroups.begin(); i != gPipeline.mVisibleGroups.end(); ++i) { - const LLFace* facep = *iter; - if (facep->getPool() != this) + LLSpatialGroup* group = *i; + if (!group->isDead() && + gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && + group->mDrawMap.find(type) != group->mDrawMap.end()) { - 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); - } -} - -void LLDrawPool::LLOverrideFaceColor::setColor(const LLColor4U& color) -{ - if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0) - { - glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV); - } - else - { - glColor4ubv(color.mV); - } -} - -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 - { - glColor4f(r,g,b,a); - } -} - -// virtual -void LLDrawPool::enableShade() -{ } - -// virtual -void LLDrawPool::disableShade() -{ } - -// virtual -void LLDrawPool::setShade(F32 shade) -{ } -- cgit v1.2.3