diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index abc281e0e..96db56418 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -115,23 +115,6 @@ void sg_assert(BOOL expr) #endif } -#if LL_DEBUG -void validate_drawable(LLDrawable* drawablep) -{ - F64 rad = drawablep->getBinRadius(); - const LLVector3* ext = drawablep->getSpatialExtents(); - - if (rad < 0 || rad > 4096 || - (ext[1]-ext[0]).magVec() > 4096) - { - llwarns << "Invalid drawable found in octree." << llendl; - } -} -#else -#define validate_drawable(x) -#endif - - S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) { return AABBSphereIntersectR2(min, max, origin, rad*rad); @@ -277,38 +260,70 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) void LLSpatialGroup::buildOcclusion() { - if (!mOcclusionVerts) + if (mOcclusionVerts.isNull()) { - mOcclusionVerts = new F32[8*3]; - } - LLVector3 bounds[2]; - bounds[0].set(mBounds[0].getF32ptr()); - bounds[1].set(mBounds[1].getF32ptr()); - LLVector3 r = bounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE); - - for (U32 k = 0; k < 3; k++) - { - r.mV[k] = llmin(bounds[1].mV[k]+0.25f, r.mV[k]); - } - - F32* v = mOcclusionVerts; - F32* c = bounds[0].mV; - F32* s = r.mV; + mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, + LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling. + mOcclusionVerts->allocateBuffer(8, 64, true); - //vertex positions are encoded so the 3 bits of their vertex index - //correspond to their axis facing, with bit position 3,2,1 matching - //axis facing x,y,z, bit set meaning positive facing, bit clear - //meaning negative facing - v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000 - v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001 - v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010 - v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011 - - v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100 - v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101 - v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110 - v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111 + LLStrider idx; + mOcclusionVerts->getIndexStrider(idx); + for (U32 i = 0; i < 64; i++) + { + *idx++ = sOcclusionIndices[i]; + } + } + + LLVector4a fudge; + fudge.splat(SG_OCCLUSION_FUDGE); + + LLVector4a r; + r.setAdd(mBounds[1], fudge); + + LLStrider pos; + + { + //LLFastTimer t(LLFastTimer::FTM_BUILD_OCCLUSION); + mOcclusionVerts->getVertexStrider(pos); + } + + { + LLVector4a* v = (LLVector4a*) pos.get(); + + const LLVector4a& c = mBounds[0]; + const LLVector4a& s = r; + + static const LLVector4a octant[] = + { + LLVector4a(-1.f, -1.f, -1.f), + LLVector4a(-1.f, -1.f, 1.f), + LLVector4a(-1.f, 1.f, -1.f), + LLVector4a(-1.f, 1.f, 1.f), + + LLVector4a(1.f, -1.f, -1.f), + LLVector4a(1.f, -1.f, 1.f), + LLVector4a(1.f, 1.f, -1.f), + LLVector4a(1.f, 1.f, 1.f), + }; + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + + for (S32 i = 0; i < 8; ++i) + { + LLVector4a p; + p.setMul(s, octant[i]); + p.add(c); + v[i] = p; + } + } + + { + mOcclusionVerts->setBuffer(0); + } clearState(LLSpatialGroup::OCCLUSION_DIRTY); } @@ -374,7 +389,6 @@ LLSpatialGroup::~LLSpatialGroup() } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -469,52 +483,6 @@ void LLSpatialGroup::checkStates() #endif } -void validate_draw_info(LLDrawInfo& params) -{ -#if LL_OCTREE_PARANOIA_CHECK - if (!params.mVertexBuffer) - { - llerrs << "Draw batch has no vertex buffer." << llendl; - } - - //bad range - if (params.mStart >= params.mEnd) - { - llerrs << "Draw batch has invalid range." << llendl; - } - - if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts()) - { - llerrs << "Draw batch has buffer overrun error." << llendl; - } - - if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices()) - { - llerrs << "Draw batch has index buffer ovverrun error." << llendl; - } - - //bad indices - U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer(); - if (indicesp) - { - for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) - { - if (indicesp[i] < (U16)params.mStart) - { - llerrs << "Draw batch has vertex buffer index out of range error (index too low). " - << "indicesp["< (U16)params.mEnd) - { - llerrs << "Draw batch has vertex buffer index out of range error (index too high)." - << "indicesp["<updateSpatialExtents(); - validate_drawable(drawablep); OctreeNode* parent = mOctreeNode->getOctParent(); @@ -548,7 +515,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) unbound(); setState(OBJECT_DIRTY); //setState(GEOM_DIRTY); - validate_drawable(drawablep); return TRUE; } @@ -566,7 +532,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc else { drawablep->setSpatialGroup(this); - validate_drawable(drawablep); setState(OBJECT_DIRTY | GEOM_DIRTY); setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); gPipeline.markRebuild(this, TRUE); @@ -839,7 +804,7 @@ void LLSpatialGroup::shift(const LLVector4a &offset) gPipeline.markRebuild(this, TRUE); } - if (mOcclusionVerts) + if (mOcclusionVerts.notNull()) { setState(OCCLUSION_DIRTY); } @@ -874,24 +839,16 @@ void LLSpatialGroup::setState(eSpatialState state) // if (LLSpatialPartition::sFreezeState) // return; mState |= state; - - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + + llassert(state <= LLSpatialGroup::STATE_MASK); } void LLSpatialGroup::setState(eSpatialState state, S32 mode) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); -// if (LLSpatialPartition::sFreezeState) -// return; - - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); + if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -937,25 +894,14 @@ public: void LLSpatialGroup::clearState(eSpatialState state) { -// if (LLSpatialPartition::sFreezeState) -// return; - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); mState &= ~state; } void LLSpatialGroup::clearState(eSpatialState state, S32 mode) { - -// if (LLSpatialPartition::sFreezeState) -// return; - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -980,10 +926,7 @@ void LLSpatialGroup::clearState(eSpatialState state, S32 mode) BOOL LLSpatialGroup::isState(eSpatialState state) const { - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "LLSpatialGroup::isState passed invalid state '" << state << "'" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); return mState & state ? TRUE : FALSE; } @@ -1121,7 +1064,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mOctreeNode(node), mSpatialPartition(part), mVertexBuffer(NULL), - mBufferUsage(GL_STATIC_DRAW_ARB), + mBufferUsage(part->mBufferUsage), mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), @@ -1399,7 +1342,6 @@ void LLSpatialGroup::destroyGL() } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) @@ -1573,7 +1515,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); } - if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) + if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY)) { buildOcclusion(); } @@ -1600,37 +1542,32 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { //LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); + + mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); + if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) { LLGLSquashToFarClip squash(glh_get_current_projection(), 1); if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); } else { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0])); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); } } else { if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); - + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); } else { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0])); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); } } @@ -1689,7 +1626,6 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); drawablep->updateSpatialExtents(); - validate_drawable(drawablep); //keep drawable from being garbage collected LLPointer ptr = drawablep; @@ -1988,11 +1924,8 @@ public: virtual void processGroup(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) - { - llerrs << "WTF?" << llendl; - } - + llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty()) + if (mRes < 2) { if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) @@ -2356,6 +2289,8 @@ void pushVerts(LLSpatialGroup* group, U32 mask) void pushVerts(LLFace* face, U32 mask) { + llassert(face->verify()); + LLVertexBuffer* buffer = face->getVertexBuffer(); if (buffer) @@ -3159,7 +3094,6 @@ public: { renderAgentTarget(avatar); } - } for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -3550,18 +3484,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, mFace(NULL), mDistance(0.f) { - mDebugColor = (rand() << 16) + rand(); - if (mStart >= mVertexBuffer->getRequestedVerts() || - mEnd >= mVertexBuffer->getRequestedVerts()) - { - llerrs << "Invalid draw info vertex range." << llendl; - } + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); - if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() || - mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices()) - { - llerrs << "Invalid draw info index range." << llendl; - } + mDebugColor = (rand() << 16) + rand(); } LLDrawInfo::~LLDrawInfo() @@ -3582,6 +3507,11 @@ LLDrawInfo::~LLDrawInfo() } } +void LLDrawInfo::validate() +{ + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); +} + LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) { return new LLVertexBuffer(type_mask, usage); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index bc11da84d..56e5ca2e5 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -88,6 +88,7 @@ public: BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); + void validate(); LLVector4a mExtents[2]; @@ -361,9 +362,9 @@ public: F32 mBuilt; OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; - + LLPointer mVertexBuffer; - F32* mOcclusionVerts; + LLPointer mOcclusionVerts; GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; U32 mBufferUsage; @@ -694,8 +695,6 @@ public: virtual void shift(const LLVector4a &offset); }; -void validate_draw_info(LLDrawInfo& params); - extern const F32 SG_BOX_SIDE; extern const F32 SG_BOX_OFFSET; extern const F32 SG_BOX_RAD; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3c040c5dd..6062461a5 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2942,7 +2942,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); - validate_draw_info(*draw_vec[idx]); + draw_vec[idx]->validate(); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]); } @@ -2966,7 +2966,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } draw_info->mExtents[0] = facep->mExtents[0]; draw_info->mExtents[1] = facep->mExtents[1]; - validate_draw_info(*draw_info); + draw_info->validate(); } }