From 89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:44:50 -0500 Subject: Second Life viewer sources 1.14.0.0 --- linden/indra/llrender/files.lst | 4 +- linden/indra/llrender/llagpmempool.cpp | 194 ------ linden/indra/llrender/llagpmempool.h | 121 ---- linden/indra/llrender/llagpmempoolapple.cpp | 314 ---------- linden/indra/llrender/llagpmempoolapple.h | 95 --- linden/indra/llrender/llagpmempoolarb.cpp | 230 ------- linden/indra/llrender/llagpmempoolarb.h | 103 ---- linden/indra/llrender/llagpmempoolati.cpp | 160 ----- linden/indra/llrender/llagpmempoolati.h | 92 --- linden/indra/llrender/llagpmempoolnv.cpp | 320 ---------- linden/indra/llrender/llagpmempoolnv.h | 95 --- linden/indra/llrender/llfont.h | 1 + linden/indra/llrender/llfontgl.cpp | 12 +- linden/indra/llrender/llgldbg.cpp | 8 +- linden/indra/llrender/llimagegl.cpp | 34 +- linden/indra/llrender/llimagegl.h | 3 +- linden/indra/llrender/llrender.vcproj | 18 +- linden/indra/llrender/llrender_vc8.vcproj | 302 +++++++++ linden/indra/llrender/llvertexbuffer.cpp | 922 ++++++++++++++++++++++++++++ linden/indra/llrender/llvertexbuffer.h | 179 ++++++ linden/indra/llrender/llvertexprogramgl.cpp | 6 +- linden/indra/llrender/text_out.cpp | 4 +- 22 files changed, 1453 insertions(+), 1764 deletions(-) delete mode 100644 linden/indra/llrender/llagpmempool.cpp delete mode 100644 linden/indra/llrender/llagpmempool.h delete mode 100644 linden/indra/llrender/llagpmempoolapple.cpp delete mode 100644 linden/indra/llrender/llagpmempoolapple.h delete mode 100644 linden/indra/llrender/llagpmempoolarb.cpp delete mode 100644 linden/indra/llrender/llagpmempoolarb.h delete mode 100644 linden/indra/llrender/llagpmempoolati.cpp delete mode 100644 linden/indra/llrender/llagpmempoolati.h delete mode 100644 linden/indra/llrender/llagpmempoolnv.cpp delete mode 100644 linden/indra/llrender/llagpmempoolnv.h create mode 100644 linden/indra/llrender/llrender_vc8.vcproj create mode 100644 linden/indra/llrender/llvertexbuffer.cpp create mode 100644 linden/indra/llrender/llvertexbuffer.h (limited to 'linden/indra/llrender') diff --git a/linden/indra/llrender/files.lst b/linden/indra/llrender/files.lst index e7b3cec..a813342 100644 --- a/linden/indra/llrender/files.lst +++ b/linden/indra/llrender/files.lst @@ -1,8 +1,6 @@ -llrender/llagpmempoolarb.cpp -llrender/llagpmempool.cpp llrender/llfont.cpp llrender/llfontgl.cpp llrender/llgldbg.cpp llrender/llimagegl.cpp -llrender/llvertexprogramgl.cpp +llrender/llvertexbuffer.cpp llrender/text_out.cpp diff --git a/linden/indra/llrender/llagpmempool.cpp b/linden/indra/llrender/llagpmempool.cpp deleted file mode 100644 index 39cd3e8..0000000 --- a/linden/indra/llrender/llagpmempool.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @file llagpmempool.cpp - * @brief LLAGPMemPool base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#include "linden_common.h" - -#include "llagpmempool.h" -#include "llgl.h" - -#include "llagpmempoolarb.h" -#include "llagpmempoolnv.h" -#include "llagpmempoolati.h" - -#if LL_DARWIN -#include "llagpmempoolapple.h" -#endif // LL_DARWIN - -//static -S32 LLAGPMemPool::LLFreeBlock::sNumBlocks = 0; - -LLAGPMemPool::LLAGPMemPool() -{ - mSize = 0; - mTotalAllocated = 0; -} - -LLAGPMemPool::~LLAGPMemPool() -{ - mFreeList.deleteAll(); -} - -LLAGPMemPool *LLAGPMemPool::createPool(const U32 size, const BOOL use_vbo) -{ - if (gGLManager.mHasVertexBufferObject && use_vbo) - { - return new LLAGPMemPoolARB(size); - } -#if LL_WINDOWS // *FIX: linux can use these, too, with some work. - if (gGLManager.mHasNVFence) - { - return new LLAGPMemPoolNV(size); - } - else if (gGLManager.mHasATIVAO) - { - return new LLAGPMemPoolATI(size); - } - else -#elif LL_DARWIN - if (gGLManager.mHasAPPLEFence && gGLManager.mHasAPPLEVertexArrayRange) - { - return new LLAGPMemPoolAPPLE(size); - } - else -#endif - { - // No AGP memory allocation at all! - return NULL; - } -} - - -LLAGPMemBlock *LLAGPMemPool::allocBlock(const S32 size) -{ - S32 aligned_size = size; - if (size & 0x0f) - { - aligned_size += 16 - (size & 0x0f); - } - - if (aligned_size > (mSize - mTotalAllocated)) - { - // We're totally out of AGP memory, bail. - return NULL; - } - - LLFreeBlock *free_block = mFreeList.getFirst(); - - while (free_block && free_block->mSize < aligned_size) - { - free_block = free_block->getNext(); - } - - U32 offset = 0; - - if (free_block) - { - if (free_block->mSize == aligned_size) - { - free_block->unlink(); - offset = free_block->mOffset; - delete free_block; - } - else - { - offset = free_block->mOffset + free_block->mSize - aligned_size; - free_block->mSize -= aligned_size; - if (0 == free_block->mSize) - { - free_block->unlink(); - } - } - } - else - { - //llwarns << "LLAGPMemPool unable to allocate " << size << " bytes" << llendl; - return NULL; - } - - mTotalAllocated += aligned_size; - return createBlock(offset, aligned_size); -} - - -void LLAGPMemPool::freeBlock(LLAGPMemBlock *blockp) -{ - if (!blockp->getSize()) - { - return; - } - - LLFreeBlock *prev_free = NULL; - LLFreeBlock *cur_free = mFreeList.getFirst(); - - while (cur_free && blockp->getOffset() > (U32)cur_free->mOffset) - { - prev_free = cur_free; - cur_free = cur_free->getNext(); - } - - LLFreeBlock *new_free = new LLFreeBlock(blockp->getOffset(), blockp->getSize()); - - if (prev_free) - { - prev_free->append(*new_free); - coalesce(new_free); - coalesce(prev_free); - } - else - { - mFreeList.append(*new_free); - coalesce(new_free); - } - mTotalAllocated -= blockp->getSize(); -} - -void LLAGPMemPool::coalesce(LLFreeBlock *free_block) -{ - LLFreeBlock *next = free_block->getNext(); - - if (next && (free_block->mOffset + free_block->mSize == next->mOffset)) - { - free_block->mSize += next->mSize; - - next->unlink(); - delete next; - - coalesce(free_block); - } -} - -void LLAGPMemPool::printFreeList() -{ - LLFreeBlock *cur_block = mFreeList.getFirst(); - while (cur_block) - { - llinfos << "Cur block begin: " << cur_block->mOffset << llendl; - llinfos << "Cur block end: " << cur_block->mOffset + cur_block->mSize << llendl; - cur_block = cur_block->getNext(); - } -} - diff --git a/linden/indra/llrender/llagpmempool.h b/linden/indra/llrender/llagpmempool.h deleted file mode 100644 index f992876..0000000 --- a/linden/indra/llrender/llagpmempool.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @file llagpmempool.h - * @brief LLAGPMemPool base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#ifndef LL_LLAGPMEMPOOL_H -#define LL_LLAGPMEMPOOL_H - -#include "stdtypes.h" -#include "lldlinked.h" - -// Raw memory handling abstraction, which handles interaction with -// the nVidia and ATI AGP extensions. - -// Minimum size we allow allocation for, in order to allow AGP usage... -const S32 MIN_AGP_SIZE = 8000000; - -class LLAGPMemBlock; - -class LLAGPMemPool -{ -public: - LLAGPMemPool(); - virtual ~LLAGPMemPool(); - - virtual LLAGPMemBlock *allocBlock(const S32 size); - virtual void freeBlock(LLAGPMemBlock *blockp); - - virtual void flush() = 0; - virtual void dump() = 0; - virtual void enable() = 0; - virtual void disable() = 0; - virtual void bind() = 0; - - virtual S32 getSize() { return mSize; } - - S32 getTotalAllocated() const { return mTotalAllocated; } - static LLAGPMemPool *createPool(const U32 size, const BOOL use_vbo); - - struct LLFreeBlock: public LLDLinked - { - S32 mOffset; - S32 mSize; - LLFreeBlock(const S32 offset, const S32 size) { mOffset = offset; mSize = size; sNumBlocks++; } - ~LLFreeBlock() { sNumBlocks--; } - - static S32 sNumBlocks; - }; - - // Fencing (for nVidia and Apple) - default is to do nothing (ATI, ARB do not need fencing) - virtual U32 createFence() { return 0; } - virtual void deleteFence(const U32 fence) {} - virtual void sendFence(U32 fence) {} - virtual void waitFence(U32 fence) {} - - void printFreeList(); -protected: - - void coalesce(LLFreeBlock *free_block); - virtual LLAGPMemBlock *createBlock(const U32 offset, const U32 size) = 0; - LLDLinked mFreeList; - - S32 mSize; - S32 mTotalAllocated; -}; - -// An AGP memory block, which contains all the info needed to -// copy data in/out. -class LLAGPMemBlock -{ -public: - LLAGPMemBlock(LLAGPMemPool *mem_poolp) : mMemPoolp(mem_poolp) {} - virtual ~LLAGPMemBlock() {} - virtual void copy (void *source, const U32 size_bytes) = 0; - virtual void copyColor(void *source, const U32 size_bytes) = 0; - - virtual void bindGLVertexPointer(const U32 stride, const U32 offset) = 0; - virtual void bindGLNormalPointer(const U32 stride, const U32 offset) = 0; - virtual void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) = 0; - virtual void bindGLColorPointer(const U32 stride, const U32 offset) = 0; - virtual void bindGLTexCoordPointer(const U32 stride, const U32 offset) = 0; - virtual void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) = 0; - virtual void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) = 0; - - virtual BOOL hasMappedMem() const = 0; - virtual U8* getMappedMem() = 0; - - virtual U32 createFence() = 0; - virtual void deleteFence(const U32 fence) = 0; - virtual void sendFence(U32 fence) = 0; - virtual void waitFence(U32 fence) = 0; - - virtual U32 getOffset() const = 0; - virtual U32 getSize() const = 0; -protected: - LLAGPMemPool *mMemPoolp; -}; - -#endif // LL_LLAGPMEMPOOL_H diff --git a/linden/indra/llrender/llagpmempoolapple.cpp b/linden/indra/llrender/llagpmempoolapple.cpp deleted file mode 100644 index 9aa4993..0000000 --- a/linden/indra/llrender/llagpmempoolapple.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/** - * @file llagpmempoolapple.cpp - * @brief LLAGPMemPoolAPPLE base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#ifdef LL_DARWIN - -#include "linden_common.h" - -#include "llagpmempoolapple.h" -#include "llgl.h" - -#include "llglheaders.h" - -LLAGPMemPoolAPPLE::LLAGPMemPoolAPPLE(S32 request) : LLAGPMemPool() -{ - llinfos << "Creating LLAGPMemPoolAPPLE" << llendl; - stop_glerror(); - if (!gGLManager.mHasAPPLEFence || !gGLManager.mHasAPPLEVertexArrayRange) - { - llerrs << "necessary extensions not present!" << llendl; - } - - // No special allocation is necessary for the Apple extensions - mBase = (U8*)::malloc(request); - mSize = request; - - if (mBase) - { - mFreeList.append(*(new LLFreeBlock(0,mSize))); - } - else - { - mSize = 0; - } - - flush_glerror(); -} - -LLAGPMemBlockAPPLE::~LLAGPMemBlockAPPLE() -{ - mMemPoolp->freeBlock(this); -} - -LLAGPMemBlock *LLAGPMemPoolAPPLE::createBlock(const U32 offset, const U32 size) -{ - return new LLAGPMemBlockAPPLE(this, mBase, offset, size); -} - -LLAGPMemPoolAPPLE::~LLAGPMemPoolAPPLE() -{ - if (mBase) - { - // MBW -- This really belongs in a call which is the opposite of bind()... - glVertexArrayRangeAPPLE(0, 0); - ::free(mBase); - } -} - -void LLAGPMemPoolAPPLE::bind() -{ - if(mBase) - { - glVertexArrayRangeAPPLE(mSize, mBase); - } -} - -void LLAGPMemPoolAPPLE::enable() -{ - glEnableClientState(GL_VERTEX_ARRAY_RANGE_APPLE); -} - -void LLAGPMemPoolAPPLE::disable() -{ - glDisableClientState(GL_VERTEX_ARRAY_RANGE_APPLE); -} - -void LLAGPMemPoolAPPLE::flush() -{ - if(mBase) - { - glFlushVertexArrayRangeAPPLE(mSize, mBase); - } -} - -void LLAGPMemPoolAPPLE::dump() -{ - LLFreeBlock *prev = 0; - LLFreeBlock *block = mFreeList.getFirst(); - - int d=0; - - int i=0; - while (block) - { - i++; - if (prev) - { - d = (S32)block->mOffset - ((S32)prev->mOffset + prev->mSize); - } - else d = 0; - - prev = block; - block = block->getNext(); - } -} - - -U32 LLAGPMemPoolAPPLE::createFence() -{ - U32 fence; - glGenFencesAPPLE(1, (GLuint*)&fence); - glSetFenceAPPLE(fence); - glFinishFenceAPPLE(fence); - return fence; -} - - -void LLAGPMemPoolAPPLE::deleteFence(const U32 fence) -{ - glDeleteFencesAPPLE(1, (GLuint*)&fence); -} - - -void LLAGPMemPoolAPPLE::sendFence(U32 fence) -{ - glSetFenceAPPLE(fence); -} - - -void LLAGPMemPoolAPPLE::waitFence(U32 fence) -{ - if(!glTestFenceAPPLE(fence)) - { - glFinishFenceAPPLE(fence); - } -} - - -///////////////////////////// -// -// LLAGPMemBlockAPPLE -// -// APPLE Implementation of an AGP memory block -// - -LLAGPMemBlockAPPLE::LLAGPMemBlockAPPLE(LLAGPMemPool *mem_poolp, U8 *baseptr, S32 offset, const U32 size) : LLAGPMemBlock(mem_poolp) -{ - mMemp = baseptr + offset; - mOffset = offset; - mSize = size; -} - - -void LLAGPMemBlockAPPLE::bindGLVertexPointer(const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty vertex array" << llendl; - } - glVertexPointer(3, GL_FLOAT, stride, mMemp + offset); -} - -void LLAGPMemBlockAPPLE::bindGLNormalPointer(const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty normal array" << llendl; - } - glNormalPointer(GL_FLOAT, stride, mMemp + offset); -} - - -void LLAGPMemBlockAPPLE::bindGLColorPointer(const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty color array" << llendl; - } - glColorPointer(4, GL_UNSIGNED_BYTE, stride, mMemp + offset); -} - - -void LLAGPMemBlockAPPLE::bindGLTexCoordPointer(const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty texcoord array" << llendl; - } - glTexCoordPointer(2, GL_FLOAT, stride, mMemp + offset); -} - - -void LLAGPMemBlockAPPLE::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty vertex weight array" << llendl; - } - - if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, (F32 *)(mMemp + offset)); -} - -void LLAGPMemBlockAPPLE::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty vertex weight array" << llendl; - } - - if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, 0, (F32 *)(mMemp + offset)); -} - -void LLAGPMemBlockAPPLE::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty vertex weight array" << llendl; - } - set_vertex_clothing_weights(index, stride, (LLVector4 *)(mMemp + offset)); -} - -U8* LLAGPMemBlockAPPLE::getMappedMem() -{ - return mMemp; -} - - -void LLAGPMemBlockAPPLE::copy(void *mem, const U32 size) -{ - if (!mMemp || !mem) - { - return; - } - llassert(size <= mSize); - - memcpy( mMemp, mem, size ); - - glFlushVertexArrayRangeAPPLE(size, mMemp); -} - -void LLAGPMemBlockAPPLE::copyColor(void *mem, const U32 size) -{ - if (!mMemp || !mem) - { - return; - } - llassert(size <= mSize); - - memcpy( mMemp, mem, size ); - - glFlushVertexArrayRangeAPPLE(size, mMemp); -} - - - -U32 LLAGPMemBlockAPPLE::createFence() -{ - U32 fence; - glGenFencesAPPLE(1, (GLuint*)&fence); - glSetFenceAPPLE(fence); - glFinishFenceAPPLE(fence); - return fence; -} - -void LLAGPMemBlockAPPLE::deleteFence(const U32 fence) -{ - glDeleteFencesAPPLE(1, (GLuint*)&fence); -} - -void LLAGPMemBlockAPPLE::sendFence(U32 fence) -{ - glSetFenceAPPLE(fence); -} - -void LLAGPMemBlockAPPLE::waitFence(U32 fence) -{ - if(!glTestFenceAPPLE(fence)) - { - glFinishFenceAPPLE(fence); - } -} - -// MBW -- May want this at some point... -#if 0 -void LLAGPMemBlockAPPLE::flush() -{ - glFlushVertexArrayRangeAPPLE(mSize, mMemp); -} -#endif - -#endif // LL_DARWIN diff --git a/linden/indra/llrender/llagpmempoolapple.h b/linden/indra/llrender/llagpmempoolapple.h deleted file mode 100644 index 4a72a28..0000000 --- a/linden/indra/llrender/llagpmempoolapple.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file llagpmempoolapple.h - * @brief LLAGPMemPoolAPPLE base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#ifndef LL_LLAGPMEMPOOLAPPLE_H -#define LL_LLAGPMEMPOOLAPPLE_H - -#include "llagpmempool.h" - -#if LL_DARWIN -class LLAGPMemPoolAPPLE : public LLAGPMemPool -{ -public: - LLAGPMemPoolAPPLE(S32 request); - virtual ~LLAGPMemPoolAPPLE(); - - /*virtual*/ void flush(); - /*virtual*/ void dump(); - /*virtual*/ void enable(); - /*virtual*/ void disable(); - /*virtual*/ void bind(); - - /*virtual*/ U32 createFence(); - /*virtual*/ void deleteFence(const U32 fence); - /*virtual*/ void sendFence(U32 fence); - /*virtual*/ void waitFence(U32 fence); - -protected: - /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size); - -protected: - U8 *mBase; -}; - -class LLAGPMemBlockAPPLE : public LLAGPMemBlock -{ -public: - LLAGPMemBlockAPPLE(LLAGPMemPool *mem_poolp, U8 *baseptr, const S32 offset, const U32 size); - virtual ~LLAGPMemBlockAPPLE(); - - /*virtual*/ void copy (void *source, const U32 size_bytes); - /*virtual*/ void copyColor(void *source, const U32 size_bytes); - /*virtual*/ void free(); - - /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset); - /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset); - /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset); - - /*virtual*/ U32 getOffset() const { return mOffset; } - /*virtual*/ U32 getSize() const { return mSize; } - - /*virtual*/ BOOL hasMappedMem() const { return TRUE; } - /*virtual*/ U8* getMappedMem(); - /*virtual*/ U32 createFence(); - /*virtual*/ void deleteFence(const U32 fence); - /*virtual*/ void sendFence(U32 fence); - /*virtual*/ void waitFence(U32 fence); - -private: - U8 *mMemp; - U32 mOffset; // Offset from base - U32 mSize; - friend class LLAGPMemPoolAPPLE; -}; - -#endif // LL_DARWIN - -#endif // LL_LLAGPMEMPOOLAPPLE_H diff --git a/linden/indra/llrender/llagpmempoolarb.cpp b/linden/indra/llrender/llagpmempoolarb.cpp deleted file mode 100644 index ab97c97..0000000 --- a/linden/indra/llrender/llagpmempoolarb.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/** - * @file llagpmempoolarb.cpp - * @brief LLAGPMemPoolARB base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#include "linden_common.h" -#include "llagpmempoolarb.h" -#include "llgl.h" - -#include "llglheaders.h" - -LLAGPMemPoolARB::LLAGPMemPoolARB(S32 request) : LLAGPMemPool() -{ - llinfos << "Creating LLAGPMemPoolARB" << llendl; - stop_glerror(); - if (!gGLManager.mHasVertexBufferObject) - { - llerrs << "No ARB vertex buffer object extension!" << llendl; - } - - mName = 0; - - mSize = request; - flush_glerror(); -} - - -LLAGPMemPoolARB::~LLAGPMemPoolARB() -{ -} - - -LLAGPMemBlock* LLAGPMemPoolARB::allocBlock(const S32 size) -{ - return allocBlock(size, GL_ARRAY_BUFFER_ARB); -} - -LLAGPMemBlock *LLAGPMemPoolARB::allocBlock(const S32 size, U32 target) -{ - S32 aligned_size = size; - if (size & 0x0f) - { - aligned_size += 16 - (size & 0x0f); - } - - if (aligned_size > (mSize - mTotalAllocated)) - { - // We're totally out of AGP memory, bail. - return (LLAGPMemBlock *)0; - } - - mTotalAllocated += aligned_size; - return createBlock(0, aligned_size, target); -} - - -void LLAGPMemPoolARB::freeBlock(LLAGPMemBlock *blockp) -{ - if (!blockp->getSize()) - { - return; - } - LLAGPMemBlockARB *arb_blockp = (LLAGPMemBlockARB*)blockp; - U32 name[1]; - name[0] = arb_blockp->getName(); - stop_glerror(); - glDeleteBuffersARB(1, (GLuint*)name); - stop_glerror(); - mTotalAllocated -= blockp->getSize(); -} - -LLAGPMemBlock *LLAGPMemPoolARB::createBlock(const U32 offset, const U32 size) -{ - return createBlock(offset, size, GL_ARRAY_BUFFER_ARB); -} - -LLAGPMemBlock *LLAGPMemPoolARB::createBlock(const U32 offset, const U32 size, const U32 target) -{ - U32 name[1]; - stop_glerror(); - glGenBuffersARB(1, (GLuint*)name); - stop_glerror(); - return new LLAGPMemBlockARB(this, name[0], offset, size, target); -} - -void LLAGPMemPoolARB::disable() -{ -} - -void LLAGPMemPoolARB::dump() -{ -} - - -///////////////////////////// -// -// LLAGPMemBlockARB -// -// ARB ImplementARBon of an AGP memory block -// - -LLAGPMemBlockARB::LLAGPMemBlockARB(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size, U32 target) : - LLAGPMemBlock(mem_poolp), mTarget(target) -{ - llassert(name > 0); - mName = name; - stop_glerror(); - glBindBufferARB(mTarget, mName); - stop_glerror(); - - glBufferDataARB(mTarget, size, NULL, GL_DYNAMIC_DRAW_ARB); - - stop_glerror(); - glBindBufferARB(mTarget, 0); - stop_glerror(); - mSize = size; -} - - -void LLAGPMemBlockARB::bindGLVertexPointer(const U32 stride, const U32 offset) -{ - stop_glerror(); - glBindBufferARB(mTarget, mName); - glVertexPointer(3, GL_FLOAT, stride, (GLvoid*)((intptr_t)offset)); - glBindBufferARB(mTarget, 0); -} - - -void LLAGPMemBlockARB::bindGLNormalPointer(const U32 stride, const U32 offset) -{ - stop_glerror(); - glBindBufferARB(mTarget, mName); - glNormalPointer(GL_FLOAT, stride, (GLvoid*)((intptr_t)offset)); - glBindBufferARB(mTarget, 0); - stop_glerror(); -} - - -void LLAGPMemBlockARB::bindGLColorPointer(const U32 stride, const U32 offset) -{ - stop_glerror(); - glBindBufferARB(mTarget, mName); - glColorPointer(4, GL_UNSIGNED_BYTE, stride, (GLvoid*)((intptr_t)offset)); - glBindBufferARB(mTarget, 0); - stop_glerror(); -} - - -void LLAGPMemBlockARB::bindGLTexCoordPointer(const U32 stride, const U32 offset) -{ - stop_glerror(); - glBindBufferARB(mTarget, mName); - glTexCoordPointer(2, GL_FLOAT, stride, (GLvoid*)((intptr_t)offset)); - glBindBufferARB(mTarget, 0); - stop_glerror(); -} - - -void LLAGPMemBlockARB::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) -{ - stop_glerror(); - glBindBufferARB(mTarget, mName); - set_vertex_weights(index, (F32*)(intptr_t)offset); - glBindBufferARB(mTarget, 0); - stop_glerror(); -} - -void LLAGPMemBlockARB::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) -{ - stop_glerror(); - glBindBufferARB(mTarget, mName); - set_binormals(index, stride, (LLVector3*)(intptr_t)offset); - glBindBufferARB(mTarget, 0); - stop_glerror(); -} - - -void LLAGPMemBlockARB::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) -{ - return; -} - - -void LLAGPMemBlockARB::copy(void *mem, const U32 size) -{ - stop_glerror(); - llassert(size <= mSize); - glBindBufferARB(mTarget, mName); - glBufferSubDataARB(mTarget, 0, size, mem); - glBindBufferARB(mTarget, 0); - stop_glerror(); -} - -void LLAGPMemBlockARB::copyColor(void *mem, const U32 size) -{ - stop_glerror(); - llassert(size <= mSize); - glBindBufferARB(mTarget, mName); - glBufferSubDataARB(mTarget, 0, size, mem); - glBindBufferARB(mTarget, 0); - stop_glerror(); -} - - -U8* LLAGPMemBlockARB::getMappedMem() -{ - return NULL; -} diff --git a/linden/indra/llrender/llagpmempoolarb.h b/linden/indra/llrender/llagpmempoolarb.h deleted file mode 100644 index 7358862..0000000 --- a/linden/indra/llrender/llagpmempoolarb.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file llagpmempoolarb.h - * @brief LLAGPMemPoolARB base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#ifndef LL_LLAGPMEMPOOLARB_H -#define LL_LLAGPMEMPOOLARB_H - -#include "llagpmempool.h" - -class LLAGPMemPoolARB : public LLAGPMemPool -{ -public: - LLAGPMemPoolARB(S32 request); - virtual ~LLAGPMemPoolARB(); - - /*virtual*/ LLAGPMemBlock* allocBlock(const S32 size); - LLAGPMemBlock *allocBlock(const S32 size, U32 target); - /*virtual*/ void freeBlock(LLAGPMemBlock *blockp); - - void bind() {} - - void enable() {} - - /*virtual*/ void disable(); - - void flush() {} - - // No point in these being inline, is there? They're virtual functions anyway... - /*virtual*/ inline LLAGPMemBlock *alloc(S32 size); - /*virtual*/ inline void free(LLAGPMemBlock *block); - /*virtual*/ inline void dump(); -protected: - /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size); - LLAGPMemBlock *createBlock(const U32 offset, const U32 size, const U32 target); - -protected: - U32 mName; -}; - -class LLAGPMemBlockARB : public LLAGPMemBlock -{ -public: - LLAGPMemBlockARB(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size, U32 target); - virtual ~LLAGPMemBlockARB() { mMemPoolp->freeBlock(this); }; - - /*virtual*/ void copy (void *source, const U32 size_bytes); - /*virtual*/ void copyColor(void *source, const U32 size_bytes); - /*virtual*/ void free(); - - /*virtual*/ void bind(); - /*virtual*/ void unbind(); - - /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset); - /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset); - /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset); - - /*virtual*/ U32 getOffset() const { return 0; } - /*virtual*/ U32 getSize() const { return mSize; } - - /*virtual*/ BOOL hasMappedMem() const { return FALSE; } - /*virtual*/ U8* getMappedMem(); - /*virtual*/ U32 createFence() { return 0; } - /*virtual*/ void deleteFence(const U32 fence) {} - /*virtual*/ void sendFence(U32 fence) { } - /*virtual*/ void waitFence(U32 fence) { } - - U32 getName() const { return mName; } -private: - U32 mName; - U32 mSize; - U32 mTarget; - - friend class LLAGPMemPoolARB; -}; - -#endif // LL_LLAGPMEMPOOLARB_H diff --git a/linden/indra/llrender/llagpmempoolati.cpp b/linden/indra/llrender/llagpmempoolati.cpp deleted file mode 100644 index f29db95..0000000 --- a/linden/indra/llrender/llagpmempoolati.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @file llagpmempoolati.cpp - * @brief LLAGPMemPoolATI base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#include "linden_common.h" - -#include "llagpmempoolati.h" -#include "llgl.h" - -#include "llglheaders.h" - -LLAGPMemPoolATI::LLAGPMemPoolATI(S32 request) : LLAGPMemPool() -{ - llinfos << "Creating LLAGPMemPoolATI" << llendl; - stop_glerror(); - if (!gGLManager.mHasATIVAO) - { - llerrs << "No ATI AGI memory extension!" << llendl; - } - - mName = 0; - - // More than 4MB of agp available - while (!mName && (request > 0)) - { - mName = glNewObjectBufferATI(request, NULL, GL_DYNAMIC_ATI); - mSize = request; - request >>= 1; - } - - if (mName) - { - mFreeList.append(*(new LLFreeBlock(0, mSize))); - } - else - { - llinfos << "Unable to allocate AGP memory!" << llendl; - mSize = 0; - } - flush_glerror(); -} - - -LLAGPMemPoolATI::~LLAGPMemPoolATI() -{ - if (mName) - { - glFreeObjectBufferATI(mName); - } -} - - -LLAGPMemBlock *LLAGPMemPoolATI::createBlock(const U32 offset, const U32 size) -{ - return new LLAGPMemBlockATI(this, mName, offset, size); -} - - -void LLAGPMemPoolATI::dump() -{ -} - - -///////////////////////////// -// -// LLAGPMemBlockATI -// -// ATI Implementation of an AGP memory block -// - -LLAGPMemBlockATI::LLAGPMemBlockATI(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size) : - LLAGPMemBlock(mem_poolp) -{ - mName = name; - mOffset = offset; - mSize = size; -} - - -void LLAGPMemBlockATI::bindGLVertexPointer(const U32 stride, const U32 offset) -{ - glArrayObjectATI(GL_VERTEX_ARRAY, 3, GL_FLOAT, stride, mName, mOffset + offset); -} - - -void LLAGPMemBlockATI::bindGLNormalPointer(const U32 stride, const U32 offset) -{ - glArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, stride, mName, mOffset + offset); -} - - -void LLAGPMemBlockATI::bindGLColorPointer(const U32 stride, const U32 offset) -{ - glArrayObjectATI(GL_COLOR_ARRAY, 4, GL_UNSIGNED_BYTE, stride, mName, mOffset + offset); -} - - -void LLAGPMemBlockATI::bindGLTexCoordPointer(const U32 stride, const U32 offset) -{ - glArrayObjectATI(GL_TEXTURE_COORD_ARRAY, 2, GL_FLOAT, stride, mName, mOffset + offset); -} - - -void LLAGPMemBlockATI::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) -{ - glVertexAttribArrayObjectATI(index, 3, GL_FLOAT, FALSE, stride, mName, mOffset + offset); -} - - -void LLAGPMemBlockATI::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) -{ - //glArrayObjectATI(GL_WEIGHT_ARRAY_ARB, 1, GL_FLOAT, stride, mName, mOffset + offset); - glVertexAttribArrayObjectATI(index, 1, GL_FLOAT, FALSE, stride, mName, mOffset + offset); -} - -void LLAGPMemBlockATI::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) -{ - glVertexAttribArrayObjectATI(index, 4, GL_FLOAT, FALSE, stride, mName, mOffset + offset); -} - -U8* LLAGPMemBlockATI::getMappedMem() -{ - return NULL; -} - -void LLAGPMemBlockATI::copy(void *mem, const U32 size) -{ - llassert(size <= mSize); - glUpdateObjectBufferATI(mName, mOffset, size, mem, GL_PRESERVE_ATI); -} - -void LLAGPMemBlockATI::copyColor(void *mem, const U32 size) -{ - llassert(size <= mSize); - glUpdateObjectBufferATI(mName, mOffset, size, mem, GL_PRESERVE_ATI); -} - diff --git a/linden/indra/llrender/llagpmempoolati.h b/linden/indra/llrender/llagpmempoolati.h deleted file mode 100644 index 67803f6..0000000 --- a/linden/indra/llrender/llagpmempoolati.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @file llagpmempoolati.h - * @brief LLAGPMemPoolATI base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#ifndef LL_LLAGPMEMPOOLATI_H -#define LL_LLAGPMEMPOOLATI_H - -#include "llagpmempool.h" - -class LLAGPMemPoolATI : public LLAGPMemPool -{ -public: - LLAGPMemPoolATI(S32 request); - virtual ~LLAGPMemPoolATI(); - - void bind() {} - - void enable() {} - - void disable() {} - - void flush() {} - - // No point in these being inline, is there? They're virtual functions anyway... - /*virtual*/ inline LLAGPMemBlock *alloc(S32 size); - /*virtual*/ inline void free(LLAGPMemBlock *block); - /*virtual*/ inline void dump(); -protected: - /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size); - -protected: - U32 mName; -}; - -class LLAGPMemBlockATI : public LLAGPMemBlock -{ -public: - LLAGPMemBlockATI(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size); - virtual ~LLAGPMemBlockATI() { mMemPoolp->freeBlock(this); }; - - /*virtual*/ void copy (void *source, const U32 size_bytes); - /*virtual*/ void copyColor(void *source, const U32 size_bytes); - /*virtual*/ void free(); - /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride,const U32 offset); - /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset); - /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset); - - /*virtual*/ U32 getOffset() const { return mOffset; } - /*virtual*/ U32 getSize() const { return mSize; } - - /*virtual*/ BOOL hasMappedMem() const { return TRUE; } - /*virtual*/ U8* getMappedMem(); - /*virtual*/ U32 createFence() { return 0; } - /*virtual*/ void deleteFence(const U32 fence) {} - /*virtual*/ void sendFence(U32 fence) { } - /*virtual*/ void waitFence(U32 fence) { } -private: - U32 mName; - U32 mOffset; - U32 mSize; - - friend class LLAGPMemPoolATI; -}; - -#endif // LL_LLAGPMEMPOOLATI_H diff --git a/linden/indra/llrender/llagpmempoolnv.cpp b/linden/indra/llrender/llagpmempoolnv.cpp deleted file mode 100644 index 8bbaef9..0000000 --- a/linden/indra/llrender/llagpmempoolnv.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/** - * @file llagpmempoolnv.cpp - * @brief LLAGPMemPoolNV base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#include "linden_common.h" - -#ifndef LL_LINUX - -#include "llagpmempoolnv.h" -#include "llgl.h" - -#include "llglheaders.h" - -#if LL_WINDOWS -//#define LL_USE_NEW_MEM_OPS 1 -#endif -#if LL_USE_NEW_MEM_OPS -#include "new_mem_ops.h" -#endif - -BOOL LLAGPMemPoolNV::sWriteOK = TRUE; - -LLAGPMemPoolNV::LLAGPMemPoolNV(int request) : LLAGPMemPool() -{ - llinfos << "Creating LLAGPMemPoolNV" << llendl; - stop_glerror(); - if (!gGLManager.mHasNVFence) - { - llerrs << "wglAllocateMemoryNV not defined!" << llendl; - } - - mBase = 0; - - if (!mBase) - { - // More than 4MB of AGP available - while (!mBase && (request > 0)) - { - // Stupid arbitrary nVidia magic numbers. - // read freq, write freq, priority - // AGP: 0.0, 0.1, 0.5 - // Video: 0.0, 0.1, 1.0 - mBase = (U8*)wglAllocateMemoryNV(request, 0.0f, 0.1f, 0.5f); - mSize = request; - request >>= 1; - } - } - - if (mBase) - { - mFreeList.append(*(new LLFreeBlock(0,mSize))); - } - else - { - mSize = 0; - } - - sWriteOK = TRUE; - flush_glerror(); -} - - -LLAGPMemBlock *LLAGPMemPoolNV::createBlock(const U32 offset, const U32 size) -{ - return new LLAGPMemBlockNV(this, mBase, offset, size); -} - -LLAGPMemPoolNV::~LLAGPMemPoolNV() -{ - if (mBase) - { - wglFreeMemoryNV(mBase); - } -} - -void LLAGPMemPoolNV::bind() -{ - glVertexArrayRangeNV(mSize, mBase); -} - -void LLAGPMemPoolNV::enable() -{ - glEnableClientState(GL_VERTEX_ARRAY_RANGE_NV); - sWriteOK = FALSE; -} - -void LLAGPMemPoolNV::disable() -{ - glDisableClientState(GL_VERTEX_ARRAY_RANGE_NV); - sWriteOK = TRUE; -} - -void LLAGPMemPoolNV::flush() -{ - glFlushVertexArrayRangeNV(); -} - -U32 LLAGPMemPoolNV::createFence() -{ - U32 fence; - glGenFencesNV(1, &fence); - glSetFenceNV(fence, GL_ALL_COMPLETED_NV); - glFinishFenceNV(fence); - return fence; -} - -void LLAGPMemPoolNV::deleteFence(const U32 fence) -{ - glDeleteFencesNV(1, &fence); -} - -void LLAGPMemPoolNV::sendFence(U32 fence) -{ - glSetFenceNV(fence, GL_ALL_COMPLETED_NV); -} - -void LLAGPMemPoolNV::waitFence(U32 fence) -{ - if(!glTestFenceNV(fence)) - { - glFinishFenceNV(fence); - } -} - - -//static -BOOL LLAGPMemPoolNV::isWriteOK() -{ - return sWriteOK; -} - -void LLAGPMemPoolNV::dump() -{ - LLFreeBlock *prev = 0; - LLFreeBlock *block = mFreeList.getFirst(); - - int d=0; - - int i=0; - while (block) - { - i++; - if (prev) - { - d = (S32)block->mOffset - ((S32)prev->mOffset + prev->mSize); - } - else d = 0; - - prev = block; - block = block->getNext(); - } -} - - -LLAGPMemBlockNV::LLAGPMemBlockNV(LLAGPMemPool *mem_poolp, U8 *baseptr, S32 offset, const U32 size) : LLAGPMemBlock(mem_poolp) -{ - mMemp = baseptr + offset; - mOffset = offset; - mSize = size; -} - -extern U8* gAGPVertices; - -void LLAGPMemBlockNV::bindGLVertexPointer(const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty vertex array" << llendl; - } - glVertexPointer(3, GL_FLOAT, stride, mMemp + offset); -} - -void LLAGPMemBlockNV::bindGLNormalPointer(const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty normal array" << llendl; - } - glNormalPointer(GL_FLOAT, stride, mMemp + offset); -} - - -void LLAGPMemBlockNV::bindGLColorPointer(const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty color array" << llendl; - } - glColorPointer(4, GL_UNSIGNED_BYTE, stride, mMemp + offset); -} - - -void LLAGPMemBlockNV::bindGLTexCoordPointer(const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty texcoord array" << llendl; - } - glTexCoordPointer(2, GL_FLOAT, stride, mMemp + offset); -} - - -void LLAGPMemBlockNV::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty vertex weight array" << llendl; - } - - glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, (F32 *)(mMemp + offset)); -} - -void LLAGPMemBlockNV::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty vertex weight array" << llendl; - } - - glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, 0, (F32 *)(mMemp + offset)); -} - -void LLAGPMemBlockNV::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) -{ - if (!mMemp) - { - llerrs << "Binding empty vertex weight array" << llendl; - } - set_vertex_clothing_weights(index, stride, (LLVector4 *)(mMemp + offset)); -} - -U8* LLAGPMemBlockNV::getMappedMem() -{ - return mMemp; -} - -void LLAGPMemBlockNV::copy(void *mem, const U32 size) -{ - if (!mMemp || !mem) - { - return; - } - llassert(LLAGPMemPoolNV::isWriteOK()); - llassert(size <= mSize); - -#if LL_USE_NEW_MEM_OPS - inline_new_memcpy( mMemp, mem, size ); -#else - memcpy( mMemp, mem, size ); -#endif -} - -void LLAGPMemBlockNV::copyColor(void *mem, const U32 size) -{ - if (!mMemp || !mem) - { - return; - } - llassert(LLAGPMemPoolNV::isWriteOK()); - llassert(size <= mSize); - -#if LL_USE_NEW_MEM_OPS - inline_new_memcpy( mMemp, mem, size ); -#else - memcpy( mMemp, mem, size ); -#endif -} - - -U32 LLAGPMemBlockNV::createFence() -{ - U32 fence; - glGenFencesNV(1, &fence); - glSetFenceNV(fence, GL_ALL_COMPLETED_NV); - glFinishFenceNV(fence); - return fence; -} - -void LLAGPMemBlockNV::deleteFence(const U32 fence) -{ - glDeleteFencesNV(1, &fence); -} - -void LLAGPMemBlockNV::sendFence(U32 fence) -{ - glSetFenceNV(fence, GL_ALL_COMPLETED_NV); -} - -void LLAGPMemBlockNV::waitFence(U32 fence) -{ - if(!glTestFenceNV(fence)) - { - glFinishFenceNV(fence); - } -} - -#endif //LL_LINUX diff --git a/linden/indra/llrender/llagpmempoolnv.h b/linden/indra/llrender/llagpmempoolnv.h deleted file mode 100644 index cffe397..0000000 --- a/linden/indra/llrender/llagpmempoolnv.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file llagpmempoolnv.h - * @brief LLAGPMemPoolNV base class - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * - * 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://secondlife.com/developers/opensource/gplv2 - * - * 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://secondlife.com/developers/opensource/flossexception - * - * 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. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#ifndef LL_LLAGPMEMPOOLNV_H -#define LL_LLAGPMEMPOOLNV_H - -#include "llagpmempool.h" - -class LLAGPMemPoolNV : public LLAGPMemPool -{ -public: - LLAGPMemPoolNV(int request); - virtual ~LLAGPMemPoolNV(); - - /*virtual*/ void flush(); - /*virtual*/ void dump(); - /*virtual*/ void enable(); - /*virtual*/ void disable(); - /*virtual*/ void bind(); - - static BOOL isWriteOK(); - - /*virtual*/ U32 createFence(); - /*virtual*/ void deleteFence(const U32 fence); - /*virtual*/ void sendFence(U32 fence); - /*virtual*/ void waitFence(U32 fence); -protected: - /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size); - -protected: - U8 *mBase; - - static BOOL sWriteOK; -}; - -class LLAGPMemBlockNV : public LLAGPMemBlock -{ -public: - LLAGPMemBlockNV(LLAGPMemPool *mem_poolp, U8 *baseptr, const S32 offset, const U32 size); - virtual ~LLAGPMemBlockNV() { mMemPoolp->freeBlock(this); }; - - /*virtual*/ void copy (void *source, const U32 size_bytes); - /*virtual*/ void copyColor(void *source, const U32 size_bytes); - /*virtual*/ void free(); - - /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset); - /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset); - /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset); - /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset); - - /*virtual*/ U32 getOffset() const { return mOffset; } - /*virtual*/ U32 getSize() const { return mSize; } - - /*virtual*/ BOOL hasMappedMem() const { return TRUE; } - /*virtual*/ U8* getMappedMem(); - /*virtual*/ U32 createFence(); - /*virtual*/ void deleteFence(const U32 fence); - /*virtual*/ void sendFence(U32 fence); - /*virtual*/ void waitFence(U32 fence); - -private: - U8 *mMemp; - U32 mOffset; // Offset from base - U32 mSize; - friend class LLAGPMemPoolNV; -}; - -#endif // LL_LLAGPMEMPOOLNV_H diff --git a/linden/indra/llrender/llfont.h b/linden/indra/llrender/llfont.h index dadeafd..a84a302 100644 --- a/linden/indra/llrender/llfont.h +++ b/linden/indra/llrender/llfont.h @@ -31,6 +31,7 @@ #include //#include "lllocalidhashmap.h" #include "llmemory.h" +#include "llstl.h" class LLImageRaw; class LLFontManager; diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp index 2774e8d..2740c6c 100644 --- a/linden/indra/llrender/llfontgl.cpp +++ b/linden/indra/llrender/llfontgl.cpp @@ -33,6 +33,7 @@ #include "llfontgl.h" #include "llgl.h" #include "v4color.h" +#include "llstl.h" const S32 BOLD_OFFSET = 1; @@ -155,7 +156,7 @@ LLString LLFontGL::getFontPathSystem() // Try to figure out where the system's font files are stored. char *system_root = NULL; #if LL_WINDOWS - system_root = getenv("SystemRoot"); + system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ if (!system_root) { llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; @@ -647,7 +648,7 @@ S32 LLFontGL::render(const LLWString &wstr, case LEFT: break; case RIGHT: - cur_x -= (F32)getWidth(wstr.c_str(), 0, length) * sScaleX; + cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX)); break; case HCENTER: cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX)) / 2; @@ -672,12 +673,13 @@ S32 LLFontGL::render(const LLWString &wstr, BOOL draw_ellipses = FALSE; - if (use_ellipses) + if (use_ellipses && halign == LEFT) { // check for too long of a string if (getWidthF32(wstr.c_str(), 0, max_chars) > scaled_max_pixels) { - const LLWString dots(utf8str_to_wstring(LLString("..."))); + // use four dots for ellipsis width to generate padding + const LLWString dots(utf8str_to_wstring(LLString("...."))); scaled_max_pixels = llmax(0, scaled_max_pixels - llround(getWidthF32(dots.c_str()))); draw_ellipses = TRUE; } @@ -1330,7 +1332,7 @@ LLString LLFontGL::nameFromFont(const LLFontGL* fontp) { if (fontp == sSansSerifHuge) { - return LLString("SansSerifHude"); + return LLString("SansSerifHuge"); } else if (fontp == sSansSerifSmall) { diff --git a/linden/indra/llrender/llgldbg.cpp b/linden/indra/llrender/llgldbg.cpp index 4d9f5f9..ab35353 100644 --- a/linden/indra/llrender/llgldbg.cpp +++ b/linden/indra/llrender/llgldbg.cpp @@ -89,8 +89,8 @@ char *fv4(F32 *f) //------------------------------------------------------------------------ char *fv3(F32 *f) { - static char str[128]; - sprintf(str, "%8.3f, %8.3f, %8.3f", f[0], f[1], f[2]); + static char str[128]; /* Flawfinder: ignore */ + snprintf(str, sizeof(str), "%8.3f, %8.3f, %8.3f", f[0], f[1], f[2]); /* Flawfinder: ignore */ return str; } @@ -99,8 +99,8 @@ char *fv3(F32 *f) //------------------------------------------------------------------------ char *fv1(F32 *f) { - static char str[128]; - sprintf(str, "%8.3f", f[0]); + static char str[128]; /* Flawfinder: ignore */ + snprintf(str, sizeof(str), "%8.3f", f[0]); /* Flawfinder: ignore */ return str; } diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp index 5ea7322..8386e95 100644 --- a/linden/indra/llrender/llimagegl.cpp +++ b/linden/indra/llrender/llimagegl.cpp @@ -134,6 +134,15 @@ void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target) sCurrentBoundTextures[stage] = 0; } +// static (duplicated for speed and to avoid GL_TEXTURE_2D default argument which requires GL header dependency) +void LLImageGL::unbindTexture(S32 stage) +{ + glActiveTextureARB(GL_TEXTURE0_ARB + stage); + glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); + glBindTexture(GL_TEXTURE_2D, 0); + sCurrentBoundTextures[stage] = 0; +} + // static void LLImageGL::updateStats(F32 current_time) { @@ -390,13 +399,8 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const llwarns << "Trying to bind a texture while GL is disabled!" << llendl; } - stop_glerror(); - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - //glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); - - stop_glerror(); - + if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName) { // already set! @@ -411,7 +415,6 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const glBindTexture(mBindTarget, mTexName); sCurrentBoundTextures[stage] = mTexName; - stop_glerror(); if (mLastBindTime != sLastFrameTime) { @@ -650,6 +653,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } mHasMipMaps = FALSE; } + glFlush(); stop_glerror(); } @@ -664,6 +668,11 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 llwarns << "Setting subimage on image without GL texture" << llendl; return FALSE; } + if (datap == NULL) + { + llwarns << "Setting subimage on image with NULL datap" << llendl; + return FALSE; + } if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight()) { @@ -676,7 +685,9 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 dump(); llerrs << "setSubImage called with mipmapped image (not supported)" << llendl; } - llassert(mCurrentDiscardLevel == 0); + llassert_always(mCurrentDiscardLevel == 0); + llassert_always(x_pos >= 0 && y_pos >= 0); + if (((x_pos + width) > getWidth()) || (y_pos + height) > getHeight()) { @@ -717,9 +728,12 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 datap += (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture - llverify(bindTextureInternal(0)); + BOOL res = bindTextureInternal(0); + if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl; stop_glerror(); + LLGLEnable tex( GL_TEXTURE_2D ); + glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, datap); stop_glerror(); @@ -733,7 +747,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); stop_glerror(); } - + glFlush(); return TRUE; } diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h index 6356703..20c31d1 100644 --- a/linden/indra/llrender/llimagegl.h +++ b/linden/indra/llrender/llimagegl.h @@ -36,7 +36,7 @@ //============================================================================ -class LLImageGL : public LLThreadSafeRefCount +class LLImageGL : public LLRefCount { public: // Size calculation @@ -48,6 +48,7 @@ public: // Usually you want stage = 0 and bind_target = GL_TEXTURE_2D static void bindExternalTexture( LLGLuint gl_name, S32 stage, LLGLenum bind_target); static void unbindTexture(S32 stage, LLGLenum target); + static void unbindTexture(S32 stage); // Uses GL_TEXTURE_2D (not a default arg to avoid gl.h dependency) // needs to be called every frame static void updateStats(F32 current_time); diff --git a/linden/indra/llrender/llrender.vcproj b/linden/indra/llrender/llrender.vcproj index 9ca9b03..d13384d 100644 --- a/linden/indra/llrender/llrender.vcproj +++ b/linden/indra/llrender/llrender.vcproj @@ -154,18 +154,6 @@ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> - - - - - - - - + + @@ -213,6 +204,9 @@ RelativePath=".\llimagegl.h"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp new file mode 100644 index 0000000..b94f593 --- /dev/null +++ b/linden/indra/llrender/llvertexbuffer.cpp @@ -0,0 +1,922 @@ +#include "linden_common.h" + +#include "llvertexbuffer.h" +// #include "llrender.h" +#include "llglheaders.h" +#include "llmemory.h" +#include "llmemtype.h" + +//============================================================================ + +//static +S32 LLVertexBuffer::sCount = 0; +S32 LLVertexBuffer::sGLCount = 0; +BOOL LLVertexBuffer::sEnableVBOs = TRUE; +U32 LLVertexBuffer::sGLRenderBuffer = 0; +U32 LLVertexBuffer::sGLRenderIndices = 0; +U32 LLVertexBuffer::sLastMask = 0; +BOOL LLVertexBuffer::sVBOActive = FALSE; +BOOL LLVertexBuffer::sIBOActive = FALSE; +U32 LLVertexBuffer::sAllocatedBytes = 0; +BOOL LLVertexBuffer::sRenderActive = FALSE; + +std::vector LLVertexBuffer::sDeleteList; +LLVertexBuffer::buffer_list_t LLVertexBuffer::sLockedList; + +S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = +{ + sizeof(LLVector3), // TYPE_VERTEX, + sizeof(LLVector3), // TYPE_NORMAL, + sizeof(LLVector2), // TYPE_TEXCOORD, + sizeof(LLVector2), // TYPE_TEXCOORD2, + sizeof(LLColor4U), // TYPE_COLOR, + sizeof(LLVector3), // TYPE_BINORMAL, + sizeof(F32), // TYPE_WEIGHT, + sizeof(LLVector4), // TYPE_CLOTHWEIGHT, +}; + +//static +void LLVertexBuffer::initClass(bool use_vbo) +{ + sEnableVBOs = use_vbo; +} + +//static +void LLVertexBuffer::unbind() +{ + if (sVBOActive) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + sVBOActive = FALSE; + } + if (sIBOActive) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + sIBOActive = FALSE; + } + + sGLRenderBuffer = 0; + sGLRenderIndices = 0; +} + +//static +void LLVertexBuffer::cleanupClass() +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + sLockedList.clear(); + startRender(); + stopRender(); + clientCopy(); // deletes GL buffers +} + +//static, call before rendering VBOs +void LLVertexBuffer::startRender() +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + if (sEnableVBOs) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + sVBOActive = FALSE; + sIBOActive = FALSE; + } + + sRenderActive = TRUE; + sGLRenderBuffer = 0; + sGLRenderIndices = 0; + sLastMask = 0; +} + +void LLVertexBuffer::stopRender() +{ + sRenderActive = FALSE; +} + +void LLVertexBuffer::clientCopy(F64 max_time) +{ + if (!sDeleteList.empty()) + { + size_t num = sDeleteList.size(); + glDeleteBuffersARB(sDeleteList.size(), (GLuint*) &(sDeleteList[0])); + sDeleteList.clear(); + sGLCount -= num; + } + + if (sEnableVBOs) + { + LLTimer timer; + BOOL reset = TRUE; + buffer_list_t::iterator iter = sLockedList.begin(); + while(iter != sLockedList.end()) + { + LLVertexBuffer* buffer = *iter; + if (buffer->isLocked() && buffer->useVBOs()) + { + buffer->setBuffer(0); + } + ++iter; + if (reset) + { + reset = FALSE; + timer.reset(); //skip first copy (don't count pipeline stall) + } + else + { + if (timer.getElapsedTimeF64() > max_time) + { + break; + } + } + + } + + sLockedList.erase(sLockedList.begin(), iter); + } +} + +//---------------------------------------------------------------------------- + +// For debugging +struct VTNC /// Simple +{ + F32 v1,v2,v3; + F32 n1,n2,n3; + F32 t1,t2; + U32 c; +}; +static VTNC dbg_vtnc; + +struct VTUNCB // Simple + Bump +{ + F32 v1,v2,v3; + F32 n1,n2,n3; + F32 t1,t2; + F32 u1,u2; + F32 b1,b2,b3; + U32 c; +}; +static VTUNCB dbg_vtuncb; + +struct VTUNC // Surfacepatch +{ + F32 v1,v2,v3; + F32 n1,n2,n3; + F32 t1,t2; + F32 u1,u2; + U32 c; +}; +static VTUNC dbg_vtunc; + +struct VTNW /// Avatar +{ + F32 v1,v2,v3; + F32 n1,n2,n3; + F32 t1,t2; + F32 w; +}; +static VTNW dbg_vtnw; + +struct VTNPAD /// Avatar Output +{ + F32 v1,v2,v3,p1; + F32 n1,n2,n3,p2; + F32 t1,t2,p3,p4; +}; +static VTNPAD dbg_vtnpad; + +//---------------------------------------------------------------------------- + +LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : + LLRefCount(), + mNumVerts(0), mNumIndices(0), mUsage(usage), mGLBuffer(0), mGLIndices(0), + mMappedData(NULL), + mMappedIndexData(NULL), mLocked(FALSE), + mFinal(FALSE), + mFilthy(FALSE), + mEmpty(TRUE), + mResized(FALSE) +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + if (!sEnableVBOs) + { + mUsage = GL_STREAM_DRAW_ARB; + } + + S32 stride = 0; + for (S32 i=0; i mNumVerts || + nverts < mNumVerts/2) + { + if (mUsage != GL_STATIC_DRAW_ARB) + { + nverts += nverts/4; + } + + mNumVerts = nverts; + } +} + +void LLVertexBuffer::updateNumIndices(S32 nindices) +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + if (!mDynamicSize) + { + mNumIndices = nindices; + } + else if (mUsage == GL_STATIC_DRAW_ARB || + nindices > mNumIndices || + nindices < mNumIndices/2) + { + if (mUsage != GL_STATIC_DRAW_ARB) + { + nindices += nindices/4; + } + + mNumIndices = nindices; + } +} + +void LLVertexBuffer::makeStatic() +{ + if (!sEnableVBOs) + { + return; + } + + if (sRenderActive) + { + llerrs << "Make static called during render." << llendl; + } + + if (mUsage != GL_STATIC_DRAW_ARB) + { + if (useVBOs()) + { + if (mGLBuffer) + { + sDeleteList.push_back(mGLBuffer); + } + if (mGLIndices) + { + sDeleteList.push_back(mGLIndices); + } + } + + if (mGLBuffer) + { + sGLCount++; + glGenBuffersARB(1, (GLuint*) &mGLBuffer); + } + if (mGLIndices) + { + sGLCount++; + glGenBuffersARB(1, (GLuint*) &mGLIndices); + } + + mUsage = GL_STATIC_DRAW_ARB; + mResized = TRUE; + + if (!mLocked) + { + mLocked = TRUE; + sLockedList.push_back(this); + } + } +} + +void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + + updateNumVerts(nverts); + updateNumIndices(nindices); + + if (mMappedData) + { + llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; + } + if (create && (nverts || nindices)) + { + createGLBuffer(); + createGLIndices(); + } + + sAllocatedBytes += getSize() + getIndicesSize(); +} + +void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + mDynamicSize = TRUE; + if (mUsage == GL_STATIC_DRAW_ARB) + { //always delete/allocate static buffers on resize + destroyGLBuffer(); + destroyGLIndices(); + allocateBuffer(newnverts, newnindices, TRUE); + mFinal = FALSE; + } + else if (newnverts > mNumVerts || newnindices > mNumIndices || + newnverts < mNumVerts/2 || newnindices < mNumIndices/2) + { + sAllocatedBytes -= getSize() + getIndicesSize(); + + S32 oldsize = getSize(); + S32 old_index_size = getIndicesSize(); + + updateNumVerts(newnverts); + updateNumIndices(newnindices); + + S32 newsize = getSize(); + S32 new_index_size = getIndicesSize(); + + sAllocatedBytes += newsize + new_index_size; + + if (newsize) + { + if (!mGLBuffer) + { //no buffer exists, create a new one + createGLBuffer(); + } + else + { + //delete old buffer, keep GL buffer for now + U8* old = mMappedData; + mMappedData = new U8[newsize]; + if (old) + { + memcpy(mMappedData, old, llmin(newsize, oldsize)); + if (newsize > oldsize) + { + memset(mMappedData+oldsize, 0, newsize-oldsize); + } + + delete [] old; + } + else + { + memset(mMappedData, 0, newsize); + mEmpty = TRUE; + } + mResized = TRUE; + } + } + else if (mGLBuffer) + { + destroyGLBuffer(); + } + + if (new_index_size) + { + if (!mGLIndices) + { + createGLIndices(); + } + else + { + //delete old buffer, keep GL buffer for now + U8* old = mMappedIndexData; + mMappedIndexData = new U8[new_index_size]; + if (old) + { + memcpy(mMappedIndexData, old, llmin(new_index_size, old_index_size)); + if (new_index_size > old_index_size) + { + memset(mMappedIndexData+old_index_size, 0, new_index_size - old_index_size); + } + delete [] old; + } + else + { + memset(mMappedIndexData, 0, new_index_size); + mEmpty = TRUE; + } + mResized = TRUE; + } + } + else if (mGLIndices) + { + destroyGLIndices(); + } + } +} + +BOOL LLVertexBuffer::useVBOs() const +{ + //it's generally ineffective to use VBO for things that are streaming + //when we already have a client buffer around + if (mUsage == GL_STREAM_DRAW_ARB) + { + return FALSE; + } + + return sEnableVBOs && (!sRenderActive || !mLocked); +} + +//---------------------------------------------------------------------------- + +// Map for data access +U8* LLVertexBuffer::mapBuffer(S32 access) +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + if (sRenderActive) + { + llwarns << "Buffer mapped during render frame!" << llendl; + } + if (!mGLBuffer && !mGLIndices) + { + llerrs << "LLVertexBuffer::mapBuffer() called before createGLBuffer" << llendl; + } + if (mFinal) + { + llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; + } + if (!mMappedData && !mMappedIndexData) + { + llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; + } + + if (!mLocked && useVBOs()) + { + mLocked = TRUE; + sLockedList.push_back(this); + } + + return mMappedData; +} + +void LLVertexBuffer::unmapBuffer() +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + if (mMappedData || mMappedIndexData) + { + if (useVBOs() && mLocked) + { + if (mGLBuffer) + { + if (mResized) + { + glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage); + } + else + { + if (mEmpty || mDirtyRegions.empty()) + { + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData); + } + else + { + for (std::vector::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i) + { + DirtyRegion& region = *i; + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, region.mIndex*mStride, region.mCount*mStride, mMappedData + region.mIndex*mStride); + } + } + } + } + + if (mGLIndices) + { + if (mResized) + { + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage); + } + else + { + if (mEmpty || mDirtyRegions.empty()) + { + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData); + } + else + { + for (std::vector::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i) + { + DirtyRegion& region = *i; + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, region.mIndicesIndex*sizeof(U32), + region.mIndicesCount*sizeof(U32), mMappedIndexData + region.mIndicesIndex*sizeof(U32)); + } + } + } + } + + mDirtyRegions.clear(); + mFilthy = FALSE; + mResized = FALSE; + + if (mUsage == GL_STATIC_DRAW_ARB) + { //static draw buffers can only be mapped a single time + //throw out client data (we won't be using it again) + delete [] mMappedData; + delete [] mMappedIndexData; + mMappedIndexData = NULL; + mMappedData = NULL; + mEmpty = TRUE; + mFinal = TRUE; + } + else + { + mEmpty = FALSE; + } + + mLocked = FALSE; + + glFlush(); + } + } +} + +//---------------------------------------------------------------------------- + +template struct VertexBufferStrider +{ + typedef LLStrider strider_t; + static bool get(LLVertexBuffer& vbo, + strider_t& strider, + S32 index) + { + vbo.mapBuffer(); + if (type == LLVertexBuffer::TYPE_INDEX) + { + S32 stride = sizeof(T); + strider = (T*)(vbo.getMappedIndices() + index*stride); + strider.setStride(0); + return TRUE; + } + else if (vbo.hasDataType(type)) + { + S32 stride = vbo.getStride(); + strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride); + strider.setStride(stride); + return TRUE; + } + else + { + llerrs << "VertexBufferStrider could not find valid vertex data." << llendl; + } + return FALSE; + } +}; + + +bool LLVertexBuffer::getVertexStrider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} +bool LLVertexBuffer::getIndexStrider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} +bool LLVertexBuffer::getTexCoordStrider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} +bool LLVertexBuffer::getTexCoord2Strider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} +bool LLVertexBuffer::getNormalStrider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} +bool LLVertexBuffer::getBinormalStrider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} +bool LLVertexBuffer::getColorStrider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} +bool LLVertexBuffer::getWeightStrider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} +bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, S32 index) +{ + 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 - sTypeOffsets[type]; + for (S32 i=type+1; i vert_index) + { + //this buffer has received multiple updates since the last copy, mark it filthy + mFilthy = TRUE; + mDirtyRegions.clear(); + return; + } + + if (region.mIndex + region.mCount == vert_index && + region.mIndicesIndex + region.mIndicesCount == indices_index) + { + region.mCount += vert_count; + region.mIndicesCount += indices_count; + return; + } + } + + mDirtyRegions.push_back(DirtyRegion(vert_index,vert_count,indices_index,indices_count)); + } +} + +void LLVertexBuffer::markClean() +{ + if (!mResized && !mEmpty && !mFilthy) + { + buffer_list_t::reverse_iterator iter = sLockedList.rbegin(); + if (*iter == this) + { + mLocked = FALSE; + sLockedList.pop_back(); + } + } +} + diff --git a/linden/indra/llrender/llvertexbuffer.h b/linden/indra/llrender/llvertexbuffer.h new file mode 100644 index 0000000..b221d35 --- /dev/null +++ b/linden/indra/llrender/llvertexbuffer.h @@ -0,0 +1,179 @@ +#ifndef LL_LLVERTEXBUFFER_H +#define LL_LLVERTEXBUFFER_H + +#include "llgl.h" +#include "v2math.h" +#include "v3math.h" +#include "v4math.h" +#include "v4coloru.h" +#include "llstrider.h" +#include "llmemory.h" +#include +#include + +//============================================================================ +// NOTES +// Threading: +// All constructors should take an 'create' paramater which should only be +// 'true' when called from the main thread. Otherwise createGLBuffer() will +// be called as soon as getVertexPointer(), etc is called (which MUST ONLY be +// called from the main (i.e OpenGL) thread) + +//============================================================================ +// base class + +class LLVertexBuffer : public LLRefCount +{ +public: + static void initClass(bool use_vbo); + static void cleanupClass(); + static void startRender(); //between start and stop render, no client copies will occur + static void stopRender(); //any buffer not copied to GL will be rendered from client memory + static void clientCopy(F64 max_time = 0.005); //copy data from client to GL + static void unbind(); //unbind any bound vertex buffer + + enum { + TYPE_VERTEX, + TYPE_NORMAL, + TYPE_TEXCOORD, + TYPE_TEXCOORD2, + TYPE_COLOR, + // These use VertexAttribPointer and should possibly be made generic + TYPE_BINORMAL, + TYPE_WEIGHT, + TYPE_CLOTHWEIGHT, + TYPE_MAX, + TYPE_INDEX, + }; + enum { + MAP_VERTEX = (1<getVertexBuffer(verts); + // vb->getNormalStrider(norms); + // setVertsNorms(verts, norms); + // vb->unmapBuffer(); + bool getVertexStrider(LLStrider& strider, S32 index=0); + bool getIndexStrider(LLStrider& strider, S32 index=0); + bool getTexCoordStrider(LLStrider& strider, S32 index=0); + bool getTexCoord2Strider(LLStrider& strider, S32 index=0); + bool getNormalStrider(LLStrider& strider, S32 index=0); + bool getBinormalStrider(LLStrider& strider, S32 index=0); + bool getColorStrider(LLStrider& strider, S32 index=0); + bool getWeightStrider(LLStrider& strider, S32 index=0); + bool getClothWeightStrider(LLStrider& strider, S32 index=0); + + BOOL isEmpty() const { return mEmpty; } + BOOL isLocked() const { return mLocked; } + S32 getNumVerts() const { return mNumVerts; } + S32 getNumIndices() const { return mNumIndices; } + U8* getIndicesPointer() const { return useVBOs() ? NULL : mMappedIndexData; } + U8* getVerticesPointer() const { return useVBOs() ? NULL : mMappedData; } + S32 getStride() const { return mStride; } + S32 getTypeMask() const { return mTypeMask; } + BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; } + S32 getSize() const { return mNumVerts*mStride; } + S32 getIndicesSize() const { return mNumIndices * sizeof(U32); } + U8* getMappedData() const { return mMappedData; } + U8* getMappedIndices() const { return mMappedIndexData; } + S32 getOffset(S32 type) const { return mOffsets[type]; } + S32 getUsage() const { return mUsage; } + + void setStride(S32 type, S32 new_stride); + + void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count); + void markClean(); + +protected: + S32 mNumVerts; // Number of vertices + S32 mNumIndices; // Number of indices + S32 mStride; + U32 mTypeMask; + S32 mUsage; // GL usage + U32 mGLBuffer; // GL VBO handle + U32 mGLIndices; // GL IBO handle + U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) + U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) + BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory + BOOL mFinal; // if TRUE, buffer can not be mapped again + BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags) + BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. + S32 mOffsets[TYPE_MAX]; + BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not + BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded) + + class DirtyRegion + { + public: + U32 mIndex; + U32 mCount; + U32 mIndicesIndex; + U32 mIndicesCount; + + DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic) + : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic) + { } + }; + + std::vector mDirtyRegions; //vector of dirty regions to rebuild + +public: + static BOOL sRenderActive; + static S32 sCount; + static S32 sGLCount; + static std::vector sDeleteList; + typedef std::list buffer_list_t; + static buffer_list_t sLockedList; + + static BOOL sEnableVBOs; + static S32 sTypeOffsets[TYPE_MAX]; + static U32 sGLRenderBuffer; + static U32 sGLRenderIndices; + static BOOL sVBOActive; + static BOOL sIBOActive; + static U32 sLastMask; + static U32 sAllocatedBytes; +}; + + +#endif // LL_LLVERTEXBUFFER_H diff --git a/linden/indra/llrender/llvertexprogramgl.cpp b/linden/indra/llrender/llvertexprogramgl.cpp index bc00a64..4ccdf01 100644 --- a/linden/indra/llrender/llvertexprogramgl.cpp +++ b/linden/indra/llrender/llvertexprogramgl.cpp @@ -92,13 +92,13 @@ BOOL LLVertexProgramGL::load(const char * filename) line_num++; next_token = strchr(next_token, '\n'); } - char output[1024]; char bad_code[11]; strncpy(bad_code, text_buffer + error_pos, 10); bad_code[10] = '\0'; - sprintf(output, "%s(%d): Vertex Program Error: %s at (%s)\n", filename, line_num, program_error_string, bad_code); - gErrorStream << output << std::endl; + llerrs << filename << "(" << line_num << "): Vertex Program Error: " + << program_error_string << " at (" << bad_code<< ")" + << llendl; // clean up buffer delete[] text_buffer; return FALSE; diff --git a/linden/indra/llrender/text_out.cpp b/linden/indra/llrender/text_out.cpp index f4892b2..572ed03 100644 --- a/linden/indra/llrender/text_out.cpp +++ b/linden/indra/llrender/text_out.cpp @@ -52,7 +52,7 @@ typedef struct s_text_line // const LLFontGL *font; // U8 color[3]; // U8 bg_color[3]; - char line[MAX_TEXT_LINE_LENGTH]; + char line[MAX_TEXT_LINE_LENGTH]; /* Flawfinder: ignore */ S32 x, y; // ETextModifiers tm; // ETextColorModifiers fcm; @@ -84,7 +84,7 @@ void add_text(S32 x, S32 y, char *text) // , ETextModifiers tm, ETextColorModifi TEXT_LINE *linep = &gTextLine[gNumTextLines++]; - strcpy(linep->line, text); + strcpy(linep->line, text); /* Flawfinder: ignore */ linep->x = x; linep->y = y; } -- cgit v1.1