VBO updates from Vir Lindens shining fixes. VBO mapping perf improvement. Alpha rigged attachments render fix, hopefully. Crashfix in void pushWireframe.
This commit is contained in:
@@ -2,31 +2,25 @@
|
||||
* @file llvertexbuffer.cpp
|
||||
* @brief LLVertexBuffer implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -155,7 +149,7 @@ U32 wpo2(U32 i)
|
||||
return r;
|
||||
}
|
||||
|
||||
U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
{
|
||||
llassert(nhpo2(size) == size);
|
||||
|
||||
@@ -166,20 +160,24 @@ U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
mFreeList.resize(i+1);
|
||||
}
|
||||
|
||||
U8* ret = NULL;
|
||||
volatile U8* ret = NULL;
|
||||
|
||||
if (mFreeList[i].empty())
|
||||
{
|
||||
//make a new buffer
|
||||
glGenBuffersARB(1, &name);
|
||||
glBindBufferARB(mType, name);
|
||||
glBufferDataARB(mType, size, 0, mUsage);
|
||||
LLVertexBuffer::sAllocatedBytes += size;
|
||||
|
||||
if (LLVertexBuffer::sDisableVBOMapping)
|
||||
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
glBufferDataARB(mType, size, 0, mUsage);
|
||||
ret = (U8*) ll_aligned_malloc_16(size);
|
||||
}
|
||||
else
|
||||
{ //always use a true hint of static draw when allocating non-client-backed buffers
|
||||
glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
glBindBufferARB(mType, 0);
|
||||
}
|
||||
else
|
||||
@@ -195,7 +193,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLVBOPool::release(U32 name, U8* buffer, U32 size)
|
||||
void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
|
||||
{
|
||||
llassert(nhpo2(size) == size);
|
||||
|
||||
@@ -208,8 +206,15 @@ void LLVBOPool::release(U32 name, U8* buffer, U32 size)
|
||||
rec.mClientData = buffer;
|
||||
|
||||
sBytesPooled += size;
|
||||
|
||||
mFreeList[i].push_back(rec);
|
||||
|
||||
if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
glDeleteBuffersARB(1, &rec.mGLName);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFreeList[i].push_back(rec);
|
||||
}
|
||||
}
|
||||
|
||||
void LLVBOPool::cleanup()
|
||||
@@ -228,7 +233,7 @@ void LLVBOPool::cleanup()
|
||||
|
||||
if (r.mClientData)
|
||||
{
|
||||
ll_aligned_free_16(r.mClientData);
|
||||
ll_aligned_free_16((void*) r.mClientData);
|
||||
}
|
||||
|
||||
l.pop_front();
|
||||
@@ -543,7 +548,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
|
||||
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
|
||||
{
|
||||
validateRange(start, end, count, indices_offset);
|
||||
|
||||
mMappable = FALSE;
|
||||
gGL.syncMatrices();
|
||||
|
||||
llassert(mNumVerts >= 0);
|
||||
@@ -598,7 +603,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
|
||||
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
||||
{
|
||||
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
|
||||
|
||||
mMappable = FALSE;
|
||||
gGL.syncMatrices();
|
||||
|
||||
llassert(mNumIndices >= 0);
|
||||
@@ -644,7 +649,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
||||
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
{
|
||||
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
|
||||
|
||||
mMappable = FALSE;
|
||||
gGL.syncMatrices();
|
||||
|
||||
llassert(mNumVerts >= 0);
|
||||
@@ -794,9 +799,25 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
|
||||
if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
|
||||
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
|
||||
mUsage = GL_DYNAMIC_DRAW_ARB;
|
||||
if (sDisableVBOMapping)
|
||||
{ //always use stream draw if VBO mapping is disabled
|
||||
mUsage = GL_STREAM_DRAW_ARB;
|
||||
}
|
||||
else
|
||||
{
|
||||
mUsage = GL_DYNAMIC_DRAW_ARB;
|
||||
}
|
||||
}
|
||||
|
||||
if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
|
||||
{
|
||||
mMappable = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMappable = FALSE;
|
||||
}
|
||||
|
||||
//zero out offsets
|
||||
for (U32 i = 0; i < TYPE_MAX; i++)
|
||||
{
|
||||
@@ -812,6 +833,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
sCount++;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices)
|
||||
{
|
||||
S32 offset = 0;
|
||||
@@ -944,11 +966,11 @@ void LLVertexBuffer::releaseBuffer()
|
||||
{
|
||||
if (mUsage == GL_STREAM_DRAW_ARB)
|
||||
{
|
||||
sStreamVBOPool.release(mGLBuffer, /*(U8*)*/mMappedData, mSize);
|
||||
sStreamVBOPool.release(mGLBuffer, mMappedData, mSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
sDynamicVBOPool.release(mGLBuffer, /*(U8*)*/mMappedData, mSize);
|
||||
sDynamicVBOPool.release(mGLBuffer, mMappedData, mSize);
|
||||
}
|
||||
|
||||
mGLBuffer = 0;
|
||||
@@ -961,11 +983,11 @@ void LLVertexBuffer::releaseIndices()
|
||||
{
|
||||
if (mUsage == GL_STREAM_DRAW_ARB)
|
||||
{
|
||||
sStreamIBOPool.release(mGLIndices, /*(U8*)*/mMappedIndexData, mIndicesSize);
|
||||
sStreamIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
sDynamicIBOPool.release(mGLIndices, /*(U8*)*/mMappedIndexData, mIndicesSize);
|
||||
sDynamicIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);
|
||||
}
|
||||
|
||||
mGLIndices = 0;
|
||||
@@ -1048,7 +1070,7 @@ void LLVertexBuffer::destroyGLBuffer()
|
||||
}
|
||||
else
|
||||
{
|
||||
FREE_MEM(sPrivatePoolp, /*(U8*)*/mMappedData) ;
|
||||
FREE_MEM(sPrivatePoolp, (void*) mMappedData) ;
|
||||
mMappedData = NULL;
|
||||
mEmpty = TRUE;
|
||||
}
|
||||
@@ -1069,7 +1091,7 @@ void LLVertexBuffer::destroyGLIndices()
|
||||
}
|
||||
else
|
||||
{
|
||||
FREE_MEM(sPrivatePoolp, /*(U8*)*/mMappedIndexData) ;
|
||||
FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ;
|
||||
mMappedIndexData = NULL;
|
||||
mEmpty = TRUE;
|
||||
}
|
||||
@@ -1289,7 +1311,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
}
|
||||
|
||||
// Map for data access
|
||||
/*volatile */U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
|
||||
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
|
||||
{
|
||||
bindGLBuffer(true);
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
@@ -1304,7 +1326,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
|
||||
if (useVBOs())
|
||||
{
|
||||
if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
|
||||
if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
|
||||
{
|
||||
if (count == -1)
|
||||
{
|
||||
@@ -1329,7 +1351,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
if (!mapped)
|
||||
{
|
||||
//not already mapped, map new region
|
||||
MappedRegion region(type, !sDisableVBOMapping && map_range ? -1 : index, count);
|
||||
MappedRegion region(type, mMappable && map_range ? -1 : index, count);
|
||||
mMappedVertexRegions.push_back(region);
|
||||
}
|
||||
}
|
||||
@@ -1345,13 +1367,13 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
sMappedCount++;
|
||||
stop_glerror();
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
if(!mMappable)
|
||||
{
|
||||
map_range = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
U8* src = NULL;
|
||||
volatile U8* src = NULL;
|
||||
waitFence();
|
||||
if (gGLManager.mHasMapBufferRange)
|
||||
{
|
||||
@@ -1408,7 +1430,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
|
||||
llassert(src != NULL);
|
||||
|
||||
mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
|
||||
mMappedData = LL_NEXT_ALIGNED_ADDRESS<volatile U8>(src);
|
||||
mAlignedOffset = mMappedData - src;
|
||||
|
||||
stop_glerror();
|
||||
@@ -1421,7 +1443,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
//check the availability of memory
|
||||
LLMemory::logMemoryInfo(TRUE) ;
|
||||
|
||||
if(!sDisableVBOMapping)
|
||||
if(mMappable)
|
||||
{
|
||||
//--------------------
|
||||
//print out more debug info before crash
|
||||
@@ -1453,7 +1475,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
map_range = false;
|
||||
}
|
||||
|
||||
if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
|
||||
if (map_range && gGLManager.mHasMapBufferRange && mMappable)
|
||||
{
|
||||
return mMappedData;
|
||||
}
|
||||
@@ -1463,7 +1485,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
}
|
||||
}
|
||||
|
||||
/*volatile */U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
|
||||
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
bindGLIndices(true);
|
||||
@@ -1478,7 +1500,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
|
||||
if (useVBOs())
|
||||
{
|
||||
if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
|
||||
if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
|
||||
{
|
||||
if (count == -1)
|
||||
{
|
||||
@@ -1500,7 +1522,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
if (!mapped)
|
||||
{
|
||||
//not already mapped, map new region
|
||||
MappedRegion region(TYPE_INDEX, !sDisableVBOMapping && map_range ? -1 : index, count);
|
||||
MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count);
|
||||
mMappedIndexRegions.push_back(region);
|
||||
}
|
||||
}
|
||||
@@ -1529,13 +1551,13 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
}
|
||||
}
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
if(!mMappable)
|
||||
{
|
||||
map_range = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
U8* src = NULL;
|
||||
volatile U8* src = NULL;
|
||||
waitFence();
|
||||
if (gGLManager.mHasMapBufferRange)
|
||||
{
|
||||
@@ -1592,7 +1614,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
log_glerror();
|
||||
LLMemory::logMemoryInfo(TRUE) ;
|
||||
|
||||
if(!sDisableVBOMapping)
|
||||
if(mMappable)
|
||||
{
|
||||
GLint buff;
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
@@ -1614,7 +1636,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
|
||||
map_range = false;
|
||||
}
|
||||
|
||||
if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
|
||||
if (map_range && gGLManager.mHasMapBufferRange && mMappable)
|
||||
{
|
||||
return mMappedIndexData;
|
||||
}
|
||||
@@ -1639,7 +1661,7 @@ void LLVertexBuffer::unmapBuffer()
|
||||
bindGLBuffer(true);
|
||||
updated_all = mIndexLocked; //both vertex and index buffers done updating
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
if(!mMappable)
|
||||
{
|
||||
if (!mMappedVertexRegions.empty())
|
||||
{
|
||||
@@ -1649,7 +1671,7 @@ void LLVertexBuffer::unmapBuffer()
|
||||
const MappedRegion& region = mMappedVertexRegions[i];
|
||||
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
|
||||
S32 length = sTypeSize[region.mType]*region.mCount;
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, /*(U8*)*/mMappedData+offset);
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
@@ -1658,7 +1680,7 @@ void LLVertexBuffer::unmapBuffer()
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), /*(U8*)*/mMappedData);
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (U8*) mMappedData);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
@@ -1704,7 +1726,7 @@ void LLVertexBuffer::unmapBuffer()
|
||||
if (mMappedIndexData && mIndexLocked)
|
||||
{
|
||||
bindGLIndices();
|
||||
if(sDisableVBOMapping)
|
||||
if(!mMappable)
|
||||
{
|
||||
if (!mMappedIndexRegions.empty())
|
||||
{
|
||||
@@ -1713,7 +1735,7 @@ void LLVertexBuffer::unmapBuffer()
|
||||
const MappedRegion& region = mMappedIndexRegions[i];
|
||||
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
|
||||
S32 length = sizeof(U16)*region.mCount;
|
||||
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, /*(U8*)*/mMappedIndexData+offset);
|
||||
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
@@ -1722,7 +1744,7 @@ void LLVertexBuffer::unmapBuffer()
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), /*(U8*)*/mMappedIndexData);
|
||||
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (U8*) mMappedIndexData);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
@@ -1783,7 +1805,7 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
{
|
||||
if (type == LLVertexBuffer::TYPE_INDEX)
|
||||
{
|
||||
/*volatile*/ U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
|
||||
volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
@@ -1798,8 +1820,8 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
else if (vbo.hasDataType(type))
|
||||
{
|
||||
S32 stride = LLVertexBuffer::sTypeSize[type];
|
||||
|
||||
/*volatile */U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
|
||||
|
||||
volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
@@ -2117,7 +2139,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
stop_glerror();
|
||||
U8* base = useVBOs() ? (U8*)mAlignedOffset : /*(U8*)*/mMappedData;
|
||||
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
|
||||
|
||||
/*if ((data_mask & mTypeMask) != data_mask)
|
||||
{
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llvertexbuffer.h
|
||||
* @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2003-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -67,10 +61,10 @@ public:
|
||||
U32 mType;
|
||||
|
||||
//size MUST be a power of 2
|
||||
U8* allocate(U32& name, U32 size);
|
||||
volatile U8* allocate(U32& name, U32 size);
|
||||
|
||||
//size MUST be the size provided to allocate that returned the given name
|
||||
void release(U32 name, U8* buffer, U32 size);
|
||||
void release(U32 name, volatile U8* buffer, U32 size);
|
||||
|
||||
//destroy all records in mFreeList
|
||||
void cleanup();
|
||||
@@ -79,7 +73,7 @@ public:
|
||||
{
|
||||
public:
|
||||
U32 mGLName;
|
||||
U8* mClientData;
|
||||
volatile U8* mClientData;
|
||||
};
|
||||
|
||||
typedef std::list<Record> record_list_t;
|
||||
@@ -215,8 +209,8 @@ public:
|
||||
LLVertexBuffer(U32 typemask, S32 usage);
|
||||
|
||||
// map for data access
|
||||
/*volatile */U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
|
||||
/*volatile */U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
|
||||
volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
|
||||
volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
|
||||
|
||||
// set for rendering
|
||||
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
|
||||
@@ -251,17 +245,18 @@ public:
|
||||
S32 getNumVerts() const { return mNumVerts; }
|
||||
S32 getNumIndices() const { return mNumIndices; }
|
||||
|
||||
/*volatile */U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
|
||||
/*volatile */U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
|
||||
volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
|
||||
volatile U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
|
||||
U32 getTypeMask() const { return mTypeMask; }
|
||||
bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
|
||||
S32 getSize() const;
|
||||
S32 getIndicesSize() const { return mIndicesSize; }
|
||||
/*volatile */U8* getMappedData() const { return mMappedData; }
|
||||
/*volatile */U8* getMappedIndices() const { return mMappedIndexData; }
|
||||
volatile U8* getMappedData() const { return mMappedData; }
|
||||
volatile U8* getMappedIndices() const { return mMappedIndexData; }
|
||||
S32 getOffset(S32 type) const { return mOffsets[type]; }
|
||||
S32 getUsage() const { return mUsage; }
|
||||
|
||||
BOOL isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? TRUE : FALSE; }
|
||||
|
||||
void draw(U32 mode, U32 count, U32 indices_offset) const;
|
||||
void drawArrays(U32 mode, U32 offset, U32 count) const;
|
||||
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
|
||||
@@ -285,12 +280,13 @@ protected:
|
||||
U32 mGLIndices; // GL IBO handle
|
||||
U32 mGLArray; // GL VAO handle
|
||||
|
||||
/*volatile */U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
|
||||
/*volatile */U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
|
||||
volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
|
||||
volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
|
||||
BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory
|
||||
BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory
|
||||
BOOL mFinal; // if TRUE, buffer can not be mapped again
|
||||
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
|
||||
mutable BOOL mMappable; // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
|
||||
S32 mOffsets[TYPE_MAX];
|
||||
|
||||
std::vector<MappedRegion> mMappedVertexRegions;
|
||||
|
||||
@@ -1301,7 +1301,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
||||
face->setGeomIndex(0);
|
||||
face->setIndicesIndex(0);
|
||||
|
||||
if (buffer.isNull() || buffer->getTypeMask() != data_mask)
|
||||
if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
|
||||
{ //make a new buffer
|
||||
if (sShaderLevel > 0)
|
||||
{
|
||||
@@ -1335,7 +1335,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
||||
LLMatrix3 mat_normal(mat3);
|
||||
|
||||
//let getGeometryVolume know if alpha should override shiny
|
||||
if (face->getFaceColor().mV[3] < 1.f)
|
||||
U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
|
||||
|
||||
if (type == LLDrawPool::POOL_ALPHA)
|
||||
{
|
||||
face->setPoolType(LLDrawPool::POOL_ALPHA);
|
||||
}
|
||||
|
||||
@@ -695,6 +695,49 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of
|
||||
tex_coord.mV[1] = t;
|
||||
}
|
||||
|
||||
// Transform the texture coordinates for this face.
|
||||
static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVector4Logical& mask, const LLVector4a& rot0, const LLVector4a& rot1, const LLVector4a& offset, const LLVector4a& scale)
|
||||
{
|
||||
//tex coord is two coords, <s0, t0, s1, t1>
|
||||
LLVector4a st;
|
||||
|
||||
// Texture transforms are done about the center of the face.
|
||||
st.setAdd(tex_coord, trans);
|
||||
|
||||
// Handle rotation
|
||||
LLVector4a rot_st;
|
||||
|
||||
// <s0 * cosAng, s0*-sinAng, s1*cosAng, s1*-sinAng>
|
||||
LLVector4a s0;
|
||||
s0.splat(st, 0);
|
||||
LLVector4a s1;
|
||||
s1.splat(st, 2);
|
||||
LLVector4a ss;
|
||||
ss.setSelectWithMask(mask, s1, s0);
|
||||
|
||||
LLVector4a a;
|
||||
a.setMul(rot0, ss);
|
||||
|
||||
// <t0*sinAng, t0*cosAng, t1*sinAng, t1*cosAng>
|
||||
LLVector4a t0;
|
||||
t0.splat(st, 1);
|
||||
LLVector4a t1;
|
||||
t1.splat(st, 3);
|
||||
LLVector4a tt;
|
||||
tt.setSelectWithMask(mask, t1, t0);
|
||||
|
||||
LLVector4a b;
|
||||
b.setMul(rot1, tt);
|
||||
|
||||
st.setAdd(a,b);
|
||||
|
||||
// Then scale
|
||||
st.mul(scale);
|
||||
|
||||
// Then offset
|
||||
tex_coord.setAdd(st, offset);
|
||||
}
|
||||
|
||||
|
||||
bool less_than_max_mag(const LLVector4a& vec)
|
||||
{
|
||||
@@ -1069,7 +1112,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
updateRebuildFlags();
|
||||
}
|
||||
|
||||
bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
|
||||
|
||||
//don't use map range (generates many redundant unmap calls)
|
||||
bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
|
||||
|
||||
if (mVertexBuffer.notNull())
|
||||
{
|
||||
@@ -1095,16 +1140,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
}
|
||||
|
||||
LLStrider<LLVector3> vert;
|
||||
LLVector4a* vertices = NULL;
|
||||
LLStrider<LLVector2> tex_coords;
|
||||
LLStrider<LLVector2> tex_coords2;
|
||||
LLVector4a* normals = NULL;
|
||||
LLStrider<LLVector3> norm;
|
||||
LLStrider<LLColor4U> colors;
|
||||
LLVector4a* binormals = NULL;
|
||||
LLStrider<LLVector3> binorm;
|
||||
LLStrider<U16> indicesp;
|
||||
LLVector4a* weights = NULL;
|
||||
LLStrider<LLVector4> wght;
|
||||
|
||||
BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
|
||||
@@ -1172,7 +1213,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
LLFastTimer t(LLFastTimer::FTM_FACE_GEOM_INDEX);
|
||||
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range);
|
||||
|
||||
__m128i* dst = (__m128i*) indicesp.get();
|
||||
volatile __m128i* dst = (__m128i*) indicesp.get();
|
||||
__m128i* src = (__m128i*) vf.mIndices;
|
||||
__m128i offset = _mm_set1_epi16(index_offset);
|
||||
|
||||
@@ -1181,12 +1222,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
for (S32 i = 0; i < end; i++)
|
||||
{
|
||||
__m128i res = _mm_add_epi16(src[i], offset);
|
||||
_mm_storeu_si128(dst+i, res);
|
||||
_mm_storeu_si128((__m128i*) dst++, res);
|
||||
}
|
||||
|
||||
for (S32 i = end*8; i < num_indices; ++i)
|
||||
{
|
||||
indicesp[i] = vf.mIndices[i]+index_offset;
|
||||
//LLFastTimer t(LLFastTimer::FTM_FACE_GEOM_INDEX_TAIL);
|
||||
U16* idx = (U16*) dst;
|
||||
|
||||
for (S32 i = end*8; i < num_indices; ++i)
|
||||
{
|
||||
*idx++ = vf.mIndices[i]+index_offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (map_range)
|
||||
@@ -1351,11 +1397,37 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
}
|
||||
else
|
||||
{
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
F32* dst = (F32*) tex_coords.get();
|
||||
LLVector4a* src = (LLVector4a*) vf.mTexCoords;
|
||||
|
||||
LLVector4a trans;
|
||||
trans.splat(-0.5f);
|
||||
|
||||
LLVector4a rot0;
|
||||
rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
|
||||
|
||||
LLVector4a rot1;
|
||||
rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
|
||||
|
||||
LLVector4a scale;
|
||||
scale.set(ms, mt, ms, mt);
|
||||
|
||||
LLVector4a offset;
|
||||
offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
|
||||
|
||||
LLVector4Logical mask;
|
||||
mask.clear();
|
||||
mask.setElement<2>();
|
||||
mask.setElement<3>();
|
||||
|
||||
U32 count = num_vertices/2 + num_vertices%2;
|
||||
|
||||
for (U32 i = 0; i < count; i++)
|
||||
{
|
||||
LLVector2 tc(vf.mTexCoords[i]);
|
||||
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
|
||||
*tex_coords++ = tc;
|
||||
LLVector4a res = *src++;
|
||||
xform4a(res, trans, mask, rot0, rot1, offset, scale);
|
||||
res.store4a(dst);
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1526,44 +1598,53 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
llassert(num_vertices > 0);
|
||||
|
||||
mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
|
||||
vertices = (LLVector4a*) vert.get();
|
||||
|
||||
|
||||
|
||||
LLMatrix4a mat_vert;
|
||||
mat_vert.loadu(mat_vert_in);
|
||||
|
||||
LLVector4a* src = vf.mPositions;
|
||||
LLVector4a* dst = vertices;
|
||||
volatile F32* dst = (volatile F32*) vert.get();
|
||||
|
||||
LLVector4a* end = dst+num_vertices;
|
||||
do
|
||||
{
|
||||
mat_vert.affineTransform(*src++, *dst++);
|
||||
}
|
||||
while(dst < end);
|
||||
volatile F32* end = dst+num_vertices*4;
|
||||
LLVector4a res;
|
||||
|
||||
LLVector4a texIdx;
|
||||
|
||||
F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0);
|
||||
|
||||
llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
|
||||
F32 *index_dst = (F32*) vertices;
|
||||
F32 *index_end = (F32*) end;
|
||||
|
||||
index_dst += 3;
|
||||
index_end += 3;
|
||||
do
|
||||
{
|
||||
*index_dst = index;
|
||||
index_dst += 4;
|
||||
}
|
||||
while (index_dst < index_end);
|
||||
LLVector4Logical mask;
|
||||
mask.clear();
|
||||
mask.setElement<3>();
|
||||
|
||||
S32 aligned_pad_vertices = mGeomCount - num_vertices;
|
||||
LLVector4a* last_vec = end - 1;
|
||||
while (aligned_pad_vertices > 0)
|
||||
texIdx.set(0,0,0,index);
|
||||
|
||||
{
|
||||
--aligned_pad_vertices;
|
||||
*dst++ = *last_vec;
|
||||
LLVector4a tmp;
|
||||
|
||||
do
|
||||
{
|
||||
mat_vert.affineTransform(*src++, res);
|
||||
tmp.setSelectWithMask(mask, texIdx, res);
|
||||
tmp.store4a((F32*) dst);
|
||||
dst += 4;
|
||||
}
|
||||
while(dst < end);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
S32 aligned_pad_vertices = mGeomCount - num_vertices;
|
||||
res.set(res[0], res[1], res[2], 0.f);
|
||||
|
||||
while (aligned_pad_vertices > 0)
|
||||
{
|
||||
--aligned_pad_vertices;
|
||||
res.store4a((F32*) dst);
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (map_range)
|
||||
{
|
||||
mVertexBuffer->flush();
|
||||
@@ -1574,14 +1655,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_FACE_GEOM_NORMAL);
|
||||
mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
|
||||
normals = (LLVector4a*) norm.get();
|
||||
F32* normals = (F32*) norm.get();
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector4a normal;
|
||||
mat_normal.rotate(vf.mNormals[i], normal);
|
||||
normal.normalize3fast();
|
||||
normals[i] = normal;
|
||||
normal.store4a(normals);
|
||||
normals += 4;
|
||||
}
|
||||
|
||||
if (map_range)
|
||||
@@ -1594,14 +1676,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_FACE_GEOM_BINORMAL);
|
||||
mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
|
||||
binormals = (LLVector4a*) binorm.get();
|
||||
F32* binormals = (F32*) binorm.get();
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector4a binormal;
|
||||
mat_normal.rotate(vf.mBinormals[i], binormal);
|
||||
binormal.normalize3fast();
|
||||
binormals[i] = binormal;
|
||||
binormal.store4a(binormals);
|
||||
binormals += 4;
|
||||
}
|
||||
|
||||
if (map_range)
|
||||
@@ -1614,8 +1697,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_FACE_GEOM_WEIGHTS);
|
||||
mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
|
||||
weights = (LLVector4a*) wght.get();
|
||||
LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
|
||||
F32* weights = (F32*) wght.get();
|
||||
LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
|
||||
if (map_range)
|
||||
{
|
||||
mVertexBuffer->flush();
|
||||
@@ -1634,7 +1717,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
src.loadua((F32*) vec);
|
||||
|
||||
LLVector4a* dst = (LLVector4a*) colors.get();
|
||||
F32* dst = (F32*) colors.get();
|
||||
S32 num_vecs = num_vertices/4;
|
||||
if (num_vertices%4 > 0)
|
||||
{
|
||||
@@ -1643,7 +1726,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
for (S32 i = 0; i < num_vecs; i++)
|
||||
{
|
||||
dst[i] = src;
|
||||
src.store4a(dst);
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
if (map_range)
|
||||
@@ -1673,7 +1757,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
src.loadua((F32*) vec);
|
||||
|
||||
LLVector4a* dst = (LLVector4a*) emissive.get();
|
||||
F32* dst = (F32*) emissive.get();
|
||||
S32 num_vecs = num_vertices/4;
|
||||
if (num_vertices%4 > 0)
|
||||
{
|
||||
@@ -1682,7 +1766,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
for (S32 i = 0; i < num_vecs; i++)
|
||||
{
|
||||
dst[i] = src;
|
||||
src.store4a(dst);
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
if (map_range)
|
||||
|
||||
@@ -5571,38 +5571,37 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power)
|
||||
//helper function for pushing relevant vertices from drawable to GL
|
||||
void pushWireframe(LLDrawable* drawable)
|
||||
{
|
||||
if (drawable->isState(LLDrawable::RIGGED))
|
||||
{ //render straight from rigged volume if this is a rigged attachment
|
||||
LLVOVolume* vobj = drawable->getVOVolume();
|
||||
if (vobj)
|
||||
{
|
||||
vobj->updateRiggedVolume();
|
||||
LLRiggedVolume* rigged_volume = vobj->getRiggedVolume();
|
||||
if (rigged_volume)
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
gGL.pushMatrix();
|
||||
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
|
||||
for (S32 i = 0; i < rigged_volume->getNumVolumeFaces(); ++i)
|
||||
{
|
||||
const LLVolumeFace& face = rigged_volume->getVolumeFace(i);
|
||||
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
|
||||
}
|
||||
gGL.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
LLVOVolume* vobj = drawable->getVOVolume();
|
||||
if (vobj)
|
||||
{
|
||||
for (S32 i = 0; i < drawable->getNumFaces(); ++i)
|
||||
LLVertexBuffer::unbind();
|
||||
gGL.pushMatrix();
|
||||
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
|
||||
|
||||
LLVolume* volume = NULL;
|
||||
|
||||
if (drawable->isState(LLDrawable::RIGGED))
|
||||
{
|
||||
LLFace* face = drawable->getFace(i);
|
||||
if (face->verify())
|
||||
vobj->updateRiggedVolume();
|
||||
volume = vobj->getRiggedVolume();
|
||||
}
|
||||
else
|
||||
{
|
||||
volume = vobj->getVolume();
|
||||
}
|
||||
|
||||
if (volume)
|
||||
{
|
||||
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
|
||||
{
|
||||
pushVerts(face, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
const LLVolumeFace& face = volume->getVolumeFace(i);
|
||||
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
|
||||
}
|
||||
}
|
||||
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLSelectNode::renderOneWireframe(const LLColor4& color)
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
|
||||
#include "llspatialpartition.h"
|
||||
|
||||
#include "llappviewer.h"
|
||||
#include "lltexturecache.h"
|
||||
#include "lltexturefetch.h"
|
||||
#include "llimageworker.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llvovolume.h"
|
||||
@@ -43,14 +47,13 @@
|
||||
#include "llface.h"
|
||||
#include "llfloatertools.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llagent.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llcamera.h"
|
||||
#include "pipeline.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llrender.h"
|
||||
#include "lloctree.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llphysicsshapebuilderutil.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llvolumemgr.h"
|
||||
#include "llglslshader.h"
|
||||
@@ -262,7 +265,7 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
|
||||
|
||||
void LLSpatialGroup::buildOcclusion()
|
||||
{
|
||||
if (mOcclusionVerts.isNull())
|
||||
//if (mOcclusionVerts.isNull())
|
||||
{
|
||||
|
||||
mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,
|
||||
@@ -608,7 +611,9 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
|
||||
if (vertex_count > 0 && index_count > 0)
|
||||
{ //create vertex buffer containing volume geometry for this node
|
||||
group->mBuilt = 1.f;
|
||||
if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
|
||||
if (group->mVertexBuffer.isNull() ||
|
||||
!group->mVertexBuffer->isWriteable() ||
|
||||
(group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
|
||||
{
|
||||
group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
|
||||
group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
|
||||
@@ -1106,6 +1111,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
|
||||
for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
|
||||
{
|
||||
mOcclusionQuery[i] = 0;
|
||||
mOcclusionIssued[i] = 0;
|
||||
mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
|
||||
mVisible[i] = 0;
|
||||
}
|
||||
@@ -1440,10 +1446,27 @@ void LLSpatialGroup::checkOcclusion()
|
||||
}
|
||||
else if (isOcclusionState(QUERY_PENDING))
|
||||
{ //otherwise, if a query is pending, read it back
|
||||
|
||||
GLuint available = 0;
|
||||
if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
|
||||
{
|
||||
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
|
||||
|
||||
if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
|
||||
{ //query was issued last frame, wait until it's available
|
||||
S32 max_loop = 1024;
|
||||
//LLFastTimer t(LLFastTimer::FTM_OCCLUSION_WAIT);
|
||||
while (!available && max_loop-- > 0)
|
||||
{
|
||||
F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
|
||||
//do some usefu work while we wait
|
||||
LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
|
||||
LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
|
||||
LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
|
||||
|
||||
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1549,6 +1572,8 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
|
||||
|
||||
{
|
||||
//LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
|
||||
//store which frame this query was issued on
|
||||
mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount;
|
||||
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
|
||||
mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
|
||||
@@ -2987,11 +3012,7 @@ void renderRaycast(LLDrawable* drawablep)
|
||||
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
|
||||
{
|
||||
const LLVolumeFace& face = volume->getVolumeFace(i);
|
||||
if (!face.mOctree)
|
||||
{
|
||||
((LLVolumeFace*) &face)->createOctree();
|
||||
}
|
||||
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
|
||||
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
|
||||
@@ -3014,9 +3035,6 @@ void renderRaycast(LLDrawable* drawablep)
|
||||
LLVector4a dir;
|
||||
dir.setSub(enda, starta);
|
||||
|
||||
F32 t = 1.f;
|
||||
|
||||
LLRenderOctreeRaycast render(starta, dir, &t);
|
||||
gGL.flush();
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
@@ -3028,8 +3046,20 @@ void renderRaycast(LLDrawable* drawablep)
|
||||
gGL.syncMatrices();
|
||||
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
|
||||
}
|
||||
|
||||
render.traverse(face.mOctree);
|
||||
|
||||
if (!volume->isUnique())
|
||||
{
|
||||
F32 t = 1.f;
|
||||
|
||||
if (!face.mOctree)
|
||||
{
|
||||
((LLVolumeFace*) &face)->createOctree();
|
||||
}
|
||||
|
||||
LLRenderOctreeRaycast render(starta, dir, &t);
|
||||
|
||||
render.traverse(face.mOctree);
|
||||
}
|
||||
gGL.popMatrix();
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "lldrawpool.h"
|
||||
#include "llface.h"
|
||||
#include "llviewercamera.h"
|
||||
|
||||
#include "llvector4a.h"
|
||||
#include <queue>
|
||||
|
||||
#define SG_STATE_INHERIT_MASK (OCCLUDED)
|
||||
@@ -368,6 +368,7 @@ protected:
|
||||
|
||||
U32 mState;
|
||||
U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
|
||||
U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS];
|
||||
S32 mLODHash;
|
||||
static S32 sLODSeed;
|
||||
|
||||
|
||||
@@ -5457,11 +5457,12 @@ void LLViewerObject::dirtyMesh()
|
||||
{
|
||||
if (mDrawable)
|
||||
{
|
||||
LLSpatialGroup* group = mDrawable->getSpatialGroup();
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
|
||||
/*LLSpatialGroup* group = mDrawable->getSpatialGroup();
|
||||
if (group)
|
||||
{
|
||||
group->dirtyMesh();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
U8* base = useVBOs() ? (U8*) mAlignedOffset : /*(U8*)*/ mMappedData;
|
||||
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
|
||||
|
||||
//assume tex coords 2 and 3 are present
|
||||
U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3;
|
||||
|
||||
@@ -4052,17 +4052,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
|
||||
//create/delete/resize vertex buffer if needed
|
||||
LLVertexBuffer* buffer = NULL;
|
||||
LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
|
||||
|
||||
{ //try to find a buffer to reuse
|
||||
LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
|
||||
|
||||
if (found_iter != group->mBufferMap[mask].end())
|
||||
{
|
||||
if ((U32) buffer_index < found_iter->second.size())
|
||||
if (found_iter != group->mBufferMap[mask].end())
|
||||
{
|
||||
buffer = found_iter->second[buffer_index];
|
||||
if ((U32) buffer_index < found_iter->second.size())
|
||||
{
|
||||
buffer = found_iter->second[buffer_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!buffer)
|
||||
if (!buffer || !buffer->isWriteable())
|
||||
{ //create new buffer if needed
|
||||
buffer = createVertexBuffer(mask, buffer_usage);
|
||||
buffer->allocateBuffer(geom_count, index_count, TRUE);
|
||||
|
||||
@@ -171,7 +171,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
|
||||
indices_per_quad * num_quads);
|
||||
|
||||
LLVertexBuffer* buff = face->getVertexBuffer();
|
||||
if (!buff)
|
||||
if (!buff || !buff->isWriteable())
|
||||
{
|
||||
buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
|
||||
buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
|
||||
|
||||
@@ -775,7 +775,7 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
|
||||
LLStrider<LLColor4U> colorsp;
|
||||
LLStrider<LLVector2> texcoordsp;
|
||||
|
||||
if (mStarsVerts.isNull())
|
||||
if (mStarsVerts.isNull() || !mStarsVerts->isWriteable())
|
||||
{
|
||||
mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
|
||||
mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE);
|
||||
|
||||
Reference in New Issue
Block a user