diff options
author | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
commit | 89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch) | |
tree | bcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/llrender | |
parent | Second Life viewer sources 1.13.3.2 (diff) | |
download | meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2 meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz |
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/llrender')
22 files changed, 1453 insertions, 1764 deletions
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 @@ | |||
1 | llrender/llagpmempoolarb.cpp | ||
2 | llrender/llagpmempool.cpp | ||
3 | llrender/llfont.cpp | 1 | llrender/llfont.cpp |
4 | llrender/llfontgl.cpp | 2 | llrender/llfontgl.cpp |
5 | llrender/llgldbg.cpp | 3 | llrender/llgldbg.cpp |
6 | llrender/llimagegl.cpp | 4 | llrender/llimagegl.cpp |
7 | llrender/llvertexprogramgl.cpp | 5 | llrender/llvertexbuffer.cpp |
8 | llrender/text_out.cpp | 6 | 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 @@ | |||
1 | /** | ||
2 | * @file llagpmempool.cpp | ||
3 | * @brief LLAGPMemPool base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "linden_common.h" | ||
29 | |||
30 | #include "llagpmempool.h" | ||
31 | #include "llgl.h" | ||
32 | |||
33 | #include "llagpmempoolarb.h" | ||
34 | #include "llagpmempoolnv.h" | ||
35 | #include "llagpmempoolati.h" | ||
36 | |||
37 | #if LL_DARWIN | ||
38 | #include "llagpmempoolapple.h" | ||
39 | #endif // LL_DARWIN | ||
40 | |||
41 | //static | ||
42 | S32 LLAGPMemPool::LLFreeBlock::sNumBlocks = 0; | ||
43 | |||
44 | LLAGPMemPool::LLAGPMemPool() | ||
45 | { | ||
46 | mSize = 0; | ||
47 | mTotalAllocated = 0; | ||
48 | } | ||
49 | |||
50 | LLAGPMemPool::~LLAGPMemPool() | ||
51 | { | ||
52 | mFreeList.deleteAll(); | ||
53 | } | ||
54 | |||
55 | LLAGPMemPool *LLAGPMemPool::createPool(const U32 size, const BOOL use_vbo) | ||
56 | { | ||
57 | if (gGLManager.mHasVertexBufferObject && use_vbo) | ||
58 | { | ||
59 | return new LLAGPMemPoolARB(size); | ||
60 | } | ||
61 | #if LL_WINDOWS // *FIX: linux can use these, too, with some work. | ||
62 | if (gGLManager.mHasNVFence) | ||
63 | { | ||
64 | return new LLAGPMemPoolNV(size); | ||
65 | } | ||
66 | else if (gGLManager.mHasATIVAO) | ||
67 | { | ||
68 | return new LLAGPMemPoolATI(size); | ||
69 | } | ||
70 | else | ||
71 | #elif LL_DARWIN | ||
72 | if (gGLManager.mHasAPPLEFence && gGLManager.mHasAPPLEVertexArrayRange) | ||
73 | { | ||
74 | return new LLAGPMemPoolAPPLE(size); | ||
75 | } | ||
76 | else | ||
77 | #endif | ||
78 | { | ||
79 | // No AGP memory allocation at all! | ||
80 | return NULL; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | |||
85 | LLAGPMemBlock *LLAGPMemPool::allocBlock(const S32 size) | ||
86 | { | ||
87 | S32 aligned_size = size; | ||
88 | if (size & 0x0f) | ||
89 | { | ||
90 | aligned_size += 16 - (size & 0x0f); | ||
91 | } | ||
92 | |||
93 | if (aligned_size > (mSize - mTotalAllocated)) | ||
94 | { | ||
95 | // We're totally out of AGP memory, bail. | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | LLFreeBlock *free_block = mFreeList.getFirst(); | ||
100 | |||
101 | while (free_block && free_block->mSize < aligned_size) | ||
102 | { | ||
103 | free_block = free_block->getNext(); | ||
104 | } | ||
105 | |||
106 | U32 offset = 0; | ||
107 | |||
108 | if (free_block) | ||
109 | { | ||
110 | if (free_block->mSize == aligned_size) | ||
111 | { | ||
112 | free_block->unlink(); | ||
113 | offset = free_block->mOffset; | ||
114 | delete free_block; | ||
115 | } | ||
116 | else | ||
117 | { | ||
118 | offset = free_block->mOffset + free_block->mSize - aligned_size; | ||
119 | free_block->mSize -= aligned_size; | ||
120 | if (0 == free_block->mSize) | ||
121 | { | ||
122 | free_block->unlink(); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | else | ||
127 | { | ||
128 | //llwarns << "LLAGPMemPool unable to allocate " << size << " bytes" << llendl; | ||
129 | return NULL; | ||
130 | } | ||
131 | |||
132 | mTotalAllocated += aligned_size; | ||
133 | return createBlock(offset, aligned_size); | ||
134 | } | ||
135 | |||
136 | |||
137 | void LLAGPMemPool::freeBlock(LLAGPMemBlock *blockp) | ||
138 | { | ||
139 | if (!blockp->getSize()) | ||
140 | { | ||
141 | return; | ||
142 | } | ||
143 | |||
144 | LLFreeBlock *prev_free = NULL; | ||
145 | LLFreeBlock *cur_free = mFreeList.getFirst(); | ||
146 | |||
147 | while (cur_free && blockp->getOffset() > (U32)cur_free->mOffset) | ||
148 | { | ||
149 | prev_free = cur_free; | ||
150 | cur_free = cur_free->getNext(); | ||
151 | } | ||
152 | |||
153 | LLFreeBlock *new_free = new LLFreeBlock(blockp->getOffset(), blockp->getSize()); | ||
154 | |||
155 | if (prev_free) | ||
156 | { | ||
157 | prev_free->append(*new_free); | ||
158 | coalesce(new_free); | ||
159 | coalesce(prev_free); | ||
160 | } | ||
161 | else | ||
162 | { | ||
163 | mFreeList.append(*new_free); | ||
164 | coalesce(new_free); | ||
165 | } | ||
166 | mTotalAllocated -= blockp->getSize(); | ||
167 | } | ||
168 | |||
169 | void LLAGPMemPool::coalesce(LLFreeBlock *free_block) | ||
170 | { | ||
171 | LLFreeBlock *next = free_block->getNext(); | ||
172 | |||
173 | if (next && (free_block->mOffset + free_block->mSize == next->mOffset)) | ||
174 | { | ||
175 | free_block->mSize += next->mSize; | ||
176 | |||
177 | next->unlink(); | ||
178 | delete next; | ||
179 | |||
180 | coalesce(free_block); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | void LLAGPMemPool::printFreeList() | ||
185 | { | ||
186 | LLFreeBlock *cur_block = mFreeList.getFirst(); | ||
187 | while (cur_block) | ||
188 | { | ||
189 | llinfos << "Cur block begin: " << cur_block->mOffset << llendl; | ||
190 | llinfos << "Cur block end: " << cur_block->mOffset + cur_block->mSize << llendl; | ||
191 | cur_block = cur_block->getNext(); | ||
192 | } | ||
193 | } | ||
194 | |||
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 @@ | |||
1 | /** | ||
2 | * @file llagpmempool.h | ||
3 | * @brief LLAGPMemPool base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_LLAGPMEMPOOL_H | ||
29 | #define LL_LLAGPMEMPOOL_H | ||
30 | |||
31 | #include "stdtypes.h" | ||
32 | #include "lldlinked.h" | ||
33 | |||
34 | // Raw memory handling abstraction, which handles interaction with | ||
35 | // the nVidia and ATI AGP extensions. | ||
36 | |||
37 | // Minimum size we allow allocation for, in order to allow AGP usage... | ||
38 | const S32 MIN_AGP_SIZE = 8000000; | ||
39 | |||
40 | class LLAGPMemBlock; | ||
41 | |||
42 | class LLAGPMemPool | ||
43 | { | ||
44 | public: | ||
45 | LLAGPMemPool(); | ||
46 | virtual ~LLAGPMemPool(); | ||
47 | |||
48 | virtual LLAGPMemBlock *allocBlock(const S32 size); | ||
49 | virtual void freeBlock(LLAGPMemBlock *blockp); | ||
50 | |||
51 | virtual void flush() = 0; | ||
52 | virtual void dump() = 0; | ||
53 | virtual void enable() = 0; | ||
54 | virtual void disable() = 0; | ||
55 | virtual void bind() = 0; | ||
56 | |||
57 | virtual S32 getSize() { return mSize; } | ||
58 | |||
59 | S32 getTotalAllocated() const { return mTotalAllocated; } | ||
60 | static LLAGPMemPool *createPool(const U32 size, const BOOL use_vbo); | ||
61 | |||
62 | struct LLFreeBlock: public LLDLinked<LLFreeBlock> | ||
63 | { | ||
64 | S32 mOffset; | ||
65 | S32 mSize; | ||
66 | LLFreeBlock(const S32 offset, const S32 size) { mOffset = offset; mSize = size; sNumBlocks++; } | ||
67 | ~LLFreeBlock() { sNumBlocks--; } | ||
68 | |||
69 | static S32 sNumBlocks; | ||
70 | }; | ||
71 | |||
72 | // Fencing (for nVidia and Apple) - default is to do nothing (ATI, ARB do not need fencing) | ||
73 | virtual U32 createFence() { return 0; } | ||
74 | virtual void deleteFence(const U32 fence) {} | ||
75 | virtual void sendFence(U32 fence) {} | ||
76 | virtual void waitFence(U32 fence) {} | ||
77 | |||
78 | void printFreeList(); | ||
79 | protected: | ||
80 | |||
81 | void coalesce(LLFreeBlock *free_block); | ||
82 | virtual LLAGPMemBlock *createBlock(const U32 offset, const U32 size) = 0; | ||
83 | LLDLinked<LLFreeBlock> mFreeList; | ||
84 | |||
85 | S32 mSize; | ||
86 | S32 mTotalAllocated; | ||
87 | }; | ||
88 | |||
89 | // An AGP memory block, which contains all the info needed to | ||
90 | // copy data in/out. | ||
91 | class LLAGPMemBlock | ||
92 | { | ||
93 | public: | ||
94 | LLAGPMemBlock(LLAGPMemPool *mem_poolp) : mMemPoolp(mem_poolp) {} | ||
95 | virtual ~LLAGPMemBlock() {} | ||
96 | virtual void copy (void *source, const U32 size_bytes) = 0; | ||
97 | virtual void copyColor(void *source, const U32 size_bytes) = 0; | ||
98 | |||
99 | virtual void bindGLVertexPointer(const U32 stride, const U32 offset) = 0; | ||
100 | virtual void bindGLNormalPointer(const U32 stride, const U32 offset) = 0; | ||
101 | virtual void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) = 0; | ||
102 | virtual void bindGLColorPointer(const U32 stride, const U32 offset) = 0; | ||
103 | virtual void bindGLTexCoordPointer(const U32 stride, const U32 offset) = 0; | ||
104 | virtual void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) = 0; | ||
105 | virtual void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) = 0; | ||
106 | |||
107 | virtual BOOL hasMappedMem() const = 0; | ||
108 | virtual U8* getMappedMem() = 0; | ||
109 | |||
110 | virtual U32 createFence() = 0; | ||
111 | virtual void deleteFence(const U32 fence) = 0; | ||
112 | virtual void sendFence(U32 fence) = 0; | ||
113 | virtual void waitFence(U32 fence) = 0; | ||
114 | |||
115 | virtual U32 getOffset() const = 0; | ||
116 | virtual U32 getSize() const = 0; | ||
117 | protected: | ||
118 | LLAGPMemPool *mMemPoolp; | ||
119 | }; | ||
120 | |||
121 | #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 @@ | |||
1 | /** | ||
2 | * @file llagpmempoolapple.cpp | ||
3 | * @brief LLAGPMemPoolAPPLE base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifdef LL_DARWIN | ||
29 | |||
30 | #include "linden_common.h" | ||
31 | |||
32 | #include "llagpmempoolapple.h" | ||
33 | #include "llgl.h" | ||
34 | |||
35 | #include "llglheaders.h" | ||
36 | |||
37 | LLAGPMemPoolAPPLE::LLAGPMemPoolAPPLE(S32 request) : LLAGPMemPool() | ||
38 | { | ||
39 | llinfos << "Creating LLAGPMemPoolAPPLE" << llendl; | ||
40 | stop_glerror(); | ||
41 | if (!gGLManager.mHasAPPLEFence || !gGLManager.mHasAPPLEVertexArrayRange) | ||
42 | { | ||
43 | llerrs << "necessary extensions not present!" << llendl; | ||
44 | } | ||
45 | |||
46 | // No special allocation is necessary for the Apple extensions | ||
47 | mBase = (U8*)::malloc(request); | ||
48 | mSize = request; | ||
49 | |||
50 | if (mBase) | ||
51 | { | ||
52 | mFreeList.append(*(new LLFreeBlock(0,mSize))); | ||
53 | } | ||
54 | else | ||
55 | { | ||
56 | mSize = 0; | ||
57 | } | ||
58 | |||
59 | flush_glerror(); | ||
60 | } | ||
61 | |||
62 | LLAGPMemBlockAPPLE::~LLAGPMemBlockAPPLE() | ||
63 | { | ||
64 | mMemPoolp->freeBlock(this); | ||
65 | } | ||
66 | |||
67 | LLAGPMemBlock *LLAGPMemPoolAPPLE::createBlock(const U32 offset, const U32 size) | ||
68 | { | ||
69 | return new LLAGPMemBlockAPPLE(this, mBase, offset, size); | ||
70 | } | ||
71 | |||
72 | LLAGPMemPoolAPPLE::~LLAGPMemPoolAPPLE() | ||
73 | { | ||
74 | if (mBase) | ||
75 | { | ||
76 | // MBW -- This really belongs in a call which is the opposite of bind()... | ||
77 | glVertexArrayRangeAPPLE(0, 0); | ||
78 | ::free(mBase); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | void LLAGPMemPoolAPPLE::bind() | ||
83 | { | ||
84 | if(mBase) | ||
85 | { | ||
86 | glVertexArrayRangeAPPLE(mSize, mBase); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | void LLAGPMemPoolAPPLE::enable() | ||
91 | { | ||
92 | glEnableClientState(GL_VERTEX_ARRAY_RANGE_APPLE); | ||
93 | } | ||
94 | |||
95 | void LLAGPMemPoolAPPLE::disable() | ||
96 | { | ||
97 | glDisableClientState(GL_VERTEX_ARRAY_RANGE_APPLE); | ||
98 | } | ||
99 | |||
100 | void LLAGPMemPoolAPPLE::flush() | ||
101 | { | ||
102 | if(mBase) | ||
103 | { | ||
104 | glFlushVertexArrayRangeAPPLE(mSize, mBase); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | void LLAGPMemPoolAPPLE::dump() | ||
109 | { | ||
110 | LLFreeBlock *prev = 0; | ||
111 | LLFreeBlock *block = mFreeList.getFirst(); | ||
112 | |||
113 | int d=0; | ||
114 | |||
115 | int i=0; | ||
116 | while (block) | ||
117 | { | ||
118 | i++; | ||
119 | if (prev) | ||
120 | { | ||
121 | d = (S32)block->mOffset - ((S32)prev->mOffset + prev->mSize); | ||
122 | } | ||
123 | else d = 0; | ||
124 | |||
125 | prev = block; | ||
126 | block = block->getNext(); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | |||
131 | U32 LLAGPMemPoolAPPLE::createFence() | ||
132 | { | ||
133 | U32 fence; | ||
134 | glGenFencesAPPLE(1, (GLuint*)&fence); | ||
135 | glSetFenceAPPLE(fence); | ||
136 | glFinishFenceAPPLE(fence); | ||
137 | return fence; | ||
138 | } | ||
139 | |||
140 | |||
141 | void LLAGPMemPoolAPPLE::deleteFence(const U32 fence) | ||
142 | { | ||
143 | glDeleteFencesAPPLE(1, (GLuint*)&fence); | ||
144 | } | ||
145 | |||
146 | |||
147 | void LLAGPMemPoolAPPLE::sendFence(U32 fence) | ||
148 | { | ||
149 | glSetFenceAPPLE(fence); | ||
150 | } | ||
151 | |||
152 | |||
153 | void LLAGPMemPoolAPPLE::waitFence(U32 fence) | ||
154 | { | ||
155 | if(!glTestFenceAPPLE(fence)) | ||
156 | { | ||
157 | glFinishFenceAPPLE(fence); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | |||
162 | ///////////////////////////// | ||
163 | // | ||
164 | // LLAGPMemBlockAPPLE | ||
165 | // | ||
166 | // APPLE Implementation of an AGP memory block | ||
167 | // | ||
168 | |||
169 | LLAGPMemBlockAPPLE::LLAGPMemBlockAPPLE(LLAGPMemPool *mem_poolp, U8 *baseptr, S32 offset, const U32 size) : LLAGPMemBlock(mem_poolp) | ||
170 | { | ||
171 | mMemp = baseptr + offset; | ||
172 | mOffset = offset; | ||
173 | mSize = size; | ||
174 | } | ||
175 | |||
176 | |||
177 | void LLAGPMemBlockAPPLE::bindGLVertexPointer(const U32 stride, const U32 offset) | ||
178 | { | ||
179 | if (!mMemp) | ||
180 | { | ||
181 | llerrs << "Binding empty vertex array" << llendl; | ||
182 | } | ||
183 | glVertexPointer(3, GL_FLOAT, stride, mMemp + offset); | ||
184 | } | ||
185 | |||
186 | void LLAGPMemBlockAPPLE::bindGLNormalPointer(const U32 stride, const U32 offset) | ||
187 | { | ||
188 | if (!mMemp) | ||
189 | { | ||
190 | llerrs << "Binding empty normal array" << llendl; | ||
191 | } | ||
192 | glNormalPointer(GL_FLOAT, stride, mMemp + offset); | ||
193 | } | ||
194 | |||
195 | |||
196 | void LLAGPMemBlockAPPLE::bindGLColorPointer(const U32 stride, const U32 offset) | ||
197 | { | ||
198 | if (!mMemp) | ||
199 | { | ||
200 | llerrs << "Binding empty color array" << llendl; | ||
201 | } | ||
202 | glColorPointer(4, GL_UNSIGNED_BYTE, stride, mMemp + offset); | ||
203 | } | ||
204 | |||
205 | |||
206 | void LLAGPMemBlockAPPLE::bindGLTexCoordPointer(const U32 stride, const U32 offset) | ||
207 | { | ||
208 | if (!mMemp) | ||
209 | { | ||
210 | llerrs << "Binding empty texcoord array" << llendl; | ||
211 | } | ||
212 | glTexCoordPointer(2, GL_FLOAT, stride, mMemp + offset); | ||
213 | } | ||
214 | |||
215 | |||
216 | void LLAGPMemBlockAPPLE::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) | ||
217 | { | ||
218 | if (!mMemp) | ||
219 | { | ||
220 | llerrs << "Binding empty vertex weight array" << llendl; | ||
221 | } | ||
222 | |||
223 | if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, (F32 *)(mMemp + offset)); | ||
224 | } | ||
225 | |||
226 | void LLAGPMemBlockAPPLE::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) | ||
227 | { | ||
228 | if (!mMemp) | ||
229 | { | ||
230 | llerrs << "Binding empty vertex weight array" << llendl; | ||
231 | } | ||
232 | |||
233 | if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, 0, (F32 *)(mMemp + offset)); | ||
234 | } | ||
235 | |||
236 | void LLAGPMemBlockAPPLE::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) | ||
237 | { | ||
238 | if (!mMemp) | ||
239 | { | ||
240 | llerrs << "Binding empty vertex weight array" << llendl; | ||
241 | } | ||
242 | set_vertex_clothing_weights(index, stride, (LLVector4 *)(mMemp + offset)); | ||
243 | } | ||
244 | |||
245 | U8* LLAGPMemBlockAPPLE::getMappedMem() | ||
246 | { | ||
247 | return mMemp; | ||
248 | } | ||
249 | |||
250 | |||
251 | void LLAGPMemBlockAPPLE::copy(void *mem, const U32 size) | ||
252 | { | ||
253 | if (!mMemp || !mem) | ||
254 | { | ||
255 | return; | ||
256 | } | ||
257 | llassert(size <= mSize); | ||
258 | |||
259 | memcpy( mMemp, mem, size ); | ||
260 | |||
261 | glFlushVertexArrayRangeAPPLE(size, mMemp); | ||
262 | } | ||
263 | |||
264 | void LLAGPMemBlockAPPLE::copyColor(void *mem, const U32 size) | ||
265 | { | ||
266 | if (!mMemp || !mem) | ||
267 | { | ||
268 | return; | ||
269 | } | ||
270 | llassert(size <= mSize); | ||
271 | |||
272 | memcpy( mMemp, mem, size ); | ||
273 | |||
274 | glFlushVertexArrayRangeAPPLE(size, mMemp); | ||
275 | } | ||
276 | |||
277 | |||
278 | |||
279 | U32 LLAGPMemBlockAPPLE::createFence() | ||
280 | { | ||
281 | U32 fence; | ||
282 | glGenFencesAPPLE(1, (GLuint*)&fence); | ||
283 | glSetFenceAPPLE(fence); | ||
284 | glFinishFenceAPPLE(fence); | ||
285 | return fence; | ||
286 | } | ||
287 | |||
288 | void LLAGPMemBlockAPPLE::deleteFence(const U32 fence) | ||
289 | { | ||
290 | glDeleteFencesAPPLE(1, (GLuint*)&fence); | ||
291 | } | ||
292 | |||
293 | void LLAGPMemBlockAPPLE::sendFence(U32 fence) | ||
294 | { | ||
295 | glSetFenceAPPLE(fence); | ||
296 | } | ||
297 | |||
298 | void LLAGPMemBlockAPPLE::waitFence(U32 fence) | ||
299 | { | ||
300 | if(!glTestFenceAPPLE(fence)) | ||
301 | { | ||
302 | glFinishFenceAPPLE(fence); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | // MBW -- May want this at some point... | ||
307 | #if 0 | ||
308 | void LLAGPMemBlockAPPLE::flush() | ||
309 | { | ||
310 | glFlushVertexArrayRangeAPPLE(mSize, mMemp); | ||
311 | } | ||
312 | #endif | ||
313 | |||
314 | #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 @@ | |||
1 | /** | ||
2 | * @file llagpmempoolapple.h | ||
3 | * @brief LLAGPMemPoolAPPLE base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_LLAGPMEMPOOLAPPLE_H | ||
29 | #define LL_LLAGPMEMPOOLAPPLE_H | ||
30 | |||
31 | #include "llagpmempool.h" | ||
32 | |||
33 | #if LL_DARWIN | ||
34 | class LLAGPMemPoolAPPLE : public LLAGPMemPool | ||
35 | { | ||
36 | public: | ||
37 | LLAGPMemPoolAPPLE(S32 request); | ||
38 | virtual ~LLAGPMemPoolAPPLE(); | ||
39 | |||
40 | /*virtual*/ void flush(); | ||
41 | /*virtual*/ void dump(); | ||
42 | /*virtual*/ void enable(); | ||
43 | /*virtual*/ void disable(); | ||
44 | /*virtual*/ void bind(); | ||
45 | |||
46 | /*virtual*/ U32 createFence(); | ||
47 | /*virtual*/ void deleteFence(const U32 fence); | ||
48 | /*virtual*/ void sendFence(U32 fence); | ||
49 | /*virtual*/ void waitFence(U32 fence); | ||
50 | |||
51 | protected: | ||
52 | /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size); | ||
53 | |||
54 | protected: | ||
55 | U8 *mBase; | ||
56 | }; | ||
57 | |||
58 | class LLAGPMemBlockAPPLE : public LLAGPMemBlock | ||
59 | { | ||
60 | public: | ||
61 | LLAGPMemBlockAPPLE(LLAGPMemPool *mem_poolp, U8 *baseptr, const S32 offset, const U32 size); | ||
62 | virtual ~LLAGPMemBlockAPPLE(); | ||
63 | |||
64 | /*virtual*/ void copy (void *source, const U32 size_bytes); | ||
65 | /*virtual*/ void copyColor(void *source, const U32 size_bytes); | ||
66 | /*virtual*/ void free(); | ||
67 | |||
68 | /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset); | ||
69 | /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset); | ||
70 | /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset); | ||
71 | /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset); | ||
72 | /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset); | ||
73 | /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset); | ||
74 | /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset); | ||
75 | |||
76 | /*virtual*/ U32 getOffset() const { return mOffset; } | ||
77 | /*virtual*/ U32 getSize() const { return mSize; } | ||
78 | |||
79 | /*virtual*/ BOOL hasMappedMem() const { return TRUE; } | ||
80 | /*virtual*/ U8* getMappedMem(); | ||
81 | /*virtual*/ U32 createFence(); | ||
82 | /*virtual*/ void deleteFence(const U32 fence); | ||
83 | /*virtual*/ void sendFence(U32 fence); | ||
84 | /*virtual*/ void waitFence(U32 fence); | ||
85 | |||
86 | private: | ||
87 | U8 *mMemp; | ||
88 | U32 mOffset; // Offset from base | ||
89 | U32 mSize; | ||
90 | friend class LLAGPMemPoolAPPLE; | ||
91 | }; | ||
92 | |||
93 | #endif // LL_DARWIN | ||
94 | |||
95 | #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 @@ | |||
1 | /** | ||
2 | * @file llagpmempoolarb.cpp | ||
3 | * @brief LLAGPMemPoolARB base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "linden_common.h" | ||
29 | #include "llagpmempoolarb.h" | ||
30 | #include "llgl.h" | ||
31 | |||
32 | #include "llglheaders.h" | ||
33 | |||
34 | LLAGPMemPoolARB::LLAGPMemPoolARB(S32 request) : LLAGPMemPool() | ||
35 | { | ||
36 | llinfos << "Creating LLAGPMemPoolARB" << llendl; | ||
37 | stop_glerror(); | ||
38 | if (!gGLManager.mHasVertexBufferObject) | ||
39 | { | ||
40 | llerrs << "No ARB vertex buffer object extension!" << llendl; | ||
41 | } | ||
42 | |||
43 | mName = 0; | ||
44 | |||
45 | mSize = request; | ||
46 | flush_glerror(); | ||
47 | } | ||
48 | |||
49 | |||
50 | LLAGPMemPoolARB::~LLAGPMemPoolARB() | ||
51 | { | ||
52 | } | ||
53 | |||
54 | |||
55 | LLAGPMemBlock* LLAGPMemPoolARB::allocBlock(const S32 size) | ||
56 | { | ||
57 | return allocBlock(size, GL_ARRAY_BUFFER_ARB); | ||
58 | } | ||
59 | |||
60 | LLAGPMemBlock *LLAGPMemPoolARB::allocBlock(const S32 size, U32 target) | ||
61 | { | ||
62 | S32 aligned_size = size; | ||
63 | if (size & 0x0f) | ||
64 | { | ||
65 | aligned_size += 16 - (size & 0x0f); | ||
66 | } | ||
67 | |||
68 | if (aligned_size > (mSize - mTotalAllocated)) | ||
69 | { | ||
70 | // We're totally out of AGP memory, bail. | ||
71 | return (LLAGPMemBlock *)0; | ||
72 | } | ||
73 | |||
74 | mTotalAllocated += aligned_size; | ||
75 | return createBlock(0, aligned_size, target); | ||
76 | } | ||
77 | |||
78 | |||
79 | void LLAGPMemPoolARB::freeBlock(LLAGPMemBlock *blockp) | ||
80 | { | ||
81 | if (!blockp->getSize()) | ||
82 | { | ||
83 | return; | ||
84 | } | ||
85 | LLAGPMemBlockARB *arb_blockp = (LLAGPMemBlockARB*)blockp; | ||
86 | U32 name[1]; | ||
87 | name[0] = arb_blockp->getName(); | ||
88 | stop_glerror(); | ||
89 | glDeleteBuffersARB(1, (GLuint*)name); | ||
90 | stop_glerror(); | ||
91 | mTotalAllocated -= blockp->getSize(); | ||
92 | } | ||
93 | |||
94 | LLAGPMemBlock *LLAGPMemPoolARB::createBlock(const U32 offset, const U32 size) | ||
95 | { | ||
96 | return createBlock(offset, size, GL_ARRAY_BUFFER_ARB); | ||
97 | } | ||
98 | |||
99 | LLAGPMemBlock *LLAGPMemPoolARB::createBlock(const U32 offset, const U32 size, const U32 target) | ||
100 | { | ||
101 | U32 name[1]; | ||
102 | stop_glerror(); | ||
103 | glGenBuffersARB(1, (GLuint*)name); | ||
104 | stop_glerror(); | ||
105 | return new LLAGPMemBlockARB(this, name[0], offset, size, target); | ||
106 | } | ||
107 | |||
108 | void LLAGPMemPoolARB::disable() | ||
109 | { | ||
110 | } | ||
111 | |||
112 | void LLAGPMemPoolARB::dump() | ||
113 | { | ||
114 | } | ||
115 | |||
116 | |||
117 | ///////////////////////////// | ||
118 | // | ||
119 | // LLAGPMemBlockARB | ||
120 | // | ||
121 | // ARB ImplementARBon of an AGP memory block | ||
122 | // | ||
123 | |||
124 | LLAGPMemBlockARB::LLAGPMemBlockARB(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size, U32 target) : | ||
125 | LLAGPMemBlock(mem_poolp), mTarget(target) | ||
126 | { | ||
127 | llassert(name > 0); | ||
128 | mName = name; | ||
129 | stop_glerror(); | ||
130 | glBindBufferARB(mTarget, mName); | ||
131 | stop_glerror(); | ||
132 | |||
133 | glBufferDataARB(mTarget, size, NULL, GL_DYNAMIC_DRAW_ARB); | ||
134 | |||
135 | stop_glerror(); | ||
136 | glBindBufferARB(mTarget, 0); | ||
137 | stop_glerror(); | ||
138 | mSize = size; | ||
139 | } | ||
140 | |||
141 | |||
142 | void LLAGPMemBlockARB::bindGLVertexPointer(const U32 stride, const U32 offset) | ||
143 | { | ||
144 | stop_glerror(); | ||
145 | glBindBufferARB(mTarget, mName); | ||
146 | glVertexPointer(3, GL_FLOAT, stride, (GLvoid*)((intptr_t)offset)); | ||
147 | glBindBufferARB(mTarget, 0); | ||
148 | } | ||
149 | |||
150 | |||
151 | void LLAGPMemBlockARB::bindGLNormalPointer(const U32 stride, const U32 offset) | ||
152 | { | ||
153 | stop_glerror(); | ||
154 | glBindBufferARB(mTarget, mName); | ||
155 | glNormalPointer(GL_FLOAT, stride, (GLvoid*)((intptr_t)offset)); | ||
156 | glBindBufferARB(mTarget, 0); | ||
157 | stop_glerror(); | ||
158 | } | ||
159 | |||
160 | |||
161 | void LLAGPMemBlockARB::bindGLColorPointer(const U32 stride, const U32 offset) | ||
162 | { | ||
163 | stop_glerror(); | ||
164 | glBindBufferARB(mTarget, mName); | ||
165 | glColorPointer(4, GL_UNSIGNED_BYTE, stride, (GLvoid*)((intptr_t)offset)); | ||
166 | glBindBufferARB(mTarget, 0); | ||
167 | stop_glerror(); | ||
168 | } | ||
169 | |||
170 | |||
171 | void LLAGPMemBlockARB::bindGLTexCoordPointer(const U32 stride, const U32 offset) | ||
172 | { | ||
173 | stop_glerror(); | ||
174 | glBindBufferARB(mTarget, mName); | ||
175 | glTexCoordPointer(2, GL_FLOAT, stride, (GLvoid*)((intptr_t)offset)); | ||
176 | glBindBufferARB(mTarget, 0); | ||
177 | stop_glerror(); | ||
178 | } | ||
179 | |||
180 | |||
181 | void LLAGPMemBlockARB::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) | ||
182 | { | ||
183 | stop_glerror(); | ||
184 | glBindBufferARB(mTarget, mName); | ||
185 | set_vertex_weights(index, (F32*)(intptr_t)offset); | ||
186 | glBindBufferARB(mTarget, 0); | ||
187 | stop_glerror(); | ||
188 | } | ||
189 | |||
190 | void LLAGPMemBlockARB::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) | ||
191 | { | ||
192 | stop_glerror(); | ||
193 | glBindBufferARB(mTarget, mName); | ||
194 | set_binormals(index, stride, (LLVector3*)(intptr_t)offset); | ||
195 | glBindBufferARB(mTarget, 0); | ||
196 | stop_glerror(); | ||
197 | } | ||
198 | |||
199 | |||
200 | void LLAGPMemBlockARB::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) | ||
201 | { | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | |||
206 | void LLAGPMemBlockARB::copy(void *mem, const U32 size) | ||
207 | { | ||
208 | stop_glerror(); | ||
209 | llassert(size <= mSize); | ||
210 | glBindBufferARB(mTarget, mName); | ||
211 | glBufferSubDataARB(mTarget, 0, size, mem); | ||
212 | glBindBufferARB(mTarget, 0); | ||
213 | stop_glerror(); | ||
214 | } | ||
215 | |||
216 | void LLAGPMemBlockARB::copyColor(void *mem, const U32 size) | ||
217 | { | ||
218 | stop_glerror(); | ||
219 | llassert(size <= mSize); | ||
220 | glBindBufferARB(mTarget, mName); | ||
221 | glBufferSubDataARB(mTarget, 0, size, mem); | ||
222 | glBindBufferARB(mTarget, 0); | ||
223 | stop_glerror(); | ||
224 | } | ||
225 | |||
226 | |||
227 | U8* LLAGPMemBlockARB::getMappedMem() | ||
228 | { | ||
229 | return NULL; | ||
230 | } | ||
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 @@ | |||
1 | /** | ||
2 | * @file llagpmempoolarb.h | ||
3 | * @brief LLAGPMemPoolARB base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_LLAGPMEMPOOLARB_H | ||
29 | #define LL_LLAGPMEMPOOLARB_H | ||
30 | |||
31 | #include "llagpmempool.h" | ||
32 | |||
33 | class LLAGPMemPoolARB : public LLAGPMemPool | ||
34 | { | ||
35 | public: | ||
36 | LLAGPMemPoolARB(S32 request); | ||
37 | virtual ~LLAGPMemPoolARB(); | ||
38 | |||
39 | /*virtual*/ LLAGPMemBlock* allocBlock(const S32 size); | ||
40 | LLAGPMemBlock *allocBlock(const S32 size, U32 target); | ||
41 | /*virtual*/ void freeBlock(LLAGPMemBlock *blockp); | ||
42 | |||
43 | void bind() {} | ||
44 | |||
45 | void enable() {} | ||
46 | |||
47 | /*virtual*/ void disable(); | ||
48 | |||
49 | void flush() {} | ||
50 | |||
51 | // No point in these being inline, is there? They're virtual functions anyway... | ||
52 | /*virtual*/ inline LLAGPMemBlock *alloc(S32 size); | ||
53 | /*virtual*/ inline void free(LLAGPMemBlock *block); | ||
54 | /*virtual*/ inline void dump(); | ||
55 | protected: | ||
56 | /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size); | ||
57 | LLAGPMemBlock *createBlock(const U32 offset, const U32 size, const U32 target); | ||
58 | |||
59 | protected: | ||
60 | U32 mName; | ||
61 | }; | ||
62 | |||
63 | class LLAGPMemBlockARB : public LLAGPMemBlock | ||
64 | { | ||
65 | public: | ||
66 | LLAGPMemBlockARB(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size, U32 target); | ||
67 | virtual ~LLAGPMemBlockARB() { mMemPoolp->freeBlock(this); }; | ||
68 | |||
69 | /*virtual*/ void copy (void *source, const U32 size_bytes); | ||
70 | /*virtual*/ void copyColor(void *source, const U32 size_bytes); | ||
71 | /*virtual*/ void free(); | ||
72 | |||
73 | /*virtual*/ void bind(); | ||
74 | /*virtual*/ void unbind(); | ||
75 | |||
76 | /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset); | ||
77 | /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset); | ||
78 | /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset); | ||
79 | /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset); | ||
80 | /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset); | ||
81 | /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset); | ||
82 | /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset); | ||
83 | |||
84 | /*virtual*/ U32 getOffset() const { return 0; } | ||
85 | /*virtual*/ U32 getSize() const { return mSize; } | ||
86 | |||
87 | /*virtual*/ BOOL hasMappedMem() const { return FALSE; } | ||
88 | /*virtual*/ U8* getMappedMem(); | ||
89 | /*virtual*/ U32 createFence() { return 0; } | ||
90 | /*virtual*/ void deleteFence(const U32 fence) {} | ||
91 | /*virtual*/ void sendFence(U32 fence) { } | ||
92 | /*virtual*/ void waitFence(U32 fence) { } | ||
93 | |||
94 | U32 getName() const { return mName; } | ||
95 | private: | ||
96 | U32 mName; | ||
97 | U32 mSize; | ||
98 | U32 mTarget; | ||
99 | |||
100 | friend class LLAGPMemPoolARB; | ||
101 | }; | ||
102 | |||
103 | #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 @@ | |||
1 | /** | ||
2 | * @file llagpmempoolati.cpp | ||
3 | * @brief LLAGPMemPoolATI base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "linden_common.h" | ||
29 | |||
30 | #include "llagpmempoolati.h" | ||
31 | #include "llgl.h" | ||
32 | |||
33 | #include "llglheaders.h" | ||
34 | |||
35 | LLAGPMemPoolATI::LLAGPMemPoolATI(S32 request) : LLAGPMemPool() | ||
36 | { | ||
37 | llinfos << "Creating LLAGPMemPoolATI" << llendl; | ||
38 | stop_glerror(); | ||
39 | if (!gGLManager.mHasATIVAO) | ||
40 | { | ||
41 | llerrs << "No ATI AGI memory extension!" << llendl; | ||
42 | } | ||
43 | |||
44 | mName = 0; | ||
45 | |||
46 | // More than 4MB of agp available | ||
47 | while (!mName && (request > 0)) | ||
48 | { | ||
49 | mName = glNewObjectBufferATI(request, NULL, GL_DYNAMIC_ATI); | ||
50 | mSize = request; | ||
51 | request >>= 1; | ||
52 | } | ||
53 | |||
54 | if (mName) | ||
55 | { | ||
56 | mFreeList.append(*(new LLFreeBlock(0, mSize))); | ||
57 | } | ||
58 | else | ||
59 | { | ||
60 | llinfos << "Unable to allocate AGP memory!" << llendl; | ||
61 | mSize = 0; | ||
62 | } | ||
63 | flush_glerror(); | ||
64 | } | ||
65 | |||
66 | |||
67 | LLAGPMemPoolATI::~LLAGPMemPoolATI() | ||
68 | { | ||
69 | if (mName) | ||
70 | { | ||
71 | glFreeObjectBufferATI(mName); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | |||
76 | LLAGPMemBlock *LLAGPMemPoolATI::createBlock(const U32 offset, const U32 size) | ||
77 | { | ||
78 | return new LLAGPMemBlockATI(this, mName, offset, size); | ||
79 | } | ||
80 | |||
81 | |||
82 | void LLAGPMemPoolATI::dump() | ||
83 | { | ||
84 | } | ||
85 | |||
86 | |||
87 | ///////////////////////////// | ||
88 | // | ||
89 | // LLAGPMemBlockATI | ||
90 | // | ||
91 | // ATI Implementation of an AGP memory block | ||
92 | // | ||
93 | |||
94 | LLAGPMemBlockATI::LLAGPMemBlockATI(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size) : | ||
95 | LLAGPMemBlock(mem_poolp) | ||
96 | { | ||
97 | mName = name; | ||
98 | mOffset = offset; | ||
99 | mSize = size; | ||
100 | } | ||
101 | |||
102 | |||
103 | void LLAGPMemBlockATI::bindGLVertexPointer(const U32 stride, const U32 offset) | ||
104 | { | ||
105 | glArrayObjectATI(GL_VERTEX_ARRAY, 3, GL_FLOAT, stride, mName, mOffset + offset); | ||
106 | } | ||
107 | |||
108 | |||
109 | void LLAGPMemBlockATI::bindGLNormalPointer(const U32 stride, const U32 offset) | ||
110 | { | ||
111 | glArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, stride, mName, mOffset + offset); | ||
112 | } | ||
113 | |||
114 | |||
115 | void LLAGPMemBlockATI::bindGLColorPointer(const U32 stride, const U32 offset) | ||
116 | { | ||
117 | glArrayObjectATI(GL_COLOR_ARRAY, 4, GL_UNSIGNED_BYTE, stride, mName, mOffset + offset); | ||
118 | } | ||
119 | |||
120 | |||
121 | void LLAGPMemBlockATI::bindGLTexCoordPointer(const U32 stride, const U32 offset) | ||
122 | { | ||
123 | glArrayObjectATI(GL_TEXTURE_COORD_ARRAY, 2, GL_FLOAT, stride, mName, mOffset + offset); | ||
124 | } | ||
125 | |||
126 | |||
127 | void LLAGPMemBlockATI::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) | ||
128 | { | ||
129 | glVertexAttribArrayObjectATI(index, 3, GL_FLOAT, FALSE, stride, mName, mOffset + offset); | ||
130 | } | ||
131 | |||
132 | |||
133 | void LLAGPMemBlockATI::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) | ||
134 | { | ||
135 | //glArrayObjectATI(GL_WEIGHT_ARRAY_ARB, 1, GL_FLOAT, stride, mName, mOffset + offset); | ||
136 | glVertexAttribArrayObjectATI(index, 1, GL_FLOAT, FALSE, stride, mName, mOffset + offset); | ||
137 | } | ||
138 | |||
139 | void LLAGPMemBlockATI::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) | ||
140 | { | ||
141 | glVertexAttribArrayObjectATI(index, 4, GL_FLOAT, FALSE, stride, mName, mOffset + offset); | ||
142 | } | ||
143 | |||
144 | U8* LLAGPMemBlockATI::getMappedMem() | ||
145 | { | ||
146 | return NULL; | ||
147 | } | ||
148 | |||
149 | void LLAGPMemBlockATI::copy(void *mem, const U32 size) | ||
150 | { | ||
151 | llassert(size <= mSize); | ||
152 | glUpdateObjectBufferATI(mName, mOffset, size, mem, GL_PRESERVE_ATI); | ||
153 | } | ||
154 | |||
155 | void LLAGPMemBlockATI::copyColor(void *mem, const U32 size) | ||
156 | { | ||
157 | llassert(size <= mSize); | ||
158 | glUpdateObjectBufferATI(mName, mOffset, size, mem, GL_PRESERVE_ATI); | ||
159 | } | ||
160 | |||
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 @@ | |||
1 | /** | ||
2 | * @file llagpmempoolati.h | ||
3 | * @brief LLAGPMemPoolATI base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_LLAGPMEMPOOLATI_H | ||
29 | #define LL_LLAGPMEMPOOLATI_H | ||
30 | |||
31 | #include "llagpmempool.h" | ||
32 | |||
33 | class LLAGPMemPoolATI : public LLAGPMemPool | ||
34 | { | ||
35 | public: | ||
36 | LLAGPMemPoolATI(S32 request); | ||
37 | virtual ~LLAGPMemPoolATI(); | ||
38 | |||
39 | void bind() {} | ||
40 | |||
41 | void enable() {} | ||
42 | |||
43 | void disable() {} | ||
44 | |||
45 | void flush() {} | ||
46 | |||
47 | // No point in these being inline, is there? They're virtual functions anyway... | ||
48 | /*virtual*/ inline LLAGPMemBlock *alloc(S32 size); | ||
49 | /*virtual*/ inline void free(LLAGPMemBlock *block); | ||
50 | /*virtual*/ inline void dump(); | ||
51 | protected: | ||
52 | /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size); | ||
53 | |||
54 | protected: | ||
55 | U32 mName; | ||
56 | }; | ||
57 | |||
58 | class LLAGPMemBlockATI : public LLAGPMemBlock | ||
59 | { | ||
60 | public: | ||
61 | LLAGPMemBlockATI(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size); | ||
62 | virtual ~LLAGPMemBlockATI() { mMemPoolp->freeBlock(this); }; | ||
63 | |||
64 | /*virtual*/ void copy (void *source, const U32 size_bytes); | ||
65 | /*virtual*/ void copyColor(void *source, const U32 size_bytes); | ||
66 | /*virtual*/ void free(); | ||
67 | /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset); | ||
68 | /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset); | ||
69 | /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride,const U32 offset); | ||
70 | /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset); | ||
71 | /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset); | ||
72 | /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset); | ||
73 | /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset); | ||
74 | |||
75 | /*virtual*/ U32 getOffset() const { return mOffset; } | ||
76 | /*virtual*/ U32 getSize() const { return mSize; } | ||
77 | |||
78 | /*virtual*/ BOOL hasMappedMem() const { return TRUE; } | ||
79 | /*virtual*/ U8* getMappedMem(); | ||
80 | /*virtual*/ U32 createFence() { return 0; } | ||
81 | /*virtual*/ void deleteFence(const U32 fence) {} | ||
82 | /*virtual*/ void sendFence(U32 fence) { } | ||
83 | /*virtual*/ void waitFence(U32 fence) { } | ||
84 | private: | ||
85 | U32 mName; | ||
86 | U32 mOffset; | ||
87 | U32 mSize; | ||
88 | |||
89 | friend class LLAGPMemPoolATI; | ||
90 | }; | ||
91 | |||
92 | #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 @@ | |||
1 | /** | ||
2 | * @file llagpmempoolnv.cpp | ||
3 | * @brief LLAGPMemPoolNV base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "linden_common.h" | ||
29 | |||
30 | #ifndef LL_LINUX | ||
31 | |||
32 | #include "llagpmempoolnv.h" | ||
33 | #include "llgl.h" | ||
34 | |||
35 | #include "llglheaders.h" | ||
36 | |||
37 | #if LL_WINDOWS | ||
38 | //#define LL_USE_NEW_MEM_OPS 1 | ||
39 | #endif | ||
40 | #if LL_USE_NEW_MEM_OPS | ||
41 | #include "new_mem_ops.h" | ||
42 | #endif | ||
43 | |||
44 | BOOL LLAGPMemPoolNV::sWriteOK = TRUE; | ||
45 | |||
46 | LLAGPMemPoolNV::LLAGPMemPoolNV(int request) : LLAGPMemPool() | ||
47 | { | ||
48 | llinfos << "Creating LLAGPMemPoolNV" << llendl; | ||
49 | stop_glerror(); | ||
50 | if (!gGLManager.mHasNVFence) | ||
51 | { | ||
52 | llerrs << "wglAllocateMemoryNV not defined!" << llendl; | ||
53 | } | ||
54 | |||
55 | mBase = 0; | ||
56 | |||
57 | if (!mBase) | ||
58 | { | ||
59 | // More than 4MB of AGP available | ||
60 | while (!mBase && (request > 0)) | ||
61 | { | ||
62 | // Stupid arbitrary nVidia magic numbers. | ||
63 | // read freq, write freq, priority | ||
64 | // AGP: 0.0, 0.1, 0.5 | ||
65 | // Video: 0.0, 0.1, 1.0 | ||
66 | mBase = (U8*)wglAllocateMemoryNV(request, 0.0f, 0.1f, 0.5f); | ||
67 | mSize = request; | ||
68 | request >>= 1; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | if (mBase) | ||
73 | { | ||
74 | mFreeList.append(*(new LLFreeBlock(0,mSize))); | ||
75 | } | ||
76 | else | ||
77 | { | ||
78 | mSize = 0; | ||
79 | } | ||
80 | |||
81 | sWriteOK = TRUE; | ||
82 | flush_glerror(); | ||
83 | } | ||
84 | |||
85 | |||
86 | LLAGPMemBlock *LLAGPMemPoolNV::createBlock(const U32 offset, const U32 size) | ||
87 | { | ||
88 | return new LLAGPMemBlockNV(this, mBase, offset, size); | ||
89 | } | ||
90 | |||
91 | LLAGPMemPoolNV::~LLAGPMemPoolNV() | ||
92 | { | ||
93 | if (mBase) | ||
94 | { | ||
95 | wglFreeMemoryNV(mBase); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | void LLAGPMemPoolNV::bind() | ||
100 | { | ||
101 | glVertexArrayRangeNV(mSize, mBase); | ||
102 | } | ||
103 | |||
104 | void LLAGPMemPoolNV::enable() | ||
105 | { | ||
106 | glEnableClientState(GL_VERTEX_ARRAY_RANGE_NV); | ||
107 | sWriteOK = FALSE; | ||
108 | } | ||
109 | |||
110 | void LLAGPMemPoolNV::disable() | ||
111 | { | ||
112 | glDisableClientState(GL_VERTEX_ARRAY_RANGE_NV); | ||
113 | sWriteOK = TRUE; | ||
114 | } | ||
115 | |||
116 | void LLAGPMemPoolNV::flush() | ||
117 | { | ||
118 | glFlushVertexArrayRangeNV(); | ||
119 | } | ||
120 | |||
121 | U32 LLAGPMemPoolNV::createFence() | ||
122 | { | ||
123 | U32 fence; | ||
124 | glGenFencesNV(1, &fence); | ||
125 | glSetFenceNV(fence, GL_ALL_COMPLETED_NV); | ||
126 | glFinishFenceNV(fence); | ||
127 | return fence; | ||
128 | } | ||
129 | |||
130 | void LLAGPMemPoolNV::deleteFence(const U32 fence) | ||
131 | { | ||
132 | glDeleteFencesNV(1, &fence); | ||
133 | } | ||
134 | |||
135 | void LLAGPMemPoolNV::sendFence(U32 fence) | ||
136 | { | ||
137 | glSetFenceNV(fence, GL_ALL_COMPLETED_NV); | ||
138 | } | ||
139 | |||
140 | void LLAGPMemPoolNV::waitFence(U32 fence) | ||
141 | { | ||
142 | if(!glTestFenceNV(fence)) | ||
143 | { | ||
144 | glFinishFenceNV(fence); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | |||
149 | //static | ||
150 | BOOL LLAGPMemPoolNV::isWriteOK() | ||
151 | { | ||
152 | return sWriteOK; | ||
153 | } | ||
154 | |||
155 | void LLAGPMemPoolNV::dump() | ||
156 | { | ||
157 | LLFreeBlock *prev = 0; | ||
158 | LLFreeBlock *block = mFreeList.getFirst(); | ||
159 | |||
160 | int d=0; | ||
161 | |||
162 | int i=0; | ||
163 | while (block) | ||
164 | { | ||
165 | i++; | ||
166 | if (prev) | ||
167 | { | ||
168 | d = (S32)block->mOffset - ((S32)prev->mOffset + prev->mSize); | ||
169 | } | ||
170 | else d = 0; | ||
171 | |||
172 | prev = block; | ||
173 | block = block->getNext(); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | |||
178 | LLAGPMemBlockNV::LLAGPMemBlockNV(LLAGPMemPool *mem_poolp, U8 *baseptr, S32 offset, const U32 size) : LLAGPMemBlock(mem_poolp) | ||
179 | { | ||
180 | mMemp = baseptr + offset; | ||
181 | mOffset = offset; | ||
182 | mSize = size; | ||
183 | } | ||
184 | |||
185 | extern U8* gAGPVertices; | ||
186 | |||
187 | void LLAGPMemBlockNV::bindGLVertexPointer(const U32 stride, const U32 offset) | ||
188 | { | ||
189 | if (!mMemp) | ||
190 | { | ||
191 | llerrs << "Binding empty vertex array" << llendl; | ||
192 | } | ||
193 | glVertexPointer(3, GL_FLOAT, stride, mMemp + offset); | ||
194 | } | ||
195 | |||
196 | void LLAGPMemBlockNV::bindGLNormalPointer(const U32 stride, const U32 offset) | ||
197 | { | ||
198 | if (!mMemp) | ||
199 | { | ||
200 | llerrs << "Binding empty normal array" << llendl; | ||
201 | } | ||
202 | glNormalPointer(GL_FLOAT, stride, mMemp + offset); | ||
203 | } | ||
204 | |||
205 | |||
206 | void LLAGPMemBlockNV::bindGLColorPointer(const U32 stride, const U32 offset) | ||
207 | { | ||
208 | if (!mMemp) | ||
209 | { | ||
210 | llerrs << "Binding empty color array" << llendl; | ||
211 | } | ||
212 | glColorPointer(4, GL_UNSIGNED_BYTE, stride, mMemp + offset); | ||
213 | } | ||
214 | |||
215 | |||
216 | void LLAGPMemBlockNV::bindGLTexCoordPointer(const U32 stride, const U32 offset) | ||
217 | { | ||
218 | if (!mMemp) | ||
219 | { | ||
220 | llerrs << "Binding empty texcoord array" << llendl; | ||
221 | } | ||
222 | glTexCoordPointer(2, GL_FLOAT, stride, mMemp + offset); | ||
223 | } | ||
224 | |||
225 | |||
226 | void LLAGPMemBlockNV::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) | ||
227 | { | ||
228 | if (!mMemp) | ||
229 | { | ||
230 | llerrs << "Binding empty vertex weight array" << llendl; | ||
231 | } | ||
232 | |||
233 | glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, (F32 *)(mMemp + offset)); | ||
234 | } | ||
235 | |||
236 | void LLAGPMemBlockNV::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) | ||
237 | { | ||
238 | if (!mMemp) | ||
239 | { | ||
240 | llerrs << "Binding empty vertex weight array" << llendl; | ||
241 | } | ||
242 | |||
243 | glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, 0, (F32 *)(mMemp + offset)); | ||
244 | } | ||
245 | |||
246 | void LLAGPMemBlockNV::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) | ||
247 | { | ||
248 | if (!mMemp) | ||
249 | { | ||
250 | llerrs << "Binding empty vertex weight array" << llendl; | ||
251 | } | ||
252 | set_vertex_clothing_weights(index, stride, (LLVector4 *)(mMemp + offset)); | ||
253 | } | ||
254 | |||
255 | U8* LLAGPMemBlockNV::getMappedMem() | ||
256 | { | ||
257 | return mMemp; | ||
258 | } | ||
259 | |||
260 | void LLAGPMemBlockNV::copy(void *mem, const U32 size) | ||
261 | { | ||
262 | if (!mMemp || !mem) | ||
263 | { | ||
264 | return; | ||
265 | } | ||
266 | llassert(LLAGPMemPoolNV::isWriteOK()); | ||
267 | llassert(size <= mSize); | ||
268 | |||
269 | #if LL_USE_NEW_MEM_OPS | ||
270 | inline_new_memcpy( mMemp, mem, size ); | ||
271 | #else | ||
272 | memcpy( mMemp, mem, size ); | ||
273 | #endif | ||
274 | } | ||
275 | |||
276 | void LLAGPMemBlockNV::copyColor(void *mem, const U32 size) | ||
277 | { | ||
278 | if (!mMemp || !mem) | ||
279 | { | ||
280 | return; | ||
281 | } | ||
282 | llassert(LLAGPMemPoolNV::isWriteOK()); | ||
283 | llassert(size <= mSize); | ||
284 | |||
285 | #if LL_USE_NEW_MEM_OPS | ||
286 | inline_new_memcpy( mMemp, mem, size ); | ||
287 | #else | ||
288 | memcpy( mMemp, mem, size ); | ||
289 | #endif | ||
290 | } | ||
291 | |||
292 | |||
293 | U32 LLAGPMemBlockNV::createFence() | ||
294 | { | ||
295 | U32 fence; | ||
296 | glGenFencesNV(1, &fence); | ||
297 | glSetFenceNV(fence, GL_ALL_COMPLETED_NV); | ||
298 | glFinishFenceNV(fence); | ||
299 | return fence; | ||
300 | } | ||
301 | |||
302 | void LLAGPMemBlockNV::deleteFence(const U32 fence) | ||
303 | { | ||
304 | glDeleteFencesNV(1, &fence); | ||
305 | } | ||
306 | |||
307 | void LLAGPMemBlockNV::sendFence(U32 fence) | ||
308 | { | ||
309 | glSetFenceNV(fence, GL_ALL_COMPLETED_NV); | ||
310 | } | ||
311 | |||
312 | void LLAGPMemBlockNV::waitFence(U32 fence) | ||
313 | { | ||
314 | if(!glTestFenceNV(fence)) | ||
315 | { | ||
316 | glFinishFenceNV(fence); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | #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 @@ | |||
1 | /** | ||
2 | * @file llagpmempoolnv.h | ||
3 | * @brief LLAGPMemPoolNV base class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_LLAGPMEMPOOLNV_H | ||
29 | #define LL_LLAGPMEMPOOLNV_H | ||
30 | |||
31 | #include "llagpmempool.h" | ||
32 | |||
33 | class LLAGPMemPoolNV : public LLAGPMemPool | ||
34 | { | ||
35 | public: | ||
36 | LLAGPMemPoolNV(int request); | ||
37 | virtual ~LLAGPMemPoolNV(); | ||
38 | |||
39 | /*virtual*/ void flush(); | ||
40 | /*virtual*/ void dump(); | ||
41 | /*virtual*/ void enable(); | ||
42 | /*virtual*/ void disable(); | ||
43 | /*virtual*/ void bind(); | ||
44 | |||
45 | static BOOL isWriteOK(); | ||
46 | |||
47 | /*virtual*/ U32 createFence(); | ||
48 | /*virtual*/ void deleteFence(const U32 fence); | ||
49 | /*virtual*/ void sendFence(U32 fence); | ||
50 | /*virtual*/ void waitFence(U32 fence); | ||
51 | protected: | ||
52 | /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size); | ||
53 | |||
54 | protected: | ||
55 | U8 *mBase; | ||
56 | |||
57 | static BOOL sWriteOK; | ||
58 | }; | ||
59 | |||
60 | class LLAGPMemBlockNV : public LLAGPMemBlock | ||
61 | { | ||
62 | public: | ||
63 | LLAGPMemBlockNV(LLAGPMemPool *mem_poolp, U8 *baseptr, const S32 offset, const U32 size); | ||
64 | virtual ~LLAGPMemBlockNV() { mMemPoolp->freeBlock(this); }; | ||
65 | |||
66 | /*virtual*/ void copy (void *source, const U32 size_bytes); | ||
67 | /*virtual*/ void copyColor(void *source, const U32 size_bytes); | ||
68 | /*virtual*/ void free(); | ||
69 | |||
70 | /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset); | ||
71 | /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset); | ||
72 | /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset); | ||
73 | /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset); | ||
74 | /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset); | ||
75 | /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset); | ||
76 | /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset); | ||
77 | |||
78 | /*virtual*/ U32 getOffset() const { return mOffset; } | ||
79 | /*virtual*/ U32 getSize() const { return mSize; } | ||
80 | |||
81 | /*virtual*/ BOOL hasMappedMem() const { return TRUE; } | ||
82 | /*virtual*/ U8* getMappedMem(); | ||
83 | /*virtual*/ U32 createFence(); | ||
84 | /*virtual*/ void deleteFence(const U32 fence); | ||
85 | /*virtual*/ void sendFence(U32 fence); | ||
86 | /*virtual*/ void waitFence(U32 fence); | ||
87 | |||
88 | private: | ||
89 | U8 *mMemp; | ||
90 | U32 mOffset; // Offset from base | ||
91 | U32 mSize; | ||
92 | friend class LLAGPMemPoolNV; | ||
93 | }; | ||
94 | |||
95 | #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 @@ | |||
31 | #include <map> | 31 | #include <map> |
32 | //#include "lllocalidhashmap.h" | 32 | //#include "lllocalidhashmap.h" |
33 | #include "llmemory.h" | 33 | #include "llmemory.h" |
34 | #include "llstl.h" | ||
34 | 35 | ||
35 | class LLImageRaw; | 36 | class LLImageRaw; |
36 | class LLFontManager; | 37 | 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 @@ | |||
33 | #include "llfontgl.h" | 33 | #include "llfontgl.h" |
34 | #include "llgl.h" | 34 | #include "llgl.h" |
35 | #include "v4color.h" | 35 | #include "v4color.h" |
36 | #include "llstl.h" | ||
36 | 37 | ||
37 | const S32 BOLD_OFFSET = 1; | 38 | const S32 BOLD_OFFSET = 1; |
38 | 39 | ||
@@ -155,7 +156,7 @@ LLString LLFontGL::getFontPathSystem() | |||
155 | // Try to figure out where the system's font files are stored. | 156 | // Try to figure out where the system's font files are stored. |
156 | char *system_root = NULL; | 157 | char *system_root = NULL; |
157 | #if LL_WINDOWS | 158 | #if LL_WINDOWS |
158 | system_root = getenv("SystemRoot"); | 159 | system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ |
159 | if (!system_root) | 160 | if (!system_root) |
160 | { | 161 | { |
161 | llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; | 162 | llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; |
@@ -647,7 +648,7 @@ S32 LLFontGL::render(const LLWString &wstr, | |||
647 | case LEFT: | 648 | case LEFT: |
648 | break; | 649 | break; |
649 | case RIGHT: | 650 | case RIGHT: |
650 | cur_x -= (F32)getWidth(wstr.c_str(), 0, length) * sScaleX; | 651 | cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX)); |
651 | break; | 652 | break; |
652 | case HCENTER: | 653 | case HCENTER: |
653 | cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX)) / 2; | 654 | 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, | |||
672 | 673 | ||
673 | 674 | ||
674 | BOOL draw_ellipses = FALSE; | 675 | BOOL draw_ellipses = FALSE; |
675 | if (use_ellipses) | 676 | if (use_ellipses && halign == LEFT) |
676 | { | 677 | { |
677 | // check for too long of a string | 678 | // check for too long of a string |
678 | if (getWidthF32(wstr.c_str(), 0, max_chars) > scaled_max_pixels) | 679 | if (getWidthF32(wstr.c_str(), 0, max_chars) > scaled_max_pixels) |
679 | { | 680 | { |
680 | const LLWString dots(utf8str_to_wstring(LLString("..."))); | 681 | // use four dots for ellipsis width to generate padding |
682 | const LLWString dots(utf8str_to_wstring(LLString("...."))); | ||
681 | scaled_max_pixels = llmax(0, scaled_max_pixels - llround(getWidthF32(dots.c_str()))); | 683 | scaled_max_pixels = llmax(0, scaled_max_pixels - llround(getWidthF32(dots.c_str()))); |
682 | draw_ellipses = TRUE; | 684 | draw_ellipses = TRUE; |
683 | } | 685 | } |
@@ -1330,7 +1332,7 @@ LLString LLFontGL::nameFromFont(const LLFontGL* fontp) | |||
1330 | { | 1332 | { |
1331 | if (fontp == sSansSerifHuge) | 1333 | if (fontp == sSansSerifHuge) |
1332 | { | 1334 | { |
1333 | return LLString("SansSerifHude"); | 1335 | return LLString("SansSerifHuge"); |
1334 | } | 1336 | } |
1335 | else if (fontp == sSansSerifSmall) | 1337 | else if (fontp == sSansSerifSmall) |
1336 | { | 1338 | { |
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) | |||
89 | //------------------------------------------------------------------------ | 89 | //------------------------------------------------------------------------ |
90 | char *fv3(F32 *f) | 90 | char *fv3(F32 *f) |
91 | { | 91 | { |
92 | static char str[128]; | 92 | static char str[128]; /* Flawfinder: ignore */ |
93 | sprintf(str, "%8.3f, %8.3f, %8.3f", f[0], f[1], f[2]); | 93 | snprintf(str, sizeof(str), "%8.3f, %8.3f, %8.3f", f[0], f[1], f[2]); /* Flawfinder: ignore */ |
94 | return str; | 94 | return str; |
95 | } | 95 | } |
96 | 96 | ||
@@ -99,8 +99,8 @@ char *fv3(F32 *f) | |||
99 | //------------------------------------------------------------------------ | 99 | //------------------------------------------------------------------------ |
100 | char *fv1(F32 *f) | 100 | char *fv1(F32 *f) |
101 | { | 101 | { |
102 | static char str[128]; | 102 | static char str[128]; /* Flawfinder: ignore */ |
103 | sprintf(str, "%8.3f", f[0]); | 103 | snprintf(str, sizeof(str), "%8.3f", f[0]); /* Flawfinder: ignore */ |
104 | return str; | 104 | return str; |
105 | } | 105 | } |
106 | 106 | ||
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) | |||
134 | sCurrentBoundTextures[stage] = 0; | 134 | sCurrentBoundTextures[stage] = 0; |
135 | } | 135 | } |
136 | 136 | ||
137 | // static (duplicated for speed and to avoid GL_TEXTURE_2D default argument which requires GL header dependency) | ||
138 | void LLImageGL::unbindTexture(S32 stage) | ||
139 | { | ||
140 | glActiveTextureARB(GL_TEXTURE0_ARB + stage); | ||
141 | glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); | ||
142 | glBindTexture(GL_TEXTURE_2D, 0); | ||
143 | sCurrentBoundTextures[stage] = 0; | ||
144 | } | ||
145 | |||
137 | // static | 146 | // static |
138 | void LLImageGL::updateStats(F32 current_time) | 147 | void LLImageGL::updateStats(F32 current_time) |
139 | { | 148 | { |
@@ -390,13 +399,8 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const | |||
390 | llwarns << "Trying to bind a texture while GL is disabled!" << llendl; | 399 | llwarns << "Trying to bind a texture while GL is disabled!" << llendl; |
391 | } | 400 | } |
392 | 401 | ||
393 | stop_glerror(); | ||
394 | |||
395 | glActiveTextureARB(GL_TEXTURE0_ARB + stage); | 402 | glActiveTextureARB(GL_TEXTURE0_ARB + stage); |
396 | //glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); | 403 | |
397 | |||
398 | stop_glerror(); | ||
399 | |||
400 | if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName) | 404 | if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName) |
401 | { | 405 | { |
402 | // already set! | 406 | // already set! |
@@ -411,7 +415,6 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const | |||
411 | 415 | ||
412 | glBindTexture(mBindTarget, mTexName); | 416 | glBindTexture(mBindTarget, mTexName); |
413 | sCurrentBoundTextures[stage] = mTexName; | 417 | sCurrentBoundTextures[stage] = mTexName; |
414 | stop_glerror(); | ||
415 | 418 | ||
416 | if (mLastBindTime != sLastFrameTime) | 419 | if (mLastBindTime != sLastFrameTime) |
417 | { | 420 | { |
@@ -650,6 +653,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
650 | } | 653 | } |
651 | mHasMipMaps = FALSE; | 654 | mHasMipMaps = FALSE; |
652 | } | 655 | } |
656 | glFlush(); | ||
653 | stop_glerror(); | 657 | stop_glerror(); |
654 | } | 658 | } |
655 | 659 | ||
@@ -664,6 +668,11 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 | |||
664 | llwarns << "Setting subimage on image without GL texture" << llendl; | 668 | llwarns << "Setting subimage on image without GL texture" << llendl; |
665 | return FALSE; | 669 | return FALSE; |
666 | } | 670 | } |
671 | if (datap == NULL) | ||
672 | { | ||
673 | llwarns << "Setting subimage on image with NULL datap" << llendl; | ||
674 | return FALSE; | ||
675 | } | ||
667 | 676 | ||
668 | if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight()) | 677 | if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight()) |
669 | { | 678 | { |
@@ -676,7 +685,9 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 | |||
676 | dump(); | 685 | dump(); |
677 | llerrs << "setSubImage called with mipmapped image (not supported)" << llendl; | 686 | llerrs << "setSubImage called with mipmapped image (not supported)" << llendl; |
678 | } | 687 | } |
679 | llassert(mCurrentDiscardLevel == 0); | 688 | llassert_always(mCurrentDiscardLevel == 0); |
689 | llassert_always(x_pos >= 0 && y_pos >= 0); | ||
690 | |||
680 | if (((x_pos + width) > getWidth()) || | 691 | if (((x_pos + width) > getWidth()) || |
681 | (y_pos + height) > getHeight()) | 692 | (y_pos + height) > getHeight()) |
682 | { | 693 | { |
@@ -717,9 +728,12 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 | |||
717 | 728 | ||
718 | datap += (y_pos * data_width + x_pos) * getComponents(); | 729 | datap += (y_pos * data_width + x_pos) * getComponents(); |
719 | // Update the GL texture | 730 | // Update the GL texture |
720 | llverify(bindTextureInternal(0)); | 731 | BOOL res = bindTextureInternal(0); |
732 | if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl; | ||
721 | stop_glerror(); | 733 | stop_glerror(); |
722 | 734 | ||
735 | LLGLEnable tex( GL_TEXTURE_2D ); | ||
736 | |||
723 | glTexSubImage2D(mTarget, 0, x_pos, y_pos, | 737 | glTexSubImage2D(mTarget, 0, x_pos, y_pos, |
724 | width, height, mFormatPrimary, mFormatType, datap); | 738 | width, height, mFormatPrimary, mFormatType, datap); |
725 | stop_glerror(); | 739 | stop_glerror(); |
@@ -733,7 +747,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 | |||
733 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | 747 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
734 | stop_glerror(); | 748 | stop_glerror(); |
735 | } | 749 | } |
736 | 750 | glFlush(); | |
737 | return TRUE; | 751 | return TRUE; |
738 | } | 752 | } |
739 | 753 | ||
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 @@ | |||
36 | 36 | ||
37 | //============================================================================ | 37 | //============================================================================ |
38 | 38 | ||
39 | class LLImageGL : public LLThreadSafeRefCount | 39 | class LLImageGL : public LLRefCount |
40 | { | 40 | { |
41 | public: | 41 | public: |
42 | // Size calculation | 42 | // Size calculation |
@@ -48,6 +48,7 @@ public: | |||
48 | // Usually you want stage = 0 and bind_target = GL_TEXTURE_2D | 48 | // Usually you want stage = 0 and bind_target = GL_TEXTURE_2D |
49 | static void bindExternalTexture( LLGLuint gl_name, S32 stage, LLGLenum bind_target); | 49 | static void bindExternalTexture( LLGLuint gl_name, S32 stage, LLGLenum bind_target); |
50 | static void unbindTexture(S32 stage, LLGLenum target); | 50 | static void unbindTexture(S32 stage, LLGLenum target); |
51 | static void unbindTexture(S32 stage); // Uses GL_TEXTURE_2D (not a default arg to avoid gl.h dependency) | ||
51 | 52 | ||
52 | // needs to be called every frame | 53 | // needs to be called every frame |
53 | static void updateStats(F32 current_time); | 54 | 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 @@ | |||
154 | Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" | 154 | Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" |
155 | UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> | 155 | UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> |
156 | <File | 156 | <File |
157 | RelativePath=".\llagpmempool.cpp"> | ||
158 | </File> | ||
159 | <File | ||
160 | RelativePath=".\llagpmempoolarb.cpp"> | ||
161 | </File> | ||
162 | <File | ||
163 | RelativePath=".\llagpmempoolati.cpp"> | ||
164 | </File> | ||
165 | <File | ||
166 | RelativePath=".\llagpmempoolnv.cpp"> | ||
167 | </File> | ||
168 | <File | ||
169 | RelativePath=".\llfont.cpp"> | 157 | RelativePath=".\llfont.cpp"> |
170 | </File> | 158 | </File> |
171 | <File | 159 | <File |
@@ -178,6 +166,9 @@ | |||
178 | RelativePath=".\llimagegl.cpp"> | 166 | RelativePath=".\llimagegl.cpp"> |
179 | </File> | 167 | </File> |
180 | <File | 168 | <File |
169 | RelativePath=".\llvertexbuffer.cpp"> | ||
170 | </File> | ||
171 | <File | ||
181 | RelativePath=".\text_out.cpp"> | 172 | RelativePath=".\text_out.cpp"> |
182 | </File> | 173 | </File> |
183 | </Filter> | 174 | </Filter> |
@@ -213,6 +204,9 @@ | |||
213 | RelativePath=".\llimagegl.h"> | 204 | RelativePath=".\llimagegl.h"> |
214 | </File> | 205 | </File> |
215 | <File | 206 | <File |
207 | RelativePath=".\llvertexbuffer.h"> | ||
208 | </File> | ||
209 | <File | ||
216 | RelativePath=".\llvertexprogramgl.h"> | 210 | RelativePath=".\llvertexprogramgl.h"> |
217 | </File> | 211 | </File> |
218 | <File | 212 | <File |
diff --git a/linden/indra/llrender/llrender_vc8.vcproj b/linden/indra/llrender/llrender_vc8.vcproj new file mode 100644 index 0000000..daa2cfc --- /dev/null +++ b/linden/indra/llrender/llrender_vc8.vcproj | |||
@@ -0,0 +1,302 @@ | |||
1 | <?xml version="1.0" encoding="Windows-1252"?> | ||
2 | <VisualStudioProject | ||
3 | ProjectType="Visual C++" | ||
4 | Version="8.00" | ||
5 | Name="llrender" | ||
6 | ProjectGUID="{2ADE3C14-94C4-40BF-B033-70F3C954EE90}" | ||
7 | Keyword="Win32Proj" | ||
8 | > | ||
9 | <Platforms> | ||
10 | <Platform | ||
11 | Name="Win32" | ||
12 | /> | ||
13 | </Platforms> | ||
14 | <ToolFiles> | ||
15 | </ToolFiles> | ||
16 | <Configurations> | ||
17 | <Configuration | ||
18 | Name="Debug|Win32" | ||
19 | OutputDirectory="../lib_$(ConfigurationName)/i686-win32" | ||
20 | IntermediateDirectory="Debug" | ||
21 | ConfigurationType="4" | ||
22 | InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" | ||
23 | CharacterSet="1" | ||
24 | > | ||
25 | <Tool | ||
26 | Name="VCPreBuildEventTool" | ||
27 | /> | ||
28 | <Tool | ||
29 | Name="VCCustomBuildTool" | ||
30 | /> | ||
31 | <Tool | ||
32 | Name="VCXMLDataGeneratorTool" | ||
33 | /> | ||
34 | <Tool | ||
35 | Name="VCWebServiceProxyGeneratorTool" | ||
36 | /> | ||
37 | <Tool | ||
38 | Name="VCMIDLTool" | ||
39 | /> | ||
40 | <Tool | ||
41 | Name="VCCLCompilerTool" | ||
42 | Optimization="0" | ||
43 | AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\llimage;..\llwindow;..\..\libraries\i686-win32\include;..\..\libraries\include\" | ||
44 | PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_DEBUG" | ||
45 | MinimalRebuild="true" | ||
46 | BasicRuntimeChecks="3" | ||
47 | RuntimeLibrary="1" | ||
48 | StructMemberAlignment="4" | ||
49 | TreatWChar_tAsBuiltInType="false" | ||
50 | ForceConformanceInForLoopScope="true" | ||
51 | UsePrecompiledHeader="0" | ||
52 | WarningLevel="3" | ||
53 | WarnAsError="true" | ||
54 | Detect64BitPortabilityProblems="false" | ||
55 | DebugInformationFormat="4" | ||
56 | /> | ||
57 | <Tool | ||
58 | Name="VCManagedResourceCompilerTool" | ||
59 | /> | ||
60 | <Tool | ||
61 | Name="VCResourceCompilerTool" | ||
62 | /> | ||
63 | <Tool | ||
64 | Name="VCPreLinkEventTool" | ||
65 | /> | ||
66 | <Tool | ||
67 | Name="VCLibrarianTool" | ||
68 | OutputFile="$(OutDir)/llrender.lib" | ||
69 | /> | ||
70 | <Tool | ||
71 | Name="VCALinkTool" | ||
72 | /> | ||
73 | <Tool | ||
74 | Name="VCXDCMakeTool" | ||
75 | /> | ||
76 | <Tool | ||
77 | Name="VCBscMakeTool" | ||
78 | /> | ||
79 | <Tool | ||
80 | Name="VCFxCopTool" | ||
81 | /> | ||
82 | <Tool | ||
83 | Name="VCPostBuildEventTool" | ||
84 | /> | ||
85 | </Configuration> | ||
86 | <Configuration | ||
87 | Name="Release|Win32" | ||
88 | OutputDirectory="../lib_$(ConfigurationName)/i686-win32" | ||
89 | IntermediateDirectory="Release" | ||
90 | ConfigurationType="4" | ||
91 | InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" | ||
92 | CharacterSet="1" | ||
93 | > | ||
94 | <Tool | ||
95 | Name="VCPreBuildEventTool" | ||
96 | /> | ||
97 | <Tool | ||
98 | Name="VCCustomBuildTool" | ||
99 | /> | ||
100 | <Tool | ||
101 | Name="VCXMLDataGeneratorTool" | ||
102 | /> | ||
103 | <Tool | ||
104 | Name="VCWebServiceProxyGeneratorTool" | ||
105 | /> | ||
106 | <Tool | ||
107 | Name="VCMIDLTool" | ||
108 | /> | ||
109 | <Tool | ||
110 | Name="VCCLCompilerTool" | ||
111 | InlineFunctionExpansion="2" | ||
112 | EnableIntrinsicFunctions="true" | ||
113 | AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\llimage;..\llwindow;..\..\libraries\i686-win32\include;..\..\libraries\include\" | ||
114 | PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE" | ||
115 | RuntimeLibrary="0" | ||
116 | StructMemberAlignment="0" | ||
117 | TreatWChar_tAsBuiltInType="false" | ||
118 | ForceConformanceInForLoopScope="true" | ||
119 | UsePrecompiledHeader="0" | ||
120 | WarningLevel="3" | ||
121 | WarnAsError="true" | ||
122 | Detect64BitPortabilityProblems="false" | ||
123 | DebugInformationFormat="3" | ||
124 | /> | ||
125 | <Tool | ||
126 | Name="VCManagedResourceCompilerTool" | ||
127 | /> | ||
128 | <Tool | ||
129 | Name="VCResourceCompilerTool" | ||
130 | /> | ||
131 | <Tool | ||
132 | Name="VCPreLinkEventTool" | ||
133 | /> | ||
134 | <Tool | ||
135 | Name="VCLibrarianTool" | ||
136 | OutputFile="$(OutDir)/llrender.lib" | ||
137 | /> | ||
138 | <Tool | ||
139 | Name="VCALinkTool" | ||
140 | /> | ||
141 | <Tool | ||
142 | Name="VCXDCMakeTool" | ||
143 | /> | ||
144 | <Tool | ||
145 | Name="VCBscMakeTool" | ||
146 | /> | ||
147 | <Tool | ||
148 | Name="VCFxCopTool" | ||
149 | /> | ||
150 | <Tool | ||
151 | Name="VCPostBuildEventTool" | ||
152 | /> | ||
153 | </Configuration> | ||
154 | <Configuration | ||
155 | Name="ReleaseNoOpt|Win32" | ||
156 | OutputDirectory="../lib_$(ConfigurationName)/i686-win32" | ||
157 | IntermediateDirectory="$(ConfigurationName)" | ||
158 | ConfigurationType="4" | ||
159 | InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" | ||
160 | CharacterSet="1" | ||
161 | > | ||
162 | <Tool | ||
163 | Name="VCPreBuildEventTool" | ||
164 | /> | ||
165 | <Tool | ||
166 | Name="VCCustomBuildTool" | ||
167 | /> | ||
168 | <Tool | ||
169 | Name="VCXMLDataGeneratorTool" | ||
170 | /> | ||
171 | <Tool | ||
172 | Name="VCWebServiceProxyGeneratorTool" | ||
173 | /> | ||
174 | <Tool | ||
175 | Name="VCMIDLTool" | ||
176 | /> | ||
177 | <Tool | ||
178 | Name="VCCLCompilerTool" | ||
179 | Optimization="0" | ||
180 | AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\llimage;..\llwindow;..\..\libraries\i686-win32\include;..\..\libraries\include\" | ||
181 | PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE" | ||
182 | RuntimeLibrary="0" | ||
183 | StructMemberAlignment="0" | ||
184 | TreatWChar_tAsBuiltInType="false" | ||
185 | ForceConformanceInForLoopScope="true" | ||
186 | UsePrecompiledHeader="0" | ||
187 | WarningLevel="3" | ||
188 | WarnAsError="true" | ||
189 | Detect64BitPortabilityProblems="false" | ||
190 | DebugInformationFormat="3" | ||
191 | /> | ||
192 | <Tool | ||
193 | Name="VCManagedResourceCompilerTool" | ||
194 | /> | ||
195 | <Tool | ||
196 | Name="VCResourceCompilerTool" | ||
197 | /> | ||
198 | <Tool | ||
199 | Name="VCPreLinkEventTool" | ||
200 | /> | ||
201 | <Tool | ||
202 | Name="VCLibrarianTool" | ||
203 | OutputFile="$(OutDir)/llrender.lib" | ||
204 | /> | ||
205 | <Tool | ||
206 | Name="VCALinkTool" | ||
207 | /> | ||
208 | <Tool | ||
209 | Name="VCXDCMakeTool" | ||
210 | /> | ||
211 | <Tool | ||
212 | Name="VCBscMakeTool" | ||
213 | /> | ||
214 | <Tool | ||
215 | Name="VCFxCopTool" | ||
216 | /> | ||
217 | <Tool | ||
218 | Name="VCPostBuildEventTool" | ||
219 | /> | ||
220 | </Configuration> | ||
221 | </Configurations> | ||
222 | <References> | ||
223 | </References> | ||
224 | <Files> | ||
225 | <Filter | ||
226 | Name="Source Files" | ||
227 | Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" | ||
228 | UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" | ||
229 | > | ||
230 | <File | ||
231 | RelativePath=".\llfont.cpp" | ||
232 | > | ||
233 | </File> | ||
234 | <File | ||
235 | RelativePath=".\llfontgl.cpp" | ||
236 | > | ||
237 | </File> | ||
238 | <File | ||
239 | RelativePath=".\llgldbg.cpp" | ||
240 | > | ||
241 | </File> | ||
242 | <File | ||
243 | RelativePath=".\llimagegl.cpp" | ||
244 | > | ||
245 | </File> | ||
246 | <File | ||
247 | RelativePath=".\llvertexbuffer.cpp" | ||
248 | > | ||
249 | </File> | ||
250 | <File | ||
251 | RelativePath=".\text_out.cpp" | ||
252 | > | ||
253 | </File> | ||
254 | </Filter> | ||
255 | <Filter | ||
256 | Name="Header Files" | ||
257 | Filter="h;hpp;hxx;hm;inl;inc;xsd" | ||
258 | UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" | ||
259 | > | ||
260 | <File | ||
261 | RelativePath=".\glext.h" | ||
262 | > | ||
263 | </File> | ||
264 | <File | ||
265 | RelativePath=".\llfont.h" | ||
266 | > | ||
267 | </File> | ||
268 | <File | ||
269 | RelativePath=".\llfontgl.h" | ||
270 | > | ||
271 | </File> | ||
272 | <File | ||
273 | RelativePath=".\llgldbg.h" | ||
274 | > | ||
275 | </File> | ||
276 | <File | ||
277 | RelativePath=".\llimagegl.h" | ||
278 | > | ||
279 | </File> | ||
280 | <File | ||
281 | RelativePath=".\llvertexbuffer.h" | ||
282 | > | ||
283 | </File> | ||
284 | <File | ||
285 | RelativePath=".\llvertexprogramgl.h" | ||
286 | > | ||
287 | </File> | ||
288 | <File | ||
289 | RelativePath=".\text_out.h" | ||
290 | > | ||
291 | </File> | ||
292 | </Filter> | ||
293 | <Filter | ||
294 | Name="Resource Files" | ||
295 | Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" | ||
296 | UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" | ||
297 | > | ||
298 | </Filter> | ||
299 | </Files> | ||
300 | <Globals> | ||
301 | </Globals> | ||
302 | </VisualStudioProject> | ||
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 @@ | |||
1 | #include "linden_common.h" | ||
2 | |||
3 | #include "llvertexbuffer.h" | ||
4 | // #include "llrender.h" | ||
5 | #include "llglheaders.h" | ||
6 | #include "llmemory.h" | ||
7 | #include "llmemtype.h" | ||
8 | |||
9 | //============================================================================ | ||
10 | |||
11 | //static | ||
12 | S32 LLVertexBuffer::sCount = 0; | ||
13 | S32 LLVertexBuffer::sGLCount = 0; | ||
14 | BOOL LLVertexBuffer::sEnableVBOs = TRUE; | ||
15 | U32 LLVertexBuffer::sGLRenderBuffer = 0; | ||
16 | U32 LLVertexBuffer::sGLRenderIndices = 0; | ||
17 | U32 LLVertexBuffer::sLastMask = 0; | ||
18 | BOOL LLVertexBuffer::sVBOActive = FALSE; | ||
19 | BOOL LLVertexBuffer::sIBOActive = FALSE; | ||
20 | U32 LLVertexBuffer::sAllocatedBytes = 0; | ||
21 | BOOL LLVertexBuffer::sRenderActive = FALSE; | ||
22 | |||
23 | std::vector<U32> LLVertexBuffer::sDeleteList; | ||
24 | LLVertexBuffer::buffer_list_t LLVertexBuffer::sLockedList; | ||
25 | |||
26 | S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = | ||
27 | { | ||
28 | sizeof(LLVector3), // TYPE_VERTEX, | ||
29 | sizeof(LLVector3), // TYPE_NORMAL, | ||
30 | sizeof(LLVector2), // TYPE_TEXCOORD, | ||
31 | sizeof(LLVector2), // TYPE_TEXCOORD2, | ||
32 | sizeof(LLColor4U), // TYPE_COLOR, | ||
33 | sizeof(LLVector3), // TYPE_BINORMAL, | ||
34 | sizeof(F32), // TYPE_WEIGHT, | ||
35 | sizeof(LLVector4), // TYPE_CLOTHWEIGHT, | ||
36 | }; | ||
37 | |||
38 | //static | ||
39 | void LLVertexBuffer::initClass(bool use_vbo) | ||
40 | { | ||
41 | sEnableVBOs = use_vbo; | ||
42 | } | ||
43 | |||
44 | //static | ||
45 | void LLVertexBuffer::unbind() | ||
46 | { | ||
47 | if (sVBOActive) | ||
48 | { | ||
49 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); | ||
50 | sVBOActive = FALSE; | ||
51 | } | ||
52 | if (sIBOActive) | ||
53 | { | ||
54 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); | ||
55 | sIBOActive = FALSE; | ||
56 | } | ||
57 | |||
58 | sGLRenderBuffer = 0; | ||
59 | sGLRenderIndices = 0; | ||
60 | } | ||
61 | |||
62 | //static | ||
63 | void LLVertexBuffer::cleanupClass() | ||
64 | { | ||
65 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
66 | sLockedList.clear(); | ||
67 | startRender(); | ||
68 | stopRender(); | ||
69 | clientCopy(); // deletes GL buffers | ||
70 | } | ||
71 | |||
72 | //static, call before rendering VBOs | ||
73 | void LLVertexBuffer::startRender() | ||
74 | { | ||
75 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
76 | if (sEnableVBOs) | ||
77 | { | ||
78 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); | ||
79 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); | ||
80 | sVBOActive = FALSE; | ||
81 | sIBOActive = FALSE; | ||
82 | } | ||
83 | |||
84 | sRenderActive = TRUE; | ||
85 | sGLRenderBuffer = 0; | ||
86 | sGLRenderIndices = 0; | ||
87 | sLastMask = 0; | ||
88 | } | ||
89 | |||
90 | void LLVertexBuffer::stopRender() | ||
91 | { | ||
92 | sRenderActive = FALSE; | ||
93 | } | ||
94 | |||
95 | void LLVertexBuffer::clientCopy(F64 max_time) | ||
96 | { | ||
97 | if (!sDeleteList.empty()) | ||
98 | { | ||
99 | size_t num = sDeleteList.size(); | ||
100 | glDeleteBuffersARB(sDeleteList.size(), (GLuint*) &(sDeleteList[0])); | ||
101 | sDeleteList.clear(); | ||
102 | sGLCount -= num; | ||
103 | } | ||
104 | |||
105 | if (sEnableVBOs) | ||
106 | { | ||
107 | LLTimer timer; | ||
108 | BOOL reset = TRUE; | ||
109 | buffer_list_t::iterator iter = sLockedList.begin(); | ||
110 | while(iter != sLockedList.end()) | ||
111 | { | ||
112 | LLVertexBuffer* buffer = *iter; | ||
113 | if (buffer->isLocked() && buffer->useVBOs()) | ||
114 | { | ||
115 | buffer->setBuffer(0); | ||
116 | } | ||
117 | ++iter; | ||
118 | if (reset) | ||
119 | { | ||
120 | reset = FALSE; | ||
121 | timer.reset(); //skip first copy (don't count pipeline stall) | ||
122 | } | ||
123 | else | ||
124 | { | ||
125 | if (timer.getElapsedTimeF64() > max_time) | ||
126 | { | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | } | ||
132 | |||
133 | sLockedList.erase(sLockedList.begin(), iter); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | //---------------------------------------------------------------------------- | ||
138 | |||
139 | // For debugging | ||
140 | struct VTNC /// Simple | ||
141 | { | ||
142 | F32 v1,v2,v3; | ||
143 | F32 n1,n2,n3; | ||
144 | F32 t1,t2; | ||
145 | U32 c; | ||
146 | }; | ||
147 | static VTNC dbg_vtnc; | ||
148 | |||
149 | struct VTUNCB // Simple + Bump | ||
150 | { | ||
151 | F32 v1,v2,v3; | ||
152 | F32 n1,n2,n3; | ||
153 | F32 t1,t2; | ||
154 | F32 u1,u2; | ||
155 | F32 b1,b2,b3; | ||
156 | U32 c; | ||
157 | }; | ||
158 | static VTUNCB dbg_vtuncb; | ||
159 | |||
160 | struct VTUNC // Surfacepatch | ||
161 | { | ||
162 | F32 v1,v2,v3; | ||
163 | F32 n1,n2,n3; | ||
164 | F32 t1,t2; | ||
165 | F32 u1,u2; | ||
166 | U32 c; | ||
167 | }; | ||
168 | static VTUNC dbg_vtunc; | ||
169 | |||
170 | struct VTNW /// Avatar | ||
171 | { | ||
172 | F32 v1,v2,v3; | ||
173 | F32 n1,n2,n3; | ||
174 | F32 t1,t2; | ||
175 | F32 w; | ||
176 | }; | ||
177 | static VTNW dbg_vtnw; | ||
178 | |||
179 | struct VTNPAD /// Avatar Output | ||
180 | { | ||
181 | F32 v1,v2,v3,p1; | ||
182 | F32 n1,n2,n3,p2; | ||
183 | F32 t1,t2,p3,p4; | ||
184 | }; | ||
185 | static VTNPAD dbg_vtnpad; | ||
186 | |||
187 | //---------------------------------------------------------------------------- | ||
188 | |||
189 | LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : | ||
190 | LLRefCount(), | ||
191 | mNumVerts(0), mNumIndices(0), mUsage(usage), mGLBuffer(0), mGLIndices(0), | ||
192 | mMappedData(NULL), | ||
193 | mMappedIndexData(NULL), mLocked(FALSE), | ||
194 | mFinal(FALSE), | ||
195 | mFilthy(FALSE), | ||
196 | mEmpty(TRUE), | ||
197 | mResized(FALSE) | ||
198 | { | ||
199 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
200 | if (!sEnableVBOs) | ||
201 | { | ||
202 | mUsage = GL_STREAM_DRAW_ARB; | ||
203 | } | ||
204 | |||
205 | S32 stride = 0; | ||
206 | for (S32 i=0; i<TYPE_MAX; i++) | ||
207 | { | ||
208 | U32 mask = 1<<i; | ||
209 | if (typemask & mask) | ||
210 | { | ||
211 | mOffsets[i] = stride; | ||
212 | stride += sTypeOffsets[i]; | ||
213 | } | ||
214 | } | ||
215 | mTypeMask = typemask; | ||
216 | mStride = stride; | ||
217 | sCount++; | ||
218 | } | ||
219 | |||
220 | // protected, use unref() | ||
221 | //virtual | ||
222 | LLVertexBuffer::~LLVertexBuffer() | ||
223 | { | ||
224 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
225 | destroyGLBuffer(); | ||
226 | destroyGLIndices(); | ||
227 | sCount--; | ||
228 | |||
229 | if (mLocked) | ||
230 | { | ||
231 | //pull off of locked list | ||
232 | for (buffer_list_t::iterator i = sLockedList.begin(); i != sLockedList.end(); ++i) | ||
233 | { | ||
234 | if (*i == this) | ||
235 | { | ||
236 | sLockedList.erase(i); | ||
237 | break; | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | }; | ||
242 | |||
243 | //---------------------------------------------------------------------------- | ||
244 | |||
245 | void LLVertexBuffer::createGLBuffer() | ||
246 | { | ||
247 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
248 | |||
249 | U32 size = getSize(); | ||
250 | if (mGLBuffer) | ||
251 | { | ||
252 | destroyGLBuffer(); | ||
253 | } | ||
254 | |||
255 | if (size == 0) | ||
256 | { | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | mMappedData = new U8[size]; | ||
261 | memset(mMappedData, 0, size); | ||
262 | mEmpty = TRUE; | ||
263 | |||
264 | if (useVBOs()) | ||
265 | { | ||
266 | glGenBuffersARB(1, (GLuint*) &mGLBuffer); | ||
267 | mResized = TRUE; | ||
268 | sGLCount++; | ||
269 | } | ||
270 | else | ||
271 | { | ||
272 | static int gl_buffer_idx = 0; | ||
273 | mGLBuffer = ++gl_buffer_idx; | ||
274 | } | ||
275 | } | ||
276 | |||
277 | void LLVertexBuffer::createGLIndices() | ||
278 | { | ||
279 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
280 | U32 size = getIndicesSize(); | ||
281 | |||
282 | if (mGLIndices) | ||
283 | { | ||
284 | destroyGLIndices(); | ||
285 | } | ||
286 | |||
287 | if (size == 0) | ||
288 | { | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | mMappedIndexData = new U8[size]; | ||
293 | memset(mMappedIndexData, 0, size); | ||
294 | mEmpty = TRUE; | ||
295 | |||
296 | if (useVBOs()) | ||
297 | { | ||
298 | glGenBuffersARB(1, (GLuint*) &mGLIndices); | ||
299 | mResized = TRUE; | ||
300 | sGLCount++; | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | static int gl_buffer_idx = 0; | ||
305 | mGLIndices = ++gl_buffer_idx; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | void LLVertexBuffer::destroyGLBuffer() | ||
310 | { | ||
311 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
312 | if (mGLBuffer) | ||
313 | { | ||
314 | if (useVBOs()) | ||
315 | { | ||
316 | sDeleteList.push_back(mGLBuffer); | ||
317 | } | ||
318 | |||
319 | delete [] mMappedData; | ||
320 | mMappedData = NULL; | ||
321 | mEmpty = TRUE; | ||
322 | sAllocatedBytes -= getSize(); | ||
323 | } | ||
324 | |||
325 | mGLBuffer = 0; | ||
326 | } | ||
327 | |||
328 | void LLVertexBuffer::destroyGLIndices() | ||
329 | { | ||
330 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
331 | if (mGLIndices) | ||
332 | { | ||
333 | if (useVBOs()) | ||
334 | { | ||
335 | sDeleteList.push_back(mGLIndices); | ||
336 | } | ||
337 | |||
338 | delete [] mMappedIndexData; | ||
339 | mMappedIndexData = NULL; | ||
340 | mEmpty = TRUE; | ||
341 | sAllocatedBytes -= getIndicesSize(); | ||
342 | } | ||
343 | |||
344 | mGLIndices = 0; | ||
345 | } | ||
346 | |||
347 | void LLVertexBuffer::updateNumVerts(S32 nverts) | ||
348 | { | ||
349 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
350 | if (!mDynamicSize) | ||
351 | { | ||
352 | mNumVerts = nverts; | ||
353 | } | ||
354 | else if (mUsage == GL_STATIC_DRAW_ARB || | ||
355 | nverts > mNumVerts || | ||
356 | nverts < mNumVerts/2) | ||
357 | { | ||
358 | if (mUsage != GL_STATIC_DRAW_ARB) | ||
359 | { | ||
360 | nverts += nverts/4; | ||
361 | } | ||
362 | |||
363 | mNumVerts = nverts; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | void LLVertexBuffer::updateNumIndices(S32 nindices) | ||
368 | { | ||
369 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
370 | if (!mDynamicSize) | ||
371 | { | ||
372 | mNumIndices = nindices; | ||
373 | } | ||
374 | else if (mUsage == GL_STATIC_DRAW_ARB || | ||
375 | nindices > mNumIndices || | ||
376 | nindices < mNumIndices/2) | ||
377 | { | ||
378 | if (mUsage != GL_STATIC_DRAW_ARB) | ||
379 | { | ||
380 | nindices += nindices/4; | ||
381 | } | ||
382 | |||
383 | mNumIndices = nindices; | ||
384 | } | ||
385 | } | ||
386 | |||
387 | void LLVertexBuffer::makeStatic() | ||
388 | { | ||
389 | if (!sEnableVBOs) | ||
390 | { | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | if (sRenderActive) | ||
395 | { | ||
396 | llerrs << "Make static called during render." << llendl; | ||
397 | } | ||
398 | |||
399 | if (mUsage != GL_STATIC_DRAW_ARB) | ||
400 | { | ||
401 | if (useVBOs()) | ||
402 | { | ||
403 | if (mGLBuffer) | ||
404 | { | ||
405 | sDeleteList.push_back(mGLBuffer); | ||
406 | } | ||
407 | if (mGLIndices) | ||
408 | { | ||
409 | sDeleteList.push_back(mGLIndices); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | if (mGLBuffer) | ||
414 | { | ||
415 | sGLCount++; | ||
416 | glGenBuffersARB(1, (GLuint*) &mGLBuffer); | ||
417 | } | ||
418 | if (mGLIndices) | ||
419 | { | ||
420 | sGLCount++; | ||
421 | glGenBuffersARB(1, (GLuint*) &mGLIndices); | ||
422 | } | ||
423 | |||
424 | mUsage = GL_STATIC_DRAW_ARB; | ||
425 | mResized = TRUE; | ||
426 | |||
427 | if (!mLocked) | ||
428 | { | ||
429 | mLocked = TRUE; | ||
430 | sLockedList.push_back(this); | ||
431 | } | ||
432 | } | ||
433 | } | ||
434 | |||
435 | void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) | ||
436 | { | ||
437 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
438 | |||
439 | updateNumVerts(nverts); | ||
440 | updateNumIndices(nindices); | ||
441 | |||
442 | if (mMappedData) | ||
443 | { | ||
444 | llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; | ||
445 | } | ||
446 | if (create && (nverts || nindices)) | ||
447 | { | ||
448 | createGLBuffer(); | ||
449 | createGLIndices(); | ||
450 | } | ||
451 | |||
452 | sAllocatedBytes += getSize() + getIndicesSize(); | ||
453 | } | ||
454 | |||
455 | void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) | ||
456 | { | ||
457 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
458 | mDynamicSize = TRUE; | ||
459 | if (mUsage == GL_STATIC_DRAW_ARB) | ||
460 | { //always delete/allocate static buffers on resize | ||
461 | destroyGLBuffer(); | ||
462 | destroyGLIndices(); | ||
463 | allocateBuffer(newnverts, newnindices, TRUE); | ||
464 | mFinal = FALSE; | ||
465 | } | ||
466 | else if (newnverts > mNumVerts || newnindices > mNumIndices || | ||
467 | newnverts < mNumVerts/2 || newnindices < mNumIndices/2) | ||
468 | { | ||
469 | sAllocatedBytes -= getSize() + getIndicesSize(); | ||
470 | |||
471 | S32 oldsize = getSize(); | ||
472 | S32 old_index_size = getIndicesSize(); | ||
473 | |||
474 | updateNumVerts(newnverts); | ||
475 | updateNumIndices(newnindices); | ||
476 | |||
477 | S32 newsize = getSize(); | ||
478 | S32 new_index_size = getIndicesSize(); | ||
479 | |||
480 | sAllocatedBytes += newsize + new_index_size; | ||
481 | |||
482 | if (newsize) | ||
483 | { | ||
484 | if (!mGLBuffer) | ||
485 | { //no buffer exists, create a new one | ||
486 | createGLBuffer(); | ||
487 | } | ||
488 | else | ||
489 | { | ||
490 | //delete old buffer, keep GL buffer for now | ||
491 | U8* old = mMappedData; | ||
492 | mMappedData = new U8[newsize]; | ||
493 | if (old) | ||
494 | { | ||
495 | memcpy(mMappedData, old, llmin(newsize, oldsize)); | ||
496 | if (newsize > oldsize) | ||
497 | { | ||
498 | memset(mMappedData+oldsize, 0, newsize-oldsize); | ||
499 | } | ||
500 | |||
501 | delete [] old; | ||
502 | } | ||
503 | else | ||
504 | { | ||
505 | memset(mMappedData, 0, newsize); | ||
506 | mEmpty = TRUE; | ||
507 | } | ||
508 | mResized = TRUE; | ||
509 | } | ||
510 | } | ||
511 | else if (mGLBuffer) | ||
512 | { | ||
513 | destroyGLBuffer(); | ||
514 | } | ||
515 | |||
516 | if (new_index_size) | ||
517 | { | ||
518 | if (!mGLIndices) | ||
519 | { | ||
520 | createGLIndices(); | ||
521 | } | ||
522 | else | ||
523 | { | ||
524 | //delete old buffer, keep GL buffer for now | ||
525 | U8* old = mMappedIndexData; | ||
526 | mMappedIndexData = new U8[new_index_size]; | ||
527 | if (old) | ||
528 | { | ||
529 | memcpy(mMappedIndexData, old, llmin(new_index_size, old_index_size)); | ||
530 | if (new_index_size > old_index_size) | ||
531 | { | ||
532 | memset(mMappedIndexData+old_index_size, 0, new_index_size - old_index_size); | ||
533 | } | ||
534 | delete [] old; | ||
535 | } | ||
536 | else | ||
537 | { | ||
538 | memset(mMappedIndexData, 0, new_index_size); | ||
539 | mEmpty = TRUE; | ||
540 | } | ||
541 | mResized = TRUE; | ||
542 | } | ||
543 | } | ||
544 | else if (mGLIndices) | ||
545 | { | ||
546 | destroyGLIndices(); | ||
547 | } | ||
548 | } | ||
549 | } | ||
550 | |||
551 | BOOL LLVertexBuffer::useVBOs() const | ||
552 | { | ||
553 | //it's generally ineffective to use VBO for things that are streaming | ||
554 | //when we already have a client buffer around | ||
555 | if (mUsage == GL_STREAM_DRAW_ARB) | ||
556 | { | ||
557 | return FALSE; | ||
558 | } | ||
559 | |||
560 | return sEnableVBOs && (!sRenderActive || !mLocked); | ||
561 | } | ||
562 | |||
563 | //---------------------------------------------------------------------------- | ||
564 | |||
565 | // Map for data access | ||
566 | U8* LLVertexBuffer::mapBuffer(S32 access) | ||
567 | { | ||
568 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
569 | if (sRenderActive) | ||
570 | { | ||
571 | llwarns << "Buffer mapped during render frame!" << llendl; | ||
572 | } | ||
573 | if (!mGLBuffer && !mGLIndices) | ||
574 | { | ||
575 | llerrs << "LLVertexBuffer::mapBuffer() called before createGLBuffer" << llendl; | ||
576 | } | ||
577 | if (mFinal) | ||
578 | { | ||
579 | llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; | ||
580 | } | ||
581 | if (!mMappedData && !mMappedIndexData) | ||
582 | { | ||
583 | llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; | ||
584 | } | ||
585 | |||
586 | if (!mLocked && useVBOs()) | ||
587 | { | ||
588 | mLocked = TRUE; | ||
589 | sLockedList.push_back(this); | ||
590 | } | ||
591 | |||
592 | return mMappedData; | ||
593 | } | ||
594 | |||
595 | void LLVertexBuffer::unmapBuffer() | ||
596 | { | ||
597 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
598 | if (mMappedData || mMappedIndexData) | ||
599 | { | ||
600 | if (useVBOs() && mLocked) | ||
601 | { | ||
602 | if (mGLBuffer) | ||
603 | { | ||
604 | if (mResized) | ||
605 | { | ||
606 | glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage); | ||
607 | } | ||
608 | else | ||
609 | { | ||
610 | if (mEmpty || mDirtyRegions.empty()) | ||
611 | { | ||
612 | glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData); | ||
613 | } | ||
614 | else | ||
615 | { | ||
616 | for (std::vector<DirtyRegion>::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i) | ||
617 | { | ||
618 | DirtyRegion& region = *i; | ||
619 | glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, region.mIndex*mStride, region.mCount*mStride, mMappedData + region.mIndex*mStride); | ||
620 | } | ||
621 | } | ||
622 | } | ||
623 | } | ||
624 | |||
625 | if (mGLIndices) | ||
626 | { | ||
627 | if (mResized) | ||
628 | { | ||
629 | glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage); | ||
630 | } | ||
631 | else | ||
632 | { | ||
633 | if (mEmpty || mDirtyRegions.empty()) | ||
634 | { | ||
635 | glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData); | ||
636 | } | ||
637 | else | ||
638 | { | ||
639 | for (std::vector<DirtyRegion>::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i) | ||
640 | { | ||
641 | DirtyRegion& region = *i; | ||
642 | glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, region.mIndicesIndex*sizeof(U32), | ||
643 | region.mIndicesCount*sizeof(U32), mMappedIndexData + region.mIndicesIndex*sizeof(U32)); | ||
644 | } | ||
645 | } | ||
646 | } | ||
647 | } | ||
648 | |||
649 | mDirtyRegions.clear(); | ||
650 | mFilthy = FALSE; | ||
651 | mResized = FALSE; | ||
652 | |||
653 | if (mUsage == GL_STATIC_DRAW_ARB) | ||
654 | { //static draw buffers can only be mapped a single time | ||
655 | //throw out client data (we won't be using it again) | ||
656 | delete [] mMappedData; | ||
657 | delete [] mMappedIndexData; | ||
658 | mMappedIndexData = NULL; | ||
659 | mMappedData = NULL; | ||
660 | mEmpty = TRUE; | ||
661 | mFinal = TRUE; | ||
662 | } | ||
663 | else | ||
664 | { | ||
665 | mEmpty = FALSE; | ||
666 | } | ||
667 | |||
668 | mLocked = FALSE; | ||
669 | |||
670 | glFlush(); | ||
671 | } | ||
672 | } | ||
673 | } | ||
674 | |||
675 | //---------------------------------------------------------------------------- | ||
676 | |||
677 | template <class T,S32 type> struct VertexBufferStrider | ||
678 | { | ||
679 | typedef LLStrider<T> strider_t; | ||
680 | static bool get(LLVertexBuffer& vbo, | ||
681 | strider_t& strider, | ||
682 | S32 index) | ||
683 | { | ||
684 | vbo.mapBuffer(); | ||
685 | if (type == LLVertexBuffer::TYPE_INDEX) | ||
686 | { | ||
687 | S32 stride = sizeof(T); | ||
688 | strider = (T*)(vbo.getMappedIndices() + index*stride); | ||
689 | strider.setStride(0); | ||
690 | return TRUE; | ||
691 | } | ||
692 | else if (vbo.hasDataType(type)) | ||
693 | { | ||
694 | S32 stride = vbo.getStride(); | ||
695 | strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride); | ||
696 | strider.setStride(stride); | ||
697 | return TRUE; | ||
698 | } | ||
699 | else | ||
700 | { | ||
701 | llerrs << "VertexBufferStrider could not find valid vertex data." << llendl; | ||
702 | } | ||
703 | return FALSE; | ||
704 | } | ||
705 | }; | ||
706 | |||
707 | |||
708 | bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index) | ||
709 | { | ||
710 | return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index); | ||
711 | } | ||
712 | bool LLVertexBuffer::getIndexStrider(LLStrider<U32>& strider, S32 index) | ||
713 | { | ||
714 | return VertexBufferStrider<U32,TYPE_INDEX>::get(*this, strider, index); | ||
715 | } | ||
716 | bool LLVertexBuffer::getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index) | ||
717 | { | ||
718 | return VertexBufferStrider<LLVector2,TYPE_TEXCOORD>::get(*this, strider, index); | ||
719 | } | ||
720 | bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index) | ||
721 | { | ||
722 | return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index); | ||
723 | } | ||
724 | bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index) | ||
725 | { | ||
726 | return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index); | ||
727 | } | ||
728 | bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index) | ||
729 | { | ||
730 | return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index); | ||
731 | } | ||
732 | bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index) | ||
733 | { | ||
734 | return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index); | ||
735 | } | ||
736 | bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index) | ||
737 | { | ||
738 | return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index); | ||
739 | } | ||
740 | bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index) | ||
741 | { | ||
742 | return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index); | ||
743 | } | ||
744 | |||
745 | void LLVertexBuffer::setStride(S32 type, S32 new_stride) | ||
746 | { | ||
747 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
748 | if (mNumVerts) | ||
749 | { | ||
750 | llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; | ||
751 | } | ||
752 | // This code assumes that setStride() will only be called once per VBO per type. | ||
753 | S32 delta = new_stride - sTypeOffsets[type]; | ||
754 | for (S32 i=type+1; i<TYPE_MAX; i++) | ||
755 | { | ||
756 | if (mTypeMask & (1<<i)) | ||
757 | { | ||
758 | mOffsets[i] += delta; | ||
759 | } | ||
760 | } | ||
761 | mStride += delta; | ||
762 | } | ||
763 | |||
764 | //---------------------------------------------------------------------------- | ||
765 | |||
766 | // Set for rendering | ||
767 | void LLVertexBuffer::setBuffer(U32 data_mask) | ||
768 | { | ||
769 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
770 | //set up pointers if the data mask is different ... | ||
771 | BOOL setup = (sLastMask != data_mask); | ||
772 | |||
773 | if (useVBOs()) | ||
774 | { | ||
775 | if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) | ||
776 | { | ||
777 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); | ||
778 | sVBOActive = TRUE; | ||
779 | setup = TRUE; // ... or the bound buffer changed | ||
780 | } | ||
781 | if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)) | ||
782 | { | ||
783 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); | ||
784 | sIBOActive = TRUE; | ||
785 | } | ||
786 | |||
787 | unmapBuffer(); | ||
788 | } | ||
789 | else | ||
790 | { | ||
791 | if (mGLBuffer) | ||
792 | { | ||
793 | if (sEnableVBOs && sVBOActive) | ||
794 | { | ||
795 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); | ||
796 | sVBOActive = FALSE; | ||
797 | setup = TRUE; // ... or a VBO is deactivated | ||
798 | } | ||
799 | if (sGLRenderBuffer != mGLBuffer) | ||
800 | { | ||
801 | setup = TRUE; // ... or a client memory pointer changed | ||
802 | } | ||
803 | } | ||
804 | if (sEnableVBOs && mGLIndices && sIBOActive) | ||
805 | { | ||
806 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); | ||
807 | sIBOActive = FALSE; | ||
808 | } | ||
809 | } | ||
810 | |||
811 | if (mGLIndices) | ||
812 | { | ||
813 | sGLRenderIndices = mGLIndices; | ||
814 | } | ||
815 | if (mGLBuffer) | ||
816 | { | ||
817 | sGLRenderBuffer = mGLBuffer; | ||
818 | if (data_mask && setup) | ||
819 | { | ||
820 | if (!sRenderActive) | ||
821 | { | ||
822 | llwarns << "Vertex buffer set for rendering outside of render frame." << llendl; | ||
823 | } | ||
824 | setupVertexBuffer(data_mask); // subclass specific setup (virtual function) | ||
825 | sLastMask = data_mask; | ||
826 | } | ||
827 | } | ||
828 | } | ||
829 | |||
830 | // virtual (default) | ||
831 | void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const | ||
832 | { | ||
833 | LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); | ||
834 | stop_glerror(); | ||
835 | U8* base = useVBOs() ? NULL : mMappedData; | ||
836 | S32 stride = mStride; | ||
837 | |||
838 | if ((data_mask & mTypeMask) != data_mask) | ||
839 | { | ||
840 | llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; | ||
841 | } | ||
842 | |||
843 | if (data_mask & MAP_VERTEX) | ||
844 | { | ||
845 | glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0)); | ||
846 | } | ||
847 | if (data_mask & MAP_NORMAL) | ||
848 | { | ||
849 | glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL])); | ||
850 | } | ||
851 | if (data_mask & MAP_TEXCOORD2) | ||
852 | { | ||
853 | glClientActiveTextureARB(GL_TEXTURE1_ARB); | ||
854 | glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2])); | ||
855 | } | ||
856 | if (data_mask & MAP_TEXCOORD) | ||
857 | { | ||
858 | glClientActiveTextureARB(GL_TEXTURE0_ARB); | ||
859 | glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD])); | ||
860 | } | ||
861 | if (data_mask & MAP_COLOR) | ||
862 | { | ||
863 | glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR])); | ||
864 | } | ||
865 | if (data_mask & MAP_BINORMAL) | ||
866 | { | ||
867 | glVertexAttribPointerARB(6, 3, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_BINORMAL])); | ||
868 | } | ||
869 | if (data_mask & MAP_WEIGHT) | ||
870 | { | ||
871 | glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT])); | ||
872 | } | ||
873 | if (data_mask & MAP_CLOTHWEIGHT) | ||
874 | { | ||
875 | glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); | ||
876 | } | ||
877 | |||
878 | llglassertok(); | ||
879 | } | ||
880 | |||
881 | void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count) | ||
882 | { | ||
883 | if (useVBOs() && !mFilthy) | ||
884 | { | ||
885 | if (!mDirtyRegions.empty()) | ||
886 | { | ||
887 | DirtyRegion& region = *(mDirtyRegions.rbegin()); | ||
888 | |||
889 | if (region.mIndex+region.mCount > vert_index) | ||
890 | { | ||
891 | //this buffer has received multiple updates since the last copy, mark it filthy | ||
892 | mFilthy = TRUE; | ||
893 | mDirtyRegions.clear(); | ||
894 | return; | ||
895 | } | ||
896 | |||
897 | if (region.mIndex + region.mCount == vert_index && | ||
898 | region.mIndicesIndex + region.mIndicesCount == indices_index) | ||
899 | { | ||
900 | region.mCount += vert_count; | ||
901 | region.mIndicesCount += indices_count; | ||
902 | return; | ||
903 | } | ||
904 | } | ||
905 | |||
906 | mDirtyRegions.push_back(DirtyRegion(vert_index,vert_count,indices_index,indices_count)); | ||
907 | } | ||
908 | } | ||
909 | |||
910 | void LLVertexBuffer::markClean() | ||
911 | { | ||
912 | if (!mResized && !mEmpty && !mFilthy) | ||
913 | { | ||
914 | buffer_list_t::reverse_iterator iter = sLockedList.rbegin(); | ||
915 | if (*iter == this) | ||
916 | { | ||
917 | mLocked = FALSE; | ||
918 | sLockedList.pop_back(); | ||
919 | } | ||
920 | } | ||
921 | } | ||
922 | |||
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 @@ | |||
1 | #ifndef LL_LLVERTEXBUFFER_H | ||
2 | #define LL_LLVERTEXBUFFER_H | ||
3 | |||
4 | #include "llgl.h" | ||
5 | #include "v2math.h" | ||
6 | #include "v3math.h" | ||
7 | #include "v4math.h" | ||
8 | #include "v4coloru.h" | ||
9 | #include "llstrider.h" | ||
10 | #include "llmemory.h" | ||
11 | #include <set> | ||
12 | #include <vector> | ||
13 | |||
14 | //============================================================================ | ||
15 | // NOTES | ||
16 | // Threading: | ||
17 | // All constructors should take an 'create' paramater which should only be | ||
18 | // 'true' when called from the main thread. Otherwise createGLBuffer() will | ||
19 | // be called as soon as getVertexPointer(), etc is called (which MUST ONLY be | ||
20 | // called from the main (i.e OpenGL) thread) | ||
21 | |||
22 | //============================================================================ | ||
23 | // base class | ||
24 | |||
25 | class LLVertexBuffer : public LLRefCount | ||
26 | { | ||
27 | public: | ||
28 | static void initClass(bool use_vbo); | ||
29 | static void cleanupClass(); | ||
30 | static void startRender(); //between start and stop render, no client copies will occur | ||
31 | static void stopRender(); //any buffer not copied to GL will be rendered from client memory | ||
32 | static void clientCopy(F64 max_time = 0.005); //copy data from client to GL | ||
33 | static void unbind(); //unbind any bound vertex buffer | ||
34 | |||
35 | enum { | ||
36 | TYPE_VERTEX, | ||
37 | TYPE_NORMAL, | ||
38 | TYPE_TEXCOORD, | ||
39 | TYPE_TEXCOORD2, | ||
40 | TYPE_COLOR, | ||
41 | // These use VertexAttribPointer and should possibly be made generic | ||
42 | TYPE_BINORMAL, | ||
43 | TYPE_WEIGHT, | ||
44 | TYPE_CLOTHWEIGHT, | ||
45 | TYPE_MAX, | ||
46 | TYPE_INDEX, | ||
47 | }; | ||
48 | enum { | ||
49 | MAP_VERTEX = (1<<TYPE_VERTEX), | ||
50 | MAP_NORMAL = (1<<TYPE_NORMAL), | ||
51 | MAP_TEXCOORD = (1<<TYPE_TEXCOORD), | ||
52 | MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2), | ||
53 | MAP_COLOR = (1<<TYPE_COLOR), | ||
54 | // These use VertexAttribPointer and should possibly be made generic | ||
55 | MAP_BINORMAL = (1<<TYPE_BINORMAL), | ||
56 | MAP_WEIGHT = (1<<TYPE_WEIGHT), | ||
57 | MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), | ||
58 | MAP_DRAW = 0x2000, // Buffer is in draw (read-only) mode | ||
59 | MAP_MAPPED = 0x4000, // Indicates that buffer has been mapped, but not to any type of data | ||
60 | MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped | ||
61 | }; | ||
62 | |||
63 | protected: | ||
64 | virtual ~LLVertexBuffer(); // use unref() | ||
65 | |||
66 | virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer() | ||
67 | |||
68 | void createGLBuffer(); | ||
69 | void createGLIndices(); | ||
70 | void destroyGLBuffer(); | ||
71 | void destroyGLIndices(); | ||
72 | void updateNumVerts(S32 nverts); | ||
73 | void updateNumIndices(S32 nindices); | ||
74 | virtual BOOL useVBOs() const; | ||
75 | void unmapBuffer(); | ||
76 | |||
77 | public: | ||
78 | LLVertexBuffer(U32 typemask, S32 usage); | ||
79 | |||
80 | // map for data access | ||
81 | U8* mapBuffer(S32 access = -1); | ||
82 | // set for rendering | ||
83 | virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 | ||
84 | // allocate buffer | ||
85 | void allocateBuffer(S32 nverts, S32 nindices, bool create); | ||
86 | virtual void resizeBuffer(S32 newnverts, S32 newnindices); | ||
87 | void makeStatic(); | ||
88 | |||
89 | // Only call each getVertexPointer, etc, once before calling unmapBuffer() | ||
90 | // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer() | ||
91 | // example: | ||
92 | // vb->getVertexBuffer(verts); | ||
93 | // vb->getNormalStrider(norms); | ||
94 | // setVertsNorms(verts, norms); | ||
95 | // vb->unmapBuffer(); | ||
96 | bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0); | ||
97 | bool getIndexStrider(LLStrider<U32>& strider, S32 index=0); | ||
98 | bool getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index=0); | ||
99 | bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0); | ||
100 | bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0); | ||
101 | bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0); | ||
102 | bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0); | ||
103 | bool getWeightStrider(LLStrider<F32>& strider, S32 index=0); | ||
104 | bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0); | ||
105 | |||
106 | BOOL isEmpty() const { return mEmpty; } | ||
107 | BOOL isLocked() const { return mLocked; } | ||
108 | S32 getNumVerts() const { return mNumVerts; } | ||
109 | S32 getNumIndices() const { return mNumIndices; } | ||
110 | U8* getIndicesPointer() const { return useVBOs() ? NULL : mMappedIndexData; } | ||
111 | U8* getVerticesPointer() const { return useVBOs() ? NULL : mMappedData; } | ||
112 | S32 getStride() const { return mStride; } | ||
113 | S32 getTypeMask() const { return mTypeMask; } | ||
114 | BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; } | ||
115 | S32 getSize() const { return mNumVerts*mStride; } | ||
116 | S32 getIndicesSize() const { return mNumIndices * sizeof(U32); } | ||
117 | U8* getMappedData() const { return mMappedData; } | ||
118 | U8* getMappedIndices() const { return mMappedIndexData; } | ||
119 | S32 getOffset(S32 type) const { return mOffsets[type]; } | ||
120 | S32 getUsage() const { return mUsage; } | ||
121 | |||
122 | void setStride(S32 type, S32 new_stride); | ||
123 | |||
124 | void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count); | ||
125 | void markClean(); | ||
126 | |||
127 | protected: | ||
128 | S32 mNumVerts; // Number of vertices | ||
129 | S32 mNumIndices; // Number of indices | ||
130 | S32 mStride; | ||
131 | U32 mTypeMask; | ||
132 | S32 mUsage; // GL usage | ||
133 | U32 mGLBuffer; // GL VBO handle | ||
134 | U32 mGLIndices; // GL IBO handle | ||
135 | U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) | ||
136 | U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) | ||
137 | BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory | ||
138 | BOOL mFinal; // if TRUE, buffer can not be mapped again | ||
139 | BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags) | ||
140 | BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. | ||
141 | S32 mOffsets[TYPE_MAX]; | ||
142 | BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not | ||
143 | BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded) | ||
144 | |||
145 | class DirtyRegion | ||
146 | { | ||
147 | public: | ||
148 | U32 mIndex; | ||
149 | U32 mCount; | ||
150 | U32 mIndicesIndex; | ||
151 | U32 mIndicesCount; | ||
152 | |||
153 | DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic) | ||
154 | : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic) | ||
155 | { } | ||
156 | }; | ||
157 | |||
158 | std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild | ||
159 | |||
160 | public: | ||
161 | static BOOL sRenderActive; | ||
162 | static S32 sCount; | ||
163 | static S32 sGLCount; | ||
164 | static std::vector<U32> sDeleteList; | ||
165 | typedef std::list<LLVertexBuffer*> buffer_list_t; | ||
166 | static buffer_list_t sLockedList; | ||
167 | |||
168 | static BOOL sEnableVBOs; | ||
169 | static S32 sTypeOffsets[TYPE_MAX]; | ||
170 | static U32 sGLRenderBuffer; | ||
171 | static U32 sGLRenderIndices; | ||
172 | static BOOL sVBOActive; | ||
173 | static BOOL sIBOActive; | ||
174 | static U32 sLastMask; | ||
175 | static U32 sAllocatedBytes; | ||
176 | }; | ||
177 | |||
178 | |||
179 | #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) | |||
92 | line_num++; | 92 | line_num++; |
93 | next_token = strchr(next_token, '\n'); | 93 | next_token = strchr(next_token, '\n'); |
94 | } | 94 | } |
95 | char output[1024]; | ||
96 | char bad_code[11]; | 95 | char bad_code[11]; |
97 | strncpy(bad_code, text_buffer + error_pos, 10); | 96 | strncpy(bad_code, text_buffer + error_pos, 10); |
98 | bad_code[10] = '\0'; | 97 | bad_code[10] = '\0'; |
99 | 98 | ||
100 | sprintf(output, "%s(%d): Vertex Program Error: %s at (%s)\n", filename, line_num, program_error_string, bad_code); | 99 | llerrs << filename << "(" << line_num << "): Vertex Program Error: " |
101 | gErrorStream << output << std::endl; | 100 | << program_error_string << " at (" << bad_code<< ")" |
101 | << llendl; | ||
102 | // clean up buffer | 102 | // clean up buffer |
103 | delete[] text_buffer; | 103 | delete[] text_buffer; |
104 | return FALSE; | 104 | 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 | |||
52 | // const LLFontGL *font; | 52 | // const LLFontGL *font; |
53 | // U8 color[3]; | 53 | // U8 color[3]; |
54 | // U8 bg_color[3]; | 54 | // U8 bg_color[3]; |
55 | char line[MAX_TEXT_LINE_LENGTH]; | 55 | char line[MAX_TEXT_LINE_LENGTH]; /* Flawfinder: ignore */ |
56 | S32 x, y; | 56 | S32 x, y; |
57 | // ETextModifiers tm; | 57 | // ETextModifiers tm; |
58 | // ETextColorModifiers fcm; | 58 | // ETextColorModifiers fcm; |
@@ -84,7 +84,7 @@ void add_text(S32 x, S32 y, char *text) // , ETextModifiers tm, ETextColorModifi | |||
84 | 84 | ||
85 | TEXT_LINE *linep = &gTextLine[gNumTextLines++]; | 85 | TEXT_LINE *linep = &gTextLine[gNumTextLines++]; |
86 | 86 | ||
87 | strcpy(linep->line, text); | 87 | strcpy(linep->line, text); /* Flawfinder: ignore */ |
88 | linep->x = x; | 88 | linep->x = x; |
89 | linep->y = y; | 89 | linep->y = y; |
90 | } | 90 | } |