summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp296
1 files changed, 106 insertions, 190 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
index 932524c132..8d455b4bf3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -10,54 +9,20 @@
#include "libGLESv2/renderer/d3d/IndexDataManager.h"
#include "libGLESv2/renderer/d3d/BufferD3D.h"
-
+#include "libGLESv2/renderer/d3d/IndexBuffer.h"
+#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/main.h"
#include "libGLESv2/formatutils.h"
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
namespace rx
{
-IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer)
+static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
{
- mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
- if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
- {
- delete mStreamingBufferShort;
- mStreamingBufferShort = NULL;
- }
-
- mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
- if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
- {
- delete mStreamingBufferInt;
- mStreamingBufferInt = NULL;
- }
-
- if (!mStreamingBufferShort)
- {
- // Make sure both buffers are deleted.
- delete mStreamingBufferInt;
- mStreamingBufferInt = NULL;
-
- ERR("Failed to allocate the streaming index buffer(s).");
- }
-
- mCountingBuffer = NULL;
-}
-
-IndexDataManager::~IndexDataManager()
-{
- delete mStreamingBufferShort;
- delete mStreamingBufferInt;
- delete mCountingBuffer;
-}
-
-static void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
-{
- if (type == GL_UNSIGNED_BYTE)
+ if (sourceType == GL_UNSIGNED_BYTE)
{
+ ASSERT(destinationType == GL_UNSIGNED_SHORT);
const GLubyte *in = static_cast<const GLubyte*>(input);
GLushort *out = static_cast<GLushort*>(output);
@@ -66,55 +31,51 @@ static void convertIndices(GLenum type, const void *input, GLsizei count, void *
out[i] = in[i];
}
}
- else if (type == GL_UNSIGNED_INT)
+ else if (sourceType == GL_UNSIGNED_INT)
{
+ ASSERT(destinationType == GL_UNSIGNED_INT);
memcpy(output, input, count * sizeof(GLuint));
}
- else if (type == GL_UNSIGNED_SHORT)
+ else if (sourceType == GL_UNSIGNED_SHORT)
{
- memcpy(output, input, count * sizeof(GLushort));
+ if (destinationType == GL_UNSIGNED_SHORT)
+ {
+ memcpy(output, input, count * sizeof(GLushort));
+ }
+ else if (destinationType == GL_UNSIGNED_INT)
+ {
+ const GLushort *in = static_cast<const GLushort*>(input);
+ GLuint *out = static_cast<GLuint*>(output);
+
+ for (GLsizei i = 0; i < count; i++)
+ {
+ out[i] = in[i];
+ }
+ }
+ else UNREACHABLE();
}
else UNREACHABLE();
}
-template <class IndexType>
-static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+IndexDataManager::IndexDataManager(Renderer *renderer)
+ : mRenderer(renderer),
+ mStreamingBufferShort(NULL),
+ mStreamingBufferInt(NULL)
{
- *minIndex = indices[0];
- *maxIndex = indices[0];
-
- for (GLsizei i = 0; i < count; i++)
- {
- if (*minIndex > indices[i]) *minIndex = indices[i];
- if (*maxIndex < indices[i]) *maxIndex = indices[i];
- }
}
-static void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+IndexDataManager::~IndexDataManager()
{
- if (type == GL_UNSIGNED_BYTE)
- {
- computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
- }
- else if (type == GL_UNSIGNED_INT)
- {
- computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
- }
- else if (type == GL_UNSIGNED_SHORT)
- {
- computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
- }
- else UNREACHABLE();
+ SafeDelete(mStreamingBufferShort);
+ SafeDelete(mStreamingBufferInt);
}
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
+gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
{
- if (!mStreamingBufferShort)
- {
- return GL_OUT_OF_MEMORY;
- }
+ const gl::Type &typeInfo = gl::GetTypeInfo(type);
GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+
unsigned int offset = 0;
bool alignedOffset = false;
@@ -122,10 +83,6 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
if (buffer != NULL)
{
- if (reinterpret_cast<uintptr_t>(indices) > std::numeric_limits<unsigned int>::max())
- {
- return GL_OUT_OF_MEMORY;
- }
offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
storage = BufferD3D::makeBufferD3D(buffer->getImplementation());
@@ -138,59 +95,56 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
default: UNREACHABLE(); alignedOffset = false;
}
- unsigned int typeSize = gl::GetTypeBytes(type);
-
- // check for integer overflows
- if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeSize) ||
- typeSize * static_cast<unsigned int>(count) + offset < offset)
- {
- return GL_OUT_OF_MEMORY;
- }
-
- if (typeSize * static_cast<unsigned int>(count) + offset > storage->getSize())
- {
- return GL_INVALID_OPERATION;
- }
+ ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize());
indices = static_cast<const GLubyte*>(storage->getData()) + offset;
}
- StreamingIndexBufferInterface *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
-
StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL;
- IndexBufferInterface *indexBuffer = streamingBuffer;
+ IndexBufferInterface *indexBuffer = NULL;
bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() &&
destinationIndexType == type;
unsigned int streamOffset = 0;
if (directStorage)
{
- indexBuffer = streamingBuffer;
streamOffset = offset;
- if (!storage->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
- &translated->maxIndex, NULL))
+ if (!buffer->getIndexRangeCache()->findRange(type, offset, count, NULL, NULL))
{
- computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
- storage->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
- translated->maxIndex, offset);
+ buffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, offset);
}
}
else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset)
{
indexBuffer = staticBuffer;
- if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
- &translated->maxIndex, &streamOffset))
+ if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, NULL, &streamOffset))
{
- streamOffset = (offset / gl::GetTypeBytes(type)) * gl::GetTypeBytes(destinationIndexType);
- computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
- staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
- translated->maxIndex, streamOffset);
+ streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes;
+ staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
}
}
- else
+
+ // Avoid D3D11's primitive restart index value
+ // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
+ if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
{
+ destinationIndexType = GL_UNSIGNED_INT;
+ directStorage = false;
+ indexBuffer = NULL;
+ }
+
+ const gl::Type &destTypeInfo = gl::GetTypeInfo(destinationIndexType);
+
+ if (!directStorage && !indexBuffer)
+ {
+ gl::Error error = getStreamingIndexBuffer(destinationIndexType, &indexBuffer);
+ if (error.isError())
+ {
+ return error;
+ }
+
unsigned int convertCount = count;
if (staticBuffer)
@@ -198,7 +152,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
if (staticBuffer->getBufferSize() == 0 && alignedOffset)
{
indexBuffer = staticBuffer;
- convertCount = storage->getSize() / gl::GetTypeBytes(type);
+ convertCount = storage->getSize() / typeInfo.bytes;
}
else
{
@@ -207,133 +161,95 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
}
}
- if (!indexBuffer)
- {
- ERR("No valid index buffer.");
- return GL_INVALID_OPERATION;
- }
+ ASSERT(indexBuffer);
- unsigned int indexTypeSize = gl::GetTypeBytes(destinationIndexType);
- if (convertCount > std::numeric_limits<unsigned int>::max() / indexTypeSize)
+ if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes)
{
- ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, indexTypeSize);
- return GL_OUT_OF_MEMORY;
+ return gl::Error(GL_OUT_OF_MEMORY, "Reserving %u indices of %u bytes each exceeds the maximum buffer size.",
+ convertCount, destTypeInfo.bytes);
}
- unsigned int bufferSizeRequired = convertCount * indexTypeSize;
- if (!indexBuffer->reserveBufferSpace(bufferSizeRequired, type))
+ unsigned int bufferSizeRequired = convertCount * destTypeInfo.bytes;
+ error = indexBuffer->reserveBufferSpace(bufferSizeRequired, type);
+ if (error.isError())
{
- ERR("Failed to reserve %u bytes in an index buffer.", bufferSizeRequired);
- return GL_OUT_OF_MEMORY;
+ return error;
}
void* output = NULL;
- if (!indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset))
+ error = indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset);
+ if (error.isError())
{
- ERR("Failed to map index buffer.");
- return GL_OUT_OF_MEMORY;
+ return error;
}
- convertIndices(type, staticBuffer ? storage->getData() : indices, convertCount, output);
+ ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
- if (!indexBuffer->unmapBuffer())
+ error = indexBuffer->unmapBuffer();
+ if (error.isError())
{
- ERR("Failed to unmap index buffer.");
- return GL_OUT_OF_MEMORY;
+ return error;
}
- computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-
if (staticBuffer)
{
- streamOffset = (offset / gl::GetTypeBytes(type)) * gl::GetTypeBytes(destinationIndexType);
- staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
- translated->maxIndex, streamOffset);
+ streamOffset = (offset / typeInfo.bytes) * destTypeInfo.bytes;
+ staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
}
}
translated->storage = directStorage ? storage : NULL;
- translated->indexBuffer = indexBuffer->getIndexBuffer();
+ translated->indexBuffer = indexBuffer ? indexBuffer->getIndexBuffer() : NULL;
translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial();
- translated->startIndex = streamOffset / gl::GetTypeBytes(destinationIndexType);
+ translated->startIndex = streamOffset / destTypeInfo.bytes;
translated->startOffset = streamOffset;
+ translated->indexType = destinationIndexType;
if (storage)
{
- storage->promoteStaticUsage(count * gl::GetTypeBytes(type));
+ storage->promoteStaticUsage(count * typeInfo.bytes);
}
- return GL_NO_ERROR;
+ return gl::Error(GL_NO_ERROR);
}
-StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count)
+gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer)
{
- if (count <= 65536) // 16-bit indices
+ ASSERT(outBuffer);
+ if (destinationIndexType == GL_UNSIGNED_INT)
{
- const unsigned int spaceNeeded = count * sizeof(unsigned short);
-
- if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
+ if (!mStreamingBufferInt)
{
- delete mCountingBuffer;
- mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
- mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
-
- void* mappedMemory = NULL;
- if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
- {
- ERR("Failed to map counting buffer.");
- return NULL;
- }
-
- unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
- for(int i = 0; i < count; i++)
+ mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
+ gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+ if (error.isError())
{
- data[i] = i;
- }
-
- if (!mCountingBuffer->unmapBuffer())
- {
- ERR("Failed to unmap counting buffer.");
- return NULL;
+ SafeDelete(mStreamingBufferInt);
+ return error;
}
}
+
+ *outBuffer = mStreamingBufferInt;
+ return gl::Error(GL_NO_ERROR);
}
- else if (mStreamingBufferInt) // 32-bit indices supported
+ else
{
- const unsigned int spaceNeeded = count * sizeof(unsigned int);
+ ASSERT(destinationIndexType == GL_UNSIGNED_SHORT);
- if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
+ if (!mStreamingBufferShort)
{
- delete mCountingBuffer;
- mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
- mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
-
- void* mappedMemory = NULL;
- if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
+ mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
+ gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT);
+ if (error.isError())
{
- ERR("Failed to map counting buffer.");
- return NULL;
- }
-
- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
- for(int i = 0; i < count; i++)
- {
- data[i] = i;
- }
-
- if (!mCountingBuffer->unmapBuffer())
- {
- ERR("Failed to unmap counting buffer.");
- return NULL;
+ SafeDelete(mStreamingBufferShort);
+ return error;
}
}
- }
- else
- {
- return NULL;
- }
- return mCountingBuffer;
+ *outBuffer = mStreamingBufferShort;
+ return gl::Error(GL_NO_ERROR);
+ }
}
}