aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llagparray.inl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llagparray.inl519
1 files changed, 0 insertions, 519 deletions
diff --git a/linden/indra/newview/llagparray.inl b/linden/indra/newview/llagparray.inl
deleted file mode 100644
index 418f7d9..0000000
--- a/linden/indra/newview/llagparray.inl
+++ /dev/null
@@ -1,519 +0,0 @@
1/**
2 * @file llagparray.inl
3 * @brief LLAGPArray - arrays used for rendering w/ AGP memory (if on)
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 "llagpmempool.h"
29#include "llglheaders.h"
30#include "pipeline.h" // for gPipeline
31#include "v4math.h"
32
33template <class Type>
34void LLAGPArray<Type>::flushAGP()
35{
36 delete mAGPp;
37 mAGPp = NULL;
38
39 setDirty();
40}
41
42template <class Type>
43void LLAGPArray<Type>::reset(S32 reserve_count)
44{
45 mNumObj = 0;
46 realloc(reserve_count);
47 setDirty();
48}
49
50template <class Type>
51S32 LLAGPArray<Type>::find(const Type &obj) const
52{
53 for ( S32 i = 0; i < (S32)mNumObj; i++ )
54 {
55 if (mMemp[i] == obj)
56 {
57 return i;
58 }
59 }
60 return FAIL;
61}
62
63template <class Type>
64Type* LLAGPArray<Type>::reserve_block(const U32 num)
65{
66 if (!num)
67 {
68 return NULL;
69 }
70
71 setDirty();
72
73 U32 new_count = mNumObj + num;
74 if (new_count >= mMaxObj)
75 {
76 if (!realloc(new_count))
77 {
78 llwarns << "Unable to realloc " << num << " objects in LLAGPArray!" << llendl;
79 return NULL;
80 }
81 }
82
83 if (mMemp)
84 {
85 Type *ret = &mMemp[mNumObj];
86 mNumObj += num;
87 return ret;
88 }
89
90 return NULL;
91}
92
93template <class Type>
94S32 LLAGPArray<Type>::put(const Type &obj)
95{
96 if (mNumObj >= mMaxObj)
97 {
98 if (!mMaxObj)
99 {
100 mMaxObj = 1;
101 }
102 if (!realloc(mMaxObj*2))
103 {
104 llwarns << "Unable to put in AGPArray due to realloc!" << llendl;
105 return FAIL;
106 }
107 }
108
109 mMemp[mNumObj] = obj;
110 mNumObj++;
111 setDirty();
112 return OKAY;
113}
114
115template <class Type>
116S32 LLAGPArray<Type>::shrinkTo(S32 newcount)
117{
118 mNumObj = newcount;
119 return mNumObj;
120}
121
122template <class Type>
123LLAGPArray<Type>::LLAGPArray(const S32 size, const U32 target)
124{
125 if (!target)
126 {
127 mTarget = GL_ARRAY_BUFFER_ARB;
128 }
129 else
130 {
131 mTarget = target;
132 }
133
134 mSynced = FALSE;
135 mMaxObj = 0;
136 mNumObj = 0;
137 mMemp = NULL;
138 mUnalignedMemp = NULL;
139 mUseAGP = FALSE;
140 mAGPp = NULL;
141 mDirty = TRUE;
142
143 if (size)
144 {
145 if (!realloc(size))
146 {
147 llerrs << "Unable to allocate AGP array of size: " << size << llendl;
148 }
149 }
150}
151
152template <class Type>
153BOOL LLAGPArray<Type>::realloc(U32 new_count)
154{
155 const U32 min_count = 1024;
156 U32 max_count = llmax(min_count, mMaxObj);
157 if (new_count == 0)
158 {
159 delete[] mUnalignedMemp;
160 mUnalignedMemp = NULL;
161 mMemp = NULL;
162
163 delete mAGPp;
164 mAGPp = NULL;
165
166 mNumObj = 0;
167 mMaxObj = 0;
168
169 return TRUE;
170 }
171 if (new_count < min_count)
172 {
173 new_count = min_count;
174 }
175 else if (new_count < max_count>>1)
176 {
177 new_count = new_count + (new_count>>1);
178 }
179 else
180 {
181 while (max_count < new_count)
182 {
183 max_count += max_count>>1;
184 }
185 new_count = max_count;
186 }
187 if (new_count != mMaxObj)
188 {
189 //Type *new_obj_array = new Type[new_count];
190 const size_t ALIGN_BYTES = 64;
191 U8* new_unaligned_obj_array = new U8[ sizeof(Type) * new_count + ALIGN_BYTES - 1];
192 if (!new_unaligned_obj_array)
193 {
194 llerrs << "Out of system memory in LLAGPArray::realloc - tried to alloc " << new_count << llendl;
195 return FALSE;
196 }
197
198 Type* new_obj_array;
199 // Use size_t to avoid warning -- size_t should be the same size as a pointer
200 // for 32 and 64 bit architectures. JC
201 size_t offset = (size_t)new_unaligned_obj_array;
202 S32 skip_bytes = (S32)(offset % ALIGN_BYTES);
203 if( skip_bytes )
204 {
205 new_obj_array = (Type*) (new_unaligned_obj_array + ALIGN_BYTES - skip_bytes);
206 }
207 else
208 {
209 new_obj_array = (Type*) new_unaligned_obj_array;
210 }
211
212 delete mAGPp;
213 mAGPp = NULL;
214
215 if (mUseAGP)
216 {
217 mAGPp = gPipeline.allocAGPFromPool(new_count * sizeof(Type), mTarget);
218 setDirty();
219 }
220
221 if (!mAGPp && mUseAGP)
222 {
223#ifdef DEBUG_AGP
224 llwarns << "Failed AGP allocation in realloc!" << llendl;
225#endif
226 }
227
228 // Copying data from previous array to new array.
229 if (new_count < mNumObj)
230 {
231 mNumObj = new_count;
232 }
233
234 if (mNumObj > 0 && mMemp)
235 {
236 memcpy(new_obj_array, mMemp, mNumObj*sizeof(Type));
237 }
238
239 delete[] mUnalignedMemp;
240 mUnalignedMemp = new_unaligned_obj_array;
241 mMemp = new_obj_array;
242
243 mMaxObj = new_count;
244 }
245
246 return TRUE;
247}
248
249template <class Type>
250void LLAGPArray<Type>::copyToMem(const S32 offset, const U8 *source, const S32 size)
251{
252 llassert(mMemp);
253 memcpy((mMemp + offset), source, size*sizeof(Type));
254}
255
256template <class Type>
257BOOL LLAGPArray<Type>::sync()
258{
259 if (mUseAGP && !mAGPp && !mDirty)
260 {
261 llwarns << "No AGP, yet not dirty!" << llendl;
262 }
263
264 if (mUseAGP && mDirty && mNumObj)
265 {
266 if (!mAGPp)
267 {
268 mAGPp = gPipeline.allocAGPFromPool(mMaxObj * sizeof(Type), mTarget);
269 if (!mAGPp)
270 {
271#ifdef DEBUG_AGP
272 llwarns << "Failure to allocate AGP in sync!" << llendl;
273#endif
274 mUseAGP = FALSE;
275 }
276 else
277 {
278 mAGPp->copy(mMemp, mNumObj * sizeof(Type));
279 }
280 }
281 else
282 {
283 mAGPp->copy(mMemp, mNumObj * sizeof(Type));
284 }
285 mSynced = TRUE;
286 }
287 mDirty = FALSE;
288 return mSynced;
289}
290
291template <class Type>
292BOOL LLAGPArray<Type>::syncColor()
293{
294 if (mUseAGP && mDirty && mNumObj)
295 {
296 if (!mAGPp)
297 {
298 mAGPp = gPipeline.allocAGPFromPool(mMaxObj * sizeof(Type), mTarget);
299 if (!mAGPp)
300 {
301#ifdef DEBUG_AGP
302 llwarns << "Failure to allocate AGP in synccolor!" << llendl;
303#endif
304 mUseAGP = FALSE;
305 }
306 else
307 {
308 mAGPp->copyColor(mMemp, mNumObj * sizeof(Type));
309 }
310 }
311 else
312 {
313 mAGPp->copyColor(mMemp, mNumObj * sizeof(Type));
314 }
315 mSynced = TRUE;
316 }
317 mDirty = FALSE;
318 return mSynced;
319}
320
321template <class Type>
322BOOL LLAGPArray<Type>::setUseAGP(const BOOL on)
323{
324 if (on == mUseAGP)
325 {
326 return TRUE;
327 }
328
329 mUseAGP = on;
330 if (!on)
331 {
332 delete mAGPp;
333 mAGPp = NULL;
334 }
335 else if (on)
336 {
337 mAGPp = gPipeline.allocAGPFromPool(mMaxObj * sizeof(Type), mTarget);
338 setDirty();
339 if (!mAGPp)
340 {
341#ifdef DEBUG_AGP
342 llwarns << "Failure to allocate AGP in setUseAGP! Block size = " << (mMaxObj * sizeof(Type)) << llendl;
343#endif
344 mUseAGP = FALSE;
345 return FALSE;
346 }
347 }
348 return TRUE;
349}
350
351extern U8* gAGPVertices;
352extern U8* gAGPNormals;
353
354template <class Type>
355U8* LLAGPArray<Type>::getScratchMemory()
356{
357 U8* memp = NULL;
358
359 if (mAGPp && gPipeline.isAGPBound())
360 {
361 memp = mAGPp->getMappedMem();
362 }
363 if (!memp)
364 {
365 memp = ((U8*)mMemp);
366 }
367
368 return memp;
369}
370
371template <class Type>
372void LLAGPArray<Type>::bindGLVertexPointer(const U32 stride, const U32 offset)
373{
374 if (mAGPp && gPipeline.isAGPBound())
375 {
376 mAGPp->bindGLVertexPointer(stride, offset);
377 }
378 else
379 {
380 if (gPipeline.isAGPBound())
381 {
382 llerrs << "Binding non-AGP vertex pointer when AGP enabled" << llendl;
383 }
384 if (!mMemp)
385 {
386 llerrs << "Binding empty vertex array" << llendl;
387 }
388 llassert(mMemp);
389 glVertexPointer(3, GL_FLOAT, stride, ((U8 *)mMemp) + offset);
390 }
391}
392
393template <class Type>
394void LLAGPArray<Type>::bindGLTexCoordPointer(const U32 stride, const U32 offset)
395{
396 if (mAGPp && gPipeline.isAGPBound())
397 {
398 mAGPp->bindGLTexCoordPointer(stride, offset);
399 }
400 else
401 {
402 if (gPipeline.isAGPBound())
403 {
404 llwarns << "Binding non-AGP texture coords pointer when AGP enabled" << llendl;
405 }
406 if (!mMemp)
407 {
408 llerrs << "Binding empty tex coord array" << llendl;
409 }
410 glTexCoordPointer(2, GL_FLOAT, stride, ((U8 *)mMemp) + offset);
411 }
412}
413
414template <class Type>
415void LLAGPArray<Type>::bindGLNormalPointer(const U32 stride, const U32 offset)
416{
417 if (mAGPp && gPipeline.isAGPBound())
418 {
419 mAGPp->bindGLNormalPointer(stride, offset);
420 }
421 else
422 {
423 if (gPipeline.isAGPBound())
424 {
425 llwarns << "Binding non-AGP normals pointer when AGP enabled" << llendl;
426 }
427 if (!mMemp)
428 {
429 llerrs << "Binding empty normal array" << llendl;
430 }
431 glNormalPointer(GL_FLOAT, stride, ((U8 *)mMemp) + offset);
432 }
433}
434
435template <class Type>
436void LLAGPArray<Type>::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset)
437{
438 if (mAGPp && gPipeline.isAGPBound())
439 {
440 mAGPp->bindGLBinormalPointer(index, stride, offset);
441 }
442 else
443 {
444 if (gPipeline.isAGPBound())
445 {
446 llwarns << "Binding non-AGP binormal pointer when AGP enabled" << llendl;
447 }
448 if (!mMemp)
449 {
450 llerrs << "Binding empty binormal array" << llendl;
451 }
452 set_binormals(index, stride, (LLVector3 *)(((U8 *)mMemp) + offset));
453 }
454}
455
456
457template <class Type>
458void LLAGPArray<Type>::bindGLColorPointer(const U32 stride, const U32 offset)
459{
460 if (mAGPp && gPipeline.isAGPBound())
461 {
462 mAGPp->bindGLColorPointer(stride, offset);
463 }
464 else
465 {
466 if (gPipeline.isAGPBound())
467 {
468 llwarns << "Binding non-AGP color pointer when AGP enabled" << llendl;
469 }
470 if (!mMemp)
471 {
472 llerrs << "Binding empty color array" << llendl;
473 }
474 glColorPointer(4, GL_UNSIGNED_BYTE, stride, ((U8 *)mMemp) + offset);
475 }
476}
477
478template <class Type>
479void LLAGPArray<Type>::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset)
480{
481 if (mAGPp && gPipeline.isAGPBound())
482 {
483 mAGPp->bindGLVertexWeightPointer(index, stride, offset);
484 }
485 else
486 {
487 if (gPipeline.isAGPBound())
488 {
489 llwarns << "Binding non-AGP vertex weight pointer when AGP enabled" << llendl;
490 }
491 if (!mMemp)
492 {
493 llerrs << "Binding empty vertex weight array" << llendl;
494 }
495 set_vertex_weights(index, (F32 *)(((U8 *)mMemp) + offset));
496 }
497}
498
499template <class Type>
500void LLAGPArray<Type>::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset)
501{
502 if (mAGPp && gPipeline.isAGPBound())
503 {
504 mAGPp->bindGLVertexClothingWeightPointer(index, stride, offset);
505 }
506 else
507 {
508 if (gPipeline.isAGPBound())
509 {
510 llwarns << "Binding non-AGP vertex weight pointer when AGP enabled" << llendl;
511 }
512 if (!mMemp)
513 {
514 llerrs << "Binding empty vertex weight array" << llendl;
515 }
516 set_vertex_clothing_weights(index, stride, (LLVector4 *)(((U8 *)mMemp) + offset));
517 }
518}
519