From 7bcd259821fa0462160ff720a1d13d1202ceb2b5 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 5 Aug 2011 19:24:17 -0500 Subject: [PATCH] Added ShyotlRenderVBOStrideMode to toggle between strided and unstrided VBOs. --- indra/llrender/llvertexbuffer.cpp | 143 +++++++++++++++--------- indra/llrender/llvertexbuffer.h | 33 +++--- indra/newview/app_settings/settings.xml | 16 ++- indra/newview/lldrawpoolavatar.cpp | 12 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llvosurfacepatch.cpp | 72 ++++++++++-- indra/newview/llvovolume.cpp | 6 +- indra/newview/llvowlsky.cpp | 2 +- indra/newview/pipeline.cpp | 2 + 9 files changed, 197 insertions(+), 90 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 301a3f056..2837cd6af 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -66,6 +66,7 @@ BOOL LLVertexBuffer::sIBOActive = FALSE; U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; +U32 LLVertexBuffer::sForceStrideMode = 0; BOOL LLVertexBuffer::sOmitBlank = FALSE; BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; S32 LLVertexBuffer::sWeight4Loc = -1; @@ -263,7 +264,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, const std::vector& norm) { U32 count = pos.size(); - llassert(norm.size() >= pos.size()); + llassert_always(norm.size() >= pos.size()); + llassert_always(count > 0) ; unbind(); @@ -448,7 +450,7 @@ void LLVertexBuffer::clientCopy(F64 max_time) //---------------------------------------------------------------------------- -LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : +LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage, bool strided) : LLRefCount(), mNumVerts(0), @@ -466,7 +468,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mFilthy(FALSE), mEmpty(TRUE), mResized(FALSE), - mDynamicSize(FALSE) + mDynamicSize(FALSE), + mIsStrided(strided), + mStride(0) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (!sEnableVBOs) @@ -483,20 +487,27 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : { mUsage = GL_STREAM_DRAW_ARB; } - - S32 stride = calcStride(typemask, mOffsets); + + //zero out offsets + for (U32 i = 0; i < TYPE_MAX; i++) + { + mOffsets[i] = 0; + } mTypeMask = typemask; - mStride = stride; + mSize = 0; mAlignedOffset = 0; mAlignedIndexOffset = 0; + + if(sForceStrideMode) + mIsStrided = sForceStrideMode == 1; + sCount++; } -//static -S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets) +S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices) { - S32 stride = 0; + S32 offset = 0; for (S32 i=0; i(src); mAlignedIndexOffset = mMappedIndexData - src; stop_glerror(); @@ -1095,7 +1146,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access) sMappedCount++; } - return mMappedIndexData ; + return mMappedIndexData + sizeof(U16)*index; } void LLVertexBuffer::unmapBuffer(S32 type) @@ -1182,7 +1233,7 @@ template struct VertexBufferStrider { if (type == LLVertexBuffer::TYPE_INDEX) { - volatile U8* ptr = vbo.mapIndexBuffer(); + volatile U8* ptr = vbo.mapIndexBuffer(index); if (ptr == NULL) { @@ -1190,16 +1241,16 @@ template struct VertexBufferStrider return FALSE; } - strider = (T*)(ptr + index*sizeof(T)); + strider = (T*)ptr; strider.setStride(0); strider.setTypeSize(0); return TRUE; } else if (vbo.hasDataType(type)) { - S32 stride = vbo.getStride(); - volatile U8* ptr = vbo.mapVertexBuffer(type); - S32 size = LLVertexBuffer::sTypeSize[type]; + S32 stride = vbo.getStride(type); + + volatile U8* ptr = vbo.mapVertexBuffer(type,index); if (ptr == NULL) { @@ -1207,9 +1258,11 @@ template struct VertexBufferStrider return FALSE; } - strider = (T*)(ptr + vbo.getOffset(type) + index*stride); + + strider = (T*)ptr; + strider.setStride(stride); - strider.setTypeSize(size); + strider.setTypeSize(LLVertexBuffer::sTypeSize[type]); return TRUE; } else @@ -1272,25 +1325,6 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, S32 in return VertexBufferStrider::get(*this, strider, index); } -void LLVertexBuffer::setStride(S32 type, S32 new_stride) -{ - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - if (mNumVerts) - { - llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; - } - // This code assumes that setStride() will only be called once per VBO per type. - S32 delta = new_stride - sTypeSize[type]; - for (S32 i=type+1; iValue 0 - ResetFocusOnSelfClick + ShyotlRenderVBOStrideMode + + Comment + 0 = Standard behavior +1 = Force strided VBOs +2 = Force unstrided(dense) VBOs + Persist + 1 + Type + U32 + Value + 0 + + + ResetFocusOnSelfClick Comment Setting this to TRUE resets your camera when you left-click your avatar diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 60a831472..b3cd43bc6 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1806,20 +1806,20 @@ void LLVertexBufferAvatar::setupVertexBuffer(U32 data_mask) const { volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; - glVertexPointer(3,GL_FLOAT, mStride, (void*)(base + 0)); - glNormalPointer(GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_NORMAL])); - glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0)); + glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL])); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); - set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], mStride, (F32*)(base + mOffsets[TYPE_WEIGHT])); + set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], getStride(TYPE_WEIGHT), (F32*)(base + mOffsets[TYPE_WEIGHT])); if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_BUMP) { - set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], mStride, (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); + set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], getStride(TYPE_BINORMAL), (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); } if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH) { - set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], mStride, (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], getStride(TYPE_CLOTHWEIGHT), (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } } else diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a58d38329..e19923f5a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -646,6 +646,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); //See LL jira VWR-3258 comment section. Implemented by LL in 2.1 -Shyotl gSavedSettings.getControl("ShyotlRenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("ShyotlRenderVBOStrideMode")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("SianaRenderOmitBlankVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2)); gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 3d36a99fe..1f0365761 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -64,23 +64,75 @@ public: mTypeMask |= MAP_TEXCOORD2 | MAP_TEXCOORD3; }; - /*// virtual + // virtual void setupVertexBuffer(U32 data_mask) const - { - if (LLDrawPoolTerrain::getDetailMode() == 0 || LLPipeline::sShadowRender) + { + volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; + + //assume tex coords 2 and 3 are present + U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3; + + if ((data_mask & type_mask) != data_mask) { - LLVertexBuffer::setupVertexBuffer(data_mask); + llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; } - else if (data_mask & LLVertexBuffer::MAP_TEXCOORD1) + + if (data_mask & MAP_NORMAL) { - LLVertexBuffer::setupVertexBuffer(data_mask); + glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL])); } - else + if (data_mask & MAP_TEXCOORD3) + { //substitute tex coord 0 for tex coord 3 + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD2) + { //substitute tex coord 0 for tex coord 2 + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD1) { - LLVertexBuffer::setupVertexBuffer(data_mask); + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD1), (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - llglassertok(); - }*/ + if (data_mask & MAP_BINORMAL) + { + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, getStride(TYPE_BINORMAL), (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD0) + { + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + } + if (data_mask & MAP_COLOR) + { + glColorPointer(4, GL_UNSIGNED_BYTE, getStride(TYPE_COLOR), (void*)(base + mOffsets[TYPE_COLOR])); + } + + if (data_mask & MAP_WEIGHT) + { + glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT), (void*)(base + mOffsets[TYPE_WEIGHT])); + } + + if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) + { + glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT4), (void*)(base+mOffsets[TYPE_WEIGHT4])); + } + + if (data_mask & MAP_CLOTHWEIGHT) + { + glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, getStride(TYPE_CLOTHWEIGHT), (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + } + if (data_mask & MAP_VERTEX) + { + glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0)); + } + } }; //============================================================================ diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6062461a5..5ae0c27ba 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3048,8 +3048,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) static const LLCachedControl render_max_vbo_size("RenderMaxVBOSize", 512); static const LLCachedControl render_max_node_size("RenderMaxNodeSize",8192); - U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); - U32 max_total = (render_max_node_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); + U32 max_total = (render_max_node_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); U32 cur_total = 0; @@ -3552,7 +3552,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //calculate maximum number of vertices to store in a single buffer static const LLCachedControl render_max_vbo_size("RenderMaxVBOSize", 512); - U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); if (!distance_sort) diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 8d63b069c..92bc8b65f 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -336,7 +336,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024; const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; - const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcStride(data_mask); + const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask); const U32 total_stacks = getNumStacks(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8103ebefb..e8376c57e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -372,6 +372,7 @@ void LLPipeline::init() sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); + LLVertexBuffer::sForceStrideMode = gSavedSettings.getU32("ShyotlRenderVBOStrideMode"); LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); @@ -5822,6 +5823,7 @@ void LLPipeline::resetVertexBuffers() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); + LLVertexBuffer::sForceStrideMode = gSavedSettings.getU32("ShyotlRenderVBOStrideMode"); LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter)