blob: 99f2f2653d24b7b010e568915fc46f35733cf4cb [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00002//
Nicolas Capens8d62bcc2014-07-25 15:08:21 -04003// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
daniel@transgaming.com8fd34bd2011-02-18 02:52:14 +00008// IndexDataManager.cpp: Defines the IndexDataManager, a class that
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00009// runs the Buffer translation process for index buffers.
10
Brandon Jonesc7a41042014-06-23 12:03:25 -070011#include "libGLESv2/renderer/d3d/IndexDataManager.h"
Brandon Jonesd38f9262014-06-18 16:26:45 -070012#include "libGLESv2/renderer/d3d/BufferD3D.h"
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000013
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000014#include "libGLESv2/Buffer.h"
daniel@transgaming.com37b141e2011-01-08 05:46:13 +000015#include "libGLESv2/main.h"
Geoff Langf23eb282013-07-22 10:52:19 -040016#include "libGLESv2/formatutils.h"
Brandon Jonesc7a41042014-06-23 12:03:25 -070017#include "libGLESv2/renderer/d3d/IndexBuffer.h"
Nicolas Capens8d62bcc2014-07-25 15:08:21 -040018#include "libGLESv2/renderer/Renderer.h"
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000019
daniel@transgaming.com31240482012-11-28 21:06:41 +000020namespace rx
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000021{
22
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000023IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000024{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000025 mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
26 if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000027 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000028 delete mStreamingBufferShort;
29 mStreamingBufferShort = NULL;
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000030 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000031
32 mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
33 if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000034 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000035 delete mStreamingBufferInt;
daniel@transgaming.com83921382011-01-08 05:46:00 +000036 mStreamingBufferInt = NULL;
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000037 }
daniel@transgaming.com72b9e182011-04-13 14:58:33 +000038
39 if (!mStreamingBufferShort)
40 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000041 // Make sure both buffers are deleted.
42 delete mStreamingBufferInt;
43 mStreamingBufferInt = NULL;
44
daniel@transgaming.com72b9e182011-04-13 14:58:33 +000045 ERR("Failed to allocate the streaming index buffer(s).");
46 }
daniel@transgaming.comf6549452012-01-27 15:39:08 +000047
48 mCountingBuffer = NULL;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000049}
50
51IndexDataManager::~IndexDataManager()
52{
daniel@transgaming.com83921382011-01-08 05:46:00 +000053 delete mStreamingBufferShort;
54 delete mStreamingBufferInt;
daniel@transgaming.comf6549452012-01-27 15:39:08 +000055 delete mCountingBuffer;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000056}
57
Nicolas Capens8d62bcc2014-07-25 15:08:21 -040058static void convertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000059{
Nicolas Capens8d62bcc2014-07-25 15:08:21 -040060 if (sourceType == GL_UNSIGNED_BYTE)
daniel@transgaming.com83921382011-01-08 05:46:00 +000061 {
Nicolas Capens8d62bcc2014-07-25 15:08:21 -040062 ASSERT(destinationType == GL_UNSIGNED_SHORT);
daniel@transgaming.com83921382011-01-08 05:46:00 +000063 const GLubyte *in = static_cast<const GLubyte*>(input);
64 GLushort *out = static_cast<GLushort*>(output);
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000065
daniel@transgaming.com83921382011-01-08 05:46:00 +000066 for (GLsizei i = 0; i < count; i++)
67 {
68 out[i] = in[i];
69 }
70 }
Nicolas Capens8d62bcc2014-07-25 15:08:21 -040071 else if (sourceType == GL_UNSIGNED_INT)
daniel@transgaming.com83921382011-01-08 05:46:00 +000072 {
Nicolas Capens8d62bcc2014-07-25 15:08:21 -040073 ASSERT(destinationType == GL_UNSIGNED_INT);
daniel@transgaming.com83921382011-01-08 05:46:00 +000074 memcpy(output, input, count * sizeof(GLuint));
75 }
Nicolas Capens8d62bcc2014-07-25 15:08:21 -040076 else if (sourceType == GL_UNSIGNED_SHORT)
daniel@transgaming.com83921382011-01-08 05:46:00 +000077 {
Nicolas Capens8d62bcc2014-07-25 15:08:21 -040078 if (destinationType == GL_UNSIGNED_SHORT)
79 {
80 memcpy(output, input, count * sizeof(GLushort));
81 }
82 else if (destinationType == GL_UNSIGNED_INT)
83 {
84 const GLushort *in = static_cast<const GLushort*>(input);
85 GLuint *out = static_cast<GLuint*>(output);
86
87 for (GLsizei i = 0; i < count; i++)
88 {
89 out[i] = in[i];
90 }
91 }
92 else UNREACHABLE();
daniel@transgaming.com83921382011-01-08 05:46:00 +000093 }
94 else UNREACHABLE();
95}
96
97template <class IndexType>
Jamie Madill39b43462014-08-18 16:39:50 -040098static RangeUI computeRange(const IndexType *indices, GLsizei count)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000099{
Jamie Madill39b43462014-08-18 16:39:50 -0400100 unsigned int minIndex = indices[0];
101 unsigned int maxIndex = indices[0];
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000102
Jamie Madill39b43462014-08-18 16:39:50 -0400103 for (GLsizei i = 1; i < count; i++)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000104 {
Jamie Madill39b43462014-08-18 16:39:50 -0400105 if (minIndex > indices[i]) minIndex = indices[i];
106 if (maxIndex < indices[i]) maxIndex = indices[i];
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000107 }
Jamie Madill39b43462014-08-18 16:39:50 -0400108
109 return RangeUI(minIndex, maxIndex);
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000110}
111
Jamie Madill39b43462014-08-18 16:39:50 -0400112static RangeUI computeRange(GLenum type, const GLvoid *indices, GLsizei count)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000113{
Jamie Madill39b43462014-08-18 16:39:50 -0400114 switch (type)
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000115 {
Jamie Madill39b43462014-08-18 16:39:50 -0400116 case GL_UNSIGNED_BYTE:
117 return computeRange(static_cast<const GLubyte*>(indices), count);
118 case GL_UNSIGNED_INT:
119 return computeRange(static_cast<const GLuint*>(indices), count);
120 case GL_UNSIGNED_SHORT:
121 return computeRange(static_cast<const GLushort*>(indices), count);
122 default:
123 UNREACHABLE();
124 return RangeUI();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000125 }
daniel@transgaming.com83921382011-01-08 05:46:00 +0000126}
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000127
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000128GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000129{
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000130 if (!mStreamingBufferShort)
131 {
132 return GL_OUT_OF_MEMORY;
133 }
134
Geoff Lang5d601382014-07-22 15:14:06 -0400135 const gl::Type &typeInfo = gl::GetTypeInfo(type);
136
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000137 GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
Geoff Lang5d601382014-07-22 15:14:06 -0400138
Geoff Langb23fc092013-08-06 10:43:14 -0400139 unsigned int offset = 0;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000140 bool alignedOffset = false;
141
Brandon Jonesd38f9262014-06-18 16:26:45 -0700142 BufferD3D *storage = NULL;
shannon.woods@transgaming.coma1229a32013-02-28 23:08:40 +0000143
daniel@transgaming.com83921382011-01-08 05:46:00 +0000144 if (buffer != NULL)
145 {
Geoff Langb23fc092013-08-06 10:43:14 -0400146 if (reinterpret_cast<uintptr_t>(indices) > std::numeric_limits<unsigned int>::max())
147 {
148 return GL_OUT_OF_MEMORY;
149 }
150 offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
151
Brandon Jonesd38f9262014-06-18 16:26:45 -0700152 storage = BufferD3D::makeBufferD3D(buffer->getImplementation());
shannon.woods@transgaming.com76655412013-02-28 23:08:09 +0000153
daniel@transgaming.com83921382011-01-08 05:46:00 +0000154 switch (type)
155 {
156 case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
157 case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
158 case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;
159 default: UNREACHABLE(); alignedOffset = false;
160 }
161
Geoff Langfdf06942013-08-06 10:41:05 -0400162 // check for integer overflows
Geoff Lang5d601382014-07-22 15:14:06 -0400163 if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeInfo.bytes) ||
164 typeInfo.bytes * static_cast<unsigned int>(count) + offset < offset)
Geoff Langa36ead42013-08-02 11:54:08 -0400165 {
166 return GL_OUT_OF_MEMORY;
167 }
168
Geoff Lang5d601382014-07-22 15:14:06 -0400169 if (typeInfo.bytes * static_cast<unsigned int>(count) + offset > storage->getSize())
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000170 {
171 return GL_INVALID_OPERATION;
172 }
173
shannon.woods@transgaming.com76655412013-02-28 23:08:09 +0000174 indices = static_cast<const GLubyte*>(storage->getData()) + offset;
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000175 }
176
Brandon Jonesd38f9262014-06-18 16:26:45 -0700177 StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL;
Nicolas Capens8d62bcc2014-07-25 15:08:21 -0400178 IndexBufferInterface *indexBuffer = NULL;
shannon.woods@transgaming.coma1229a32013-02-28 23:08:40 +0000179 bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() &&
180 destinationIndexType == type;
Geoff Langa36ead42013-08-02 11:54:08 -0400181 unsigned int streamOffset = 0;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000182
shannon.woods@transgaming.coma1229a32013-02-28 23:08:40 +0000183 if (directStorage)
184 {
shannon.woods@transgaming.coma1229a32013-02-28 23:08:40 +0000185 streamOffset = offset;
Geoff Langf23eb282013-07-22 10:52:19 -0400186
Jamie Madillef9d63e2014-08-04 10:48:02 -0400187 if (!buffer->getIndexRangeCache()->findRange(type, offset, count, &translated->indexRange, NULL))
Geoff Langf23eb282013-07-22 10:52:19 -0400188 {
Jamie Madill39b43462014-08-18 16:39:50 -0400189 translated->indexRange = computeRange(type, indices, count);
Jamie Madillef9d63e2014-08-04 10:48:02 -0400190 buffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, offset);
Geoff Langf23eb282013-07-22 10:52:19 -0400191 }
shannon.woods@transgaming.coma1229a32013-02-28 23:08:40 +0000192 }
shannon.woods@transgaming.com38e87882013-02-28 23:18:32 +0000193 else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset)
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000194 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000195 indexBuffer = staticBuffer;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000196
Jamie Madill39b43462014-08-18 16:39:50 -0400197 if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->indexRange, &streamOffset))
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000198 {
Geoff Lang5d601382014-07-22 15:14:06 -0400199 streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes;
Jamie Madill39b43462014-08-18 16:39:50 -0400200 translated->indexRange = computeRange(type, indices, count);
201 staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000202 }
203 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000204 else
205 {
Jamie Madill39b43462014-08-18 16:39:50 -0400206 translated->indexRange = computeRange(type, indices, count);
Nicolas Capens8d62bcc2014-07-25 15:08:21 -0400207 }
208
209 // Avoid D3D11's primitive restart index value
210 // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
Jamie Madill39b43462014-08-18 16:39:50 -0400211 if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
Nicolas Capens8d62bcc2014-07-25 15:08:21 -0400212 {
213 destinationIndexType = GL_UNSIGNED_INT;
214 directStorage = false;
215 indexBuffer = NULL;
216 }
217
Geoff Lang5d601382014-07-22 15:14:06 -0400218 const gl::Type &destTypeInfo = gl::GetTypeInfo(destinationIndexType);
219
Nicolas Capens8d62bcc2014-07-25 15:08:21 -0400220 if (!directStorage && !indexBuffer)
221 {
222 indexBuffer = (destinationIndexType == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
223
Geoff Langa36ead42013-08-02 11:54:08 -0400224 unsigned int convertCount = count;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000225
daniel@transgaming.com83921382011-01-08 05:46:00 +0000226 if (staticBuffer)
227 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000228 if (staticBuffer->getBufferSize() == 0 && alignedOffset)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000229 {
230 indexBuffer = staticBuffer;
Geoff Lang5d601382014-07-22 15:14:06 -0400231 convertCount = storage->getSize() / typeInfo.bytes;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000232 }
233 else
234 {
Brandon Jonesd38f9262014-06-18 16:26:45 -0700235 storage->invalidateStaticData();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000236 staticBuffer = NULL;
237 }
238 }
239
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000240 if (!indexBuffer)
daniel@transgaming.com5ee2ad02011-01-08 05:46:20 +0000241 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000242 ERR("No valid index buffer.");
243 return GL_INVALID_OPERATION;
daniel@transgaming.com5ee2ad02011-01-08 05:46:20 +0000244 }
daniel@transgaming.com50aadb02012-11-28 21:06:11 +0000245
Geoff Lang5d601382014-07-22 15:14:06 -0400246 if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes)
Geoff Langa36ead42013-08-02 11:54:08 -0400247 {
Geoff Lang5d601382014-07-22 15:14:06 -0400248 ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, destTypeInfo.bytes);
Geoff Langa36ead42013-08-02 11:54:08 -0400249 return GL_OUT_OF_MEMORY;
250 }
251
Geoff Lang5d601382014-07-22 15:14:06 -0400252 unsigned int bufferSizeRequired = convertCount * destTypeInfo.bytes;
Geoff Langa36ead42013-08-02 11:54:08 -0400253 if (!indexBuffer->reserveBufferSpace(bufferSizeRequired, type))
254 {
255 ERR("Failed to reserve %u bytes in an index buffer.", bufferSizeRequired);
256 return GL_OUT_OF_MEMORY;
257 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000258
259 void* output = NULL;
Geoff Langa36ead42013-08-02 11:54:08 -0400260 if (!indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset))
daniel@transgaming.com83921382011-01-08 05:46:00 +0000261 {
262 ERR("Failed to map index buffer.");
263 return GL_OUT_OF_MEMORY;
264 }
265
Nicolas Capens8d62bcc2014-07-25 15:08:21 -0400266 convertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000267
268 if (!indexBuffer->unmapBuffer())
269 {
270 ERR("Failed to unmap index buffer.");
271 return GL_OUT_OF_MEMORY;
272 }
daniel@transgaming.com83921382011-01-08 05:46:00 +0000273
daniel@transgaming.com83921382011-01-08 05:46:00 +0000274 if (staticBuffer)
275 {
Geoff Lang5d601382014-07-22 15:14:06 -0400276 streamOffset = (offset / typeInfo.bytes) * destTypeInfo.bytes;
Jamie Madill39b43462014-08-18 16:39:50 -0400277 staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
daniel@transgaming.com83921382011-01-08 05:46:00 +0000278 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000279 }
280
shannon.woods@transgaming.coma1229a32013-02-28 23:08:40 +0000281 translated->storage = directStorage ? storage : NULL;
Nicolas Capens8d62bcc2014-07-25 15:08:21 -0400282 translated->indexBuffer = indexBuffer ? indexBuffer->getIndexBuffer() : NULL;
shannon.woods@transgaming.coma1229a32013-02-28 23:08:40 +0000283 translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial();
Geoff Lang5d601382014-07-22 15:14:06 -0400284 translated->startIndex = streamOffset / destTypeInfo.bytes;
daniel@transgaming.com22ada2c2013-01-11 04:07:12 +0000285 translated->startOffset = streamOffset;
Nicolas Capens8d62bcc2014-07-25 15:08:21 -0400286 translated->indexType = destinationIndexType;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000287
Brandon Jonesd38f9262014-06-18 16:26:45 -0700288 if (storage)
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000289 {
Geoff Lang5d601382014-07-22 15:14:06 -0400290 storage->promoteStaticUsage(count * typeInfo.bytes);
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000291 }
292
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000293 return GL_NO_ERROR;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000294}
295
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000296StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count)
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000297{
daniel@transgaming.com0f328a72012-03-05 15:07:50 +0000298 if (count <= 65536) // 16-bit indices
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000299 {
300 const unsigned int spaceNeeded = count * sizeof(unsigned short);
301
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000302 if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000303 {
304 delete mCountingBuffer;
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000305 mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000306 mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000307
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000308 void* mappedMemory = NULL;
Geoff Langa36ead42013-08-02 11:54:08 -0400309 if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000310 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000311 ERR("Failed to map counting buffer.");
312 return NULL;
313 }
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000314
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000315 unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
316 for(int i = 0; i < count; i++)
317 {
318 data[i] = i;
319 }
320
321 if (!mCountingBuffer->unmapBuffer())
322 {
323 ERR("Failed to unmap counting buffer.");
324 return NULL;
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000325 }
326 }
327 }
328 else if (mStreamingBufferInt) // 32-bit indices supported
329 {
330 const unsigned int spaceNeeded = count * sizeof(unsigned int);
331
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000332 if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000333 {
334 delete mCountingBuffer;
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000335 mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000336 mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000337
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000338 void* mappedMemory = NULL;
Geoff Langa36ead42013-08-02 11:54:08 -0400339 if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000340 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000341 ERR("Failed to map counting buffer.");
342 return NULL;
343 }
daniel@transgaming.com50aadb02012-11-28 21:06:11 +0000344
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000345 unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
346 for(int i = 0; i < count; i++)
347 {
348 data[i] = i;
349 }
350
351 if (!mCountingBuffer->unmapBuffer())
352 {
353 ERR("Failed to unmap counting buffer.");
354 return NULL;
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000355 }
356 }
357 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000358 else
359 {
360 return NULL;
361 }
daniel@transgaming.com50aadb02012-11-28 21:06:11 +0000362
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000363 return mCountingBuffer;
364}
365
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000366}