blob: 513512b3405330cf20b4f9819591c8ed52b5ba9a [file] [log] [blame]
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00001//
daniel@transgaming.comf6549452012-01-27 15:39:08 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
daniel@transgaming.com8fd34bd2011-02-18 02:52:14 +00007// IndexDataManager.cpp: Defines the IndexDataManager, a class that
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00008// runs the Buffer translation process for index buffers.
9
daniel@transgaming.com8fd34bd2011-02-18 02:52:14 +000010#include "libGLESv2/IndexDataManager.h"
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000011
12#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013
14#include "libGLESv2/Buffer.h"
daniel@transgaming.com81655a72010-05-20 19:18:17 +000015#include "libGLESv2/mathutil.h"
daniel@transgaming.com37b141e2011-01-08 05:46:13 +000016#include "libGLESv2/main.h"
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000017
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000018namespace gl
19{
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +000020unsigned int IndexBuffer::mCurrentSerial = 1;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000021
daniel@transgaming.com6716a272012-10-31 18:31:39 +000022IndexDataManager::IndexDataManager(Context *context, renderer::Renderer *renderer) : mRenderer(renderer)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000023{
daniel@transgaming.com6716a272012-10-31 18:31:39 +000024 mStreamingBufferShort = new StreamingIndexBuffer(mRenderer, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
daniel@transgaming.com81655a72010-05-20 19:18:17 +000025
daniel@transgaming.com83921382011-01-08 05:46:00 +000026 if (context->supports32bitIndices())
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000027 {
daniel@transgaming.com6716a272012-10-31 18:31:39 +000028 mStreamingBufferInt = new StreamingIndexBuffer(mRenderer, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
daniel@transgaming.com72b9e182011-04-13 14:58:33 +000029
30 if (!mStreamingBufferInt)
31 {
32 // Don't leave it in a half-initialized state
33 delete mStreamingBufferShort;
34 mStreamingBufferShort = NULL;
35 }
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000036 }
37 else
38 {
daniel@transgaming.com83921382011-01-08 05:46:00 +000039 mStreamingBufferInt = NULL;
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000040 }
daniel@transgaming.com72b9e182011-04-13 14:58:33 +000041
42 if (!mStreamingBufferShort)
43 {
44 ERR("Failed to allocate the streaming index buffer(s).");
45 }
daniel@transgaming.comf6549452012-01-27 15:39:08 +000046
47 mCountingBuffer = NULL;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000048}
49
50IndexDataManager::~IndexDataManager()
51{
daniel@transgaming.com83921382011-01-08 05:46:00 +000052 delete mStreamingBufferShort;
53 delete mStreamingBufferInt;
daniel@transgaming.comf6549452012-01-27 15:39:08 +000054 delete mCountingBuffer;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000055}
56
daniel@transgaming.com83921382011-01-08 05:46:00 +000057void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000058{
daniel@transgaming.com83921382011-01-08 05:46:00 +000059 if (type == GL_UNSIGNED_BYTE)
60 {
61 const GLubyte *in = static_cast<const GLubyte*>(input);
62 GLushort *out = static_cast<GLushort*>(output);
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000063
daniel@transgaming.com83921382011-01-08 05:46:00 +000064 for (GLsizei i = 0; i < count; i++)
65 {
66 out[i] = in[i];
67 }
68 }
69 else if (type == GL_UNSIGNED_INT)
70 {
71 memcpy(output, input, count * sizeof(GLuint));
72 }
73 else if (type == GL_UNSIGNED_SHORT)
74 {
75 memcpy(output, input, count * sizeof(GLushort));
76 }
77 else UNREACHABLE();
78}
79
80template <class IndexType>
81void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000082{
daniel@transgaming.com83921382011-01-08 05:46:00 +000083 *minIndex = indices[0];
84 *maxIndex = indices[0];
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000085
86 for (GLsizei i = 0; i < count; i++)
87 {
daniel@transgaming.com83921382011-01-08 05:46:00 +000088 if (*minIndex > indices[i]) *minIndex = indices[i];
89 if (*maxIndex < indices[i]) *maxIndex = indices[i];
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000090 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000091}
92
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +000093void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000094{
daniel@transgaming.com83921382011-01-08 05:46:00 +000095 if (type == GL_UNSIGNED_BYTE)
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +000096 {
daniel@transgaming.com83921382011-01-08 05:46:00 +000097 computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
98 }
99 else if (type == GL_UNSIGNED_INT)
100 {
101 computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
102 }
103 else if (type == GL_UNSIGNED_SHORT)
104 {
105 computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
106 }
107 else UNREACHABLE();
108}
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000109
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +0000110GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000111{
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000112 if (!mStreamingBufferShort)
113 {
114 return GL_OUT_OF_MEMORY;
115 }
116
daniel@transgaming.com83921382011-01-08 05:46:00 +0000117 D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
118 intptr_t offset = reinterpret_cast<intptr_t>(indices);
119 bool alignedOffset = false;
120
121 if (buffer != NULL)
122 {
123 switch (type)
124 {
125 case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
126 case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
127 case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;
128 default: UNREACHABLE(); alignedOffset = false;
129 }
130
131 if (typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000132 {
133 return GL_INVALID_OPERATION;
134 }
135
daniel@transgaming.com83921382011-01-08 05:46:00 +0000136 indices = static_cast<const GLubyte*>(buffer->data()) + offset;
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000137 }
138
daniel@transgaming.com83921382011-01-08 05:46:00 +0000139 StreamingIndexBuffer *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000140
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000141 StaticIndexBuffer *staticBuffer = buffer ? buffer->getStaticIndexBuffer() : NULL;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000142 IndexBuffer *indexBuffer = streamingBuffer;
143 UINT streamOffset = 0;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000144
daniel@transgaming.com83921382011-01-08 05:46:00 +0000145 if (staticBuffer && staticBuffer->lookupType(type) && alignedOffset)
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000146 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000147 indexBuffer = staticBuffer;
148 streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex);
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000149
daniel@transgaming.com83921382011-01-08 05:46:00 +0000150 if (streamOffset == -1)
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000151 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000152 streamOffset = (offset / typeSize(type)) * indexSize(format);
153 computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
154 staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000155 }
156 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000157 else
158 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000159 int convertCount = count;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000160
daniel@transgaming.com83921382011-01-08 05:46:00 +0000161 if (staticBuffer)
162 {
163 if (staticBuffer->size() == 0 && alignedOffset)
164 {
165 indexBuffer = staticBuffer;
166 convertCount = buffer->size() / typeSize(type);
167 }
168 else
169 {
170 buffer->invalidateStaticData();
171 staticBuffer = NULL;
172 }
173 }
174
daniel@transgaming.com5ee2ad02011-01-08 05:46:20 +0000175 void *output = NULL;
176
177 if (indexBuffer)
178 {
179 indexBuffer->reserveSpace(convertCount * indexSize(format), type);
180 output = indexBuffer->map(indexSize(format) * convertCount, &streamOffset);
181 }
182
daniel@transgaming.com83921382011-01-08 05:46:00 +0000183 if (output == NULL)
184 {
185 ERR("Failed to map index buffer.");
186 return GL_OUT_OF_MEMORY;
187 }
188
189 convertIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
190 indexBuffer->unmap();
191
192 computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
193
194 if (staticBuffer)
195 {
196 streamOffset = (offset / typeSize(type)) * indexSize(format);
197 staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
198 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000199 }
200
daniel@transgaming.com83921382011-01-08 05:46:00 +0000201 translated->indexBuffer = indexBuffer->getBuffer();
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000202 translated->serial = indexBuffer->getSerial();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000203 translated->startIndex = streamOffset / indexSize(format);
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000204
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000205 if (buffer)
206 {
207 buffer->promoteStaticUsage(count * typeSize(type));
208 }
209
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000210 return GL_NO_ERROR;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000211}
212
daniel@transgaming.com83921382011-01-08 05:46:00 +0000213std::size_t IndexDataManager::indexSize(D3DFORMAT format) const
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000214{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000215 return (format == D3DFMT_INDEX32) ? sizeof(unsigned int) : sizeof(unsigned short);
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000216}
217
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000218std::size_t IndexDataManager::typeSize(GLenum type) const
219{
220 switch (type)
221 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000222 case GL_UNSIGNED_INT: return sizeof(GLuint);
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000223 case GL_UNSIGNED_SHORT: return sizeof(GLushort);
daniel@transgaming.com83921382011-01-08 05:46:00 +0000224 case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
225 default: UNREACHABLE(); return sizeof(GLushort);
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000226 }
227}
228
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000229StaticIndexBuffer *IndexDataManager::getCountingIndices(GLsizei count)
230{
daniel@transgaming.com0f328a72012-03-05 15:07:50 +0000231 if (count <= 65536) // 16-bit indices
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000232 {
233 const unsigned int spaceNeeded = count * sizeof(unsigned short);
234
235 if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
236 {
237 delete mCountingBuffer;
daniel@transgaming.com6716a272012-10-31 18:31:39 +0000238 mCountingBuffer = new StaticIndexBuffer(mRenderer);
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000239 mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
240
241 UINT offset;
242 unsigned short *data = static_cast<unsigned short*>(mCountingBuffer->map(spaceNeeded, &offset));
243
244 if (data)
245 {
246 for(int i = 0; i < count; i++)
247 {
248 data[i] = i;
249 }
250
251 mCountingBuffer->unmap();
252 }
253 }
254 }
255 else if (mStreamingBufferInt) // 32-bit indices supported
256 {
257 const unsigned int spaceNeeded = count * sizeof(unsigned int);
258
259 if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
260 {
261 delete mCountingBuffer;
daniel@transgaming.com6716a272012-10-31 18:31:39 +0000262 mCountingBuffer = new StaticIndexBuffer(mRenderer);
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000263 mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
264
265 UINT offset;
266 unsigned int *data = static_cast<unsigned int*>(mCountingBuffer->map(spaceNeeded, &offset));
267
268 if (data)
269 {
270 for(int i = 0; i < count; i++)
271 {
272 data[i] = i;
273 }
274
275 mCountingBuffer->unmap();
276 }
277 }
278 }
279 else return NULL;
280
281 return mCountingBuffer;
282}
283
daniel@transgaming.com6716a272012-10-31 18:31:39 +0000284IndexBuffer::IndexBuffer(renderer::Renderer *renderer, UINT size, D3DFORMAT format) : mRenderer(renderer), mBufferSize(size), mIndexBuffer(NULL)
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000285{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000286 if (size > 0)
287 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000288 // D3D9_REPLACE
daniel@transgaming.com6716a272012-10-31 18:31:39 +0000289 D3DPOOL pool = mRenderer->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
290 HRESULT result = mRenderer->getDevice()->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, pool, &mIndexBuffer, NULL);
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000291 mSerial = issueSerial();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000292
293 if (FAILED(result))
294 {
295 ERR("Out of memory allocating an index buffer of size %lu.", size);
296 }
297 }
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000298}
299
daniel@transgaming.com83921382011-01-08 05:46:00 +0000300IndexBuffer::~IndexBuffer()
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000301{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000302 if (mIndexBuffer)
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000303 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000304 mIndexBuffer->Release();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000305 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000306}
307
daniel@transgaming.com83921382011-01-08 05:46:00 +0000308IDirect3DIndexBuffer9 *IndexBuffer::getBuffer() const
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000309{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000310 return mIndexBuffer;
311}
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000312
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000313unsigned int IndexBuffer::getSerial() const
314{
315 return mSerial;
316}
317
318unsigned int IndexBuffer::issueSerial()
319{
320 return mCurrentSerial++;
321}
322
daniel@transgaming.com83921382011-01-08 05:46:00 +0000323void IndexBuffer::unmap()
324{
325 if (mIndexBuffer)
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000326 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000327 mIndexBuffer->Unlock();
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000328 }
daniel@transgaming.com83921382011-01-08 05:46:00 +0000329}
330
daniel@transgaming.com6716a272012-10-31 18:31:39 +0000331StreamingIndexBuffer::StreamingIndexBuffer(renderer::Renderer *renderer, UINT initialSize, D3DFORMAT format) : IndexBuffer(renderer, initialSize, format)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000332{
333 mWritePosition = 0;
334}
335
336StreamingIndexBuffer::~StreamingIndexBuffer()
337{
338}
339
340void *StreamingIndexBuffer::map(UINT requiredSpace, UINT *offset)
341{
342 void *mapPtr = NULL;
343
344 if (mIndexBuffer)
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000345 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000346 HRESULT result = mIndexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
347
348 if (FAILED(result))
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000349 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000350 ERR(" Lock failed with error 0x%08x", result);
351 return NULL;
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000352 }
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000353
daniel@transgaming.com83921382011-01-08 05:46:00 +0000354 *offset = mWritePosition;
355 mWritePosition += requiredSpace;
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000356 }
357
daniel@transgaming.com83921382011-01-08 05:46:00 +0000358 return mapPtr;
359}
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000360
daniel@transgaming.com83921382011-01-08 05:46:00 +0000361void StreamingIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
362{
363 if (requiredSpace > mBufferSize)
364 {
365 if (mIndexBuffer)
366 {
367 mIndexBuffer->Release();
368 mIndexBuffer = NULL;
369 }
370
371 mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
372
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000373 // D3D9_REPLACE
daniel@transgaming.com6716a272012-10-31 18:31:39 +0000374 D3DPOOL pool = mRenderer->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
375 HRESULT result = mRenderer->getDevice()->CreateIndexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000376 mSerial = issueSerial();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000377
378 if (FAILED(result))
379 {
380 ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
381 }
382
383 mWritePosition = 0;
384 }
385 else if (mWritePosition + requiredSpace > mBufferSize) // Recycle
386 {
387 void *dummy;
388 mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
389 mIndexBuffer->Unlock();
390
391 mWritePosition = 0;
392 }
393}
394
daniel@transgaming.com6716a272012-10-31 18:31:39 +0000395StaticIndexBuffer::StaticIndexBuffer(renderer::Renderer *renderer) : IndexBuffer(renderer, 0, D3DFMT_UNKNOWN)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000396{
397 mCacheType = GL_NONE;
398}
399
400StaticIndexBuffer::~StaticIndexBuffer()
401{
402}
403
404void *StaticIndexBuffer::map(UINT requiredSpace, UINT *offset)
405{
406 void *mapPtr = NULL;
407
408 if (mIndexBuffer)
409 {
410 HRESULT result = mIndexBuffer->Lock(0, requiredSpace, &mapPtr, 0);
411
412 if (FAILED(result))
413 {
414 ERR(" Lock failed with error 0x%08x", result);
415 return NULL;
416 }
417
418 *offset = 0;
419 }
420
421 return mapPtr;
422}
423
424void StaticIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
425{
426 if (!mIndexBuffer && mBufferSize == 0)
427 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000428 // D3D9_REPLACE
daniel@transgaming.com6716a272012-10-31 18:31:39 +0000429 D3DPOOL pool = mRenderer->getBufferPool(D3DUSAGE_WRITEONLY);
430 HRESULT result = mRenderer->getDevice()->CreateIndexBuffer(requiredSpace, D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000431 mSerial = issueSerial();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000432
433 if (FAILED(result))
434 {
435 ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
436 }
437
438 mBufferSize = requiredSpace;
439 mCacheType = type;
440 }
441 else if (mIndexBuffer && mBufferSize >= requiredSpace && mCacheType == type)
442 {
443 // Already allocated
444 }
445 else UNREACHABLE(); // Static index buffers can't be resized
446}
447
448bool StaticIndexBuffer::lookupType(GLenum type)
449{
450 return mCacheType == type;
451}
452
453UINT StaticIndexBuffer::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex)
454{
jbauman@chromium.org43cbe742011-09-01 22:09:40 +0000455 IndexRange range = {offset, count};
daniel@transgaming.com83921382011-01-08 05:46:00 +0000456
jbauman@chromium.org43cbe742011-09-01 22:09:40 +0000457 std::map<IndexRange, IndexResult>::iterator res = mCache.find(range);
458
459 if (res == mCache.end())
460 {
461 return -1;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000462 }
463
jbauman@chromium.org43cbe742011-09-01 22:09:40 +0000464 *minIndex = res->second.minIndex;
465 *maxIndex = res->second.maxIndex;
466 return res->second.streamOffset;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000467}
468
469void StaticIndexBuffer::addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset)
470{
jbauman@chromium.org43cbe742011-09-01 22:09:40 +0000471 IndexRange indexRange = {offset, count};
472 IndexResult indexResult = {minIndex, maxIndex, streamOffset};
473 mCache[indexRange] = indexResult;
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000474}
475
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000476}