summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp250
1 files changed, 108 insertions, 142 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
index f1ba3d3db0..e974097b45 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
@@ -10,10 +10,12 @@
#include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "common/utilities.h"
-#include "libANGLE/renderer/d3d/BufferD3D.h"
-#include "libANGLE/renderer/d3d/IndexBuffer.h"
#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/VertexArray.h"
#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
namespace rx
{
@@ -76,11 +78,12 @@ void ConvertIndices(GLenum sourceType,
ConvertIndexArray<GLushort, GLuint>(input, sourceType, output, destinationType, count,
usePrimitiveRestartFixedIndex);
}
- else UNREACHABLE();
+ else
+ UNREACHABLE();
}
gl::Error StreamInIndexBuffer(IndexBufferInterface *buffer,
- const GLvoid *data,
+ const void *data,
unsigned int count,
GLenum srcType,
GLenum dstType,
@@ -91,50 +94,59 @@ gl::Error StreamInIndexBuffer(IndexBufferInterface *buffer,
if (count > (std::numeric_limits<unsigned int>::max() >> dstTypeInfo.bytesShift))
{
- return gl::Error(GL_OUT_OF_MEMORY,
- "Reserving %u indices of %u bytes each exceeds the maximum buffer size.",
- count, dstTypeInfo.bytes);
+ return gl::OutOfMemory() << "Reserving " << count << " indices of " << dstTypeInfo.bytes
+ << " bytes each exceeds the maximum buffer size.";
}
unsigned int bufferSizeRequired = count << dstTypeInfo.bytesShift;
- gl::Error error = buffer->reserveBufferSpace(bufferSizeRequired, dstType);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(buffer->reserveBufferSpace(bufferSizeRequired, dstType));
void *output = nullptr;
- error = buffer->mapBuffer(bufferSizeRequired, &output, offset);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(buffer->mapBuffer(bufferSizeRequired, &output, offset));
ConvertIndices(srcType, dstType, data, count, output, usePrimitiveRestartFixedIndex);
- error = buffer->unmapBuffer();
- if (error.isError())
+ ANGLE_TRY(buffer->unmapBuffer());
+ return gl::NoError();
+}
+
+unsigned int ElementTypeSize(GLenum elementType)
+{
+ switch (elementType)
{
- return error;
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ default:
+ UNREACHABLE();
+ return 0;
}
-
- return gl::Error(GL_NO_ERROR);
}
} // anonymous namespace
-IndexDataManager::IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass)
- : mFactory(factory),
- mRendererClass(rendererClass),
- mStreamingBufferShort(nullptr),
- mStreamingBufferInt(nullptr)
+bool IsOffsetAligned(GLenum elementType, unsigned int offset)
+{
+ return (offset % ElementTypeSize(elementType) == 0);
+}
+
+// IndexDataManager implementation.
+IndexDataManager::IndexDataManager(BufferFactoryD3D *factory)
+ : mFactory(factory), mStreamingBufferShort(), mStreamingBufferInt()
{
}
IndexDataManager::~IndexDataManager()
{
- SafeDelete(mStreamingBufferShort);
- SafeDelete(mStreamingBufferInt);
+}
+
+void IndexDataManager::deinitialize()
+{
+ mStreamingBufferShort.reset();
+ mStreamingBufferInt.reset();
}
// This function translates a GL-style indices into DX-style indices, with their description
@@ -143,43 +155,31 @@ IndexDataManager::~IndexDataManager()
// possible in DX and requires streaming (Case 1). If the GL indices are specified with a buffer
// (Case 2), in a format supported by DX (subcase a) then all is good.
// When we have a buffer with an unsupported format (subcase b) then we need to do some translation:
-// we will start by falling back to streaming, and after a while will start using a static translated
-// copy of the index buffer.
-gl::Error IndexDataManager::prepareIndexData(GLenum srcType,
+// we will start by falling back to streaming, and after a while will start using a static
+// translated copy of the index buffer.
+gl::Error IndexDataManager::prepareIndexData(const gl::Context *context,
+ GLenum srcType,
+ GLenum dstType,
GLsizei count,
gl::Buffer *glBuffer,
- const GLvoid *indices,
- TranslatedIndexData *translated,
- bool primitiveRestartFixedIndexEnabled)
+ const void *indices,
+ TranslatedIndexData *translated)
{
- // Avoid D3D11's primitive restart index value
- // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
- bool hasPrimitiveRestartIndex =
- translated->indexRange.vertexIndexCount < static_cast<size_t>(count) ||
- translated->indexRange.end == gl::GetPrimitiveRestartIndex(srcType);
- bool primitiveRestartWorkaround = mRendererClass == RENDERER_D3D11 &&
- !primitiveRestartFixedIndexEnabled &&
- hasPrimitiveRestartIndex && srcType == GL_UNSIGNED_SHORT;
-
- // We should never have to deal with MAX_UINT indices, since we restrict it via
- // MAX_ELEMENT_INDEX.
- ASSERT(!(mRendererClass == RENDERER_D3D11 && !primitiveRestartFixedIndexEnabled &&
- hasPrimitiveRestartIndex && srcType == GL_UNSIGNED_INT));
-
- const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround) ?
- GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
-
const gl::Type &srcTypeInfo = gl::GetTypeInfo(srcType);
const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType);
BufferD3D *buffer = glBuffer ? GetImplAs<BufferD3D>(glBuffer) : nullptr;
- translated->indexType = dstType;
+ translated->indexType = dstType;
translated->srcIndexData.srcBuffer = buffer;
translated->srcIndexData.srcIndices = indices;
translated->srcIndexData.srcIndexType = srcType;
translated->srcIndexData.srcCount = count;
+ // Context can be nullptr in perf tests.
+ bool primitiveRestartFixedIndexEnabled =
+ context ? context->getGLState().isPrimitiveRestartEnabled() : false;
+
// Case 1: the indices are passed by pointer, which forces the streaming of index data
if (glBuffer == nullptr)
{
@@ -192,95 +192,69 @@ gl::Error IndexDataManager::prepareIndexData(GLenum srcType,
unsigned int offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
ASSERT(srcTypeInfo.bytes * static_cast<unsigned int>(count) + offset <= buffer->getSize());
- bool offsetAligned;
- switch (srcType)
- {
- case GL_UNSIGNED_BYTE: offsetAligned = (offset % sizeof(GLubyte) == 0); break;
- case GL_UNSIGNED_SHORT: offsetAligned = (offset % sizeof(GLushort) == 0); break;
- case GL_UNSIGNED_INT: offsetAligned = (offset % sizeof(GLuint) == 0); break;
- default: UNREACHABLE(); offsetAligned = false;
- }
+ bool offsetAligned = IsOffsetAligned(srcType, offset);
// Case 2a: the buffer can be used directly
- if (offsetAligned && buffer->supportsDirectBinding() &&
- dstType == srcType && !primitiveRestartWorkaround)
+ if (offsetAligned && buffer->supportsDirectBinding() && dstType == srcType)
{
- translated->storage = buffer;
+ translated->storage = buffer;
translated->indexBuffer = nullptr;
- translated->serial = buffer->getSerial();
- translated->startIndex = (offset >> srcTypeInfo.bytesShift);
+ translated->serial = buffer->getSerial();
+ translated->startIndex = (offset >> srcTypeInfo.bytesShift);
translated->startOffset = offset;
- buffer->promoteStaticUsage(count << srcTypeInfo.bytesShift);
- return gl::Error(GL_NO_ERROR);
- }
- else
- {
- translated->storage = nullptr;
+ return gl::NoError();
}
+ translated->storage = nullptr;
+
// Case 2b: use a static translated copy or fall back to streaming
StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer();
bool staticBufferInitialized = staticBuffer && staticBuffer->getBufferSize() != 0;
- bool staticBufferUsable = staticBuffer &&
- offsetAligned && staticBuffer->getIndexType() == dstType;
+ bool staticBufferUsable =
+ staticBuffer && offsetAligned && staticBuffer->getIndexType() == dstType;
if (staticBufferInitialized && !staticBufferUsable)
{
- buffer->invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE);
+ buffer->invalidateStaticData(context);
staticBuffer = nullptr;
}
if (staticBuffer == nullptr || !offsetAligned)
{
const uint8_t *bufferData = nullptr;
- gl::Error error = buffer->getData(&bufferData);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(buffer->getData(context, &bufferData));
ASSERT(bufferData != nullptr);
- error = streamIndexData(bufferData + offset, count, srcType, dstType,
- primitiveRestartFixedIndexEnabled, translated);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(streamIndexData(bufferData + offset, count, srcType, dstType,
+ primitiveRestartFixedIndexEnabled, translated));
+ buffer->promoteStaticUsage(context, count << srcTypeInfo.bytesShift);
}
else
{
if (!staticBufferInitialized)
{
const uint8_t *bufferData = nullptr;
- gl::Error error = buffer->getData(&bufferData);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(buffer->getData(context, &bufferData));
ASSERT(bufferData != nullptr);
unsigned int convertCount =
static_cast<unsigned int>(buffer->getSize()) >> srcTypeInfo.bytesShift;
- error = StreamInIndexBuffer(staticBuffer, bufferData, convertCount, srcType, dstType,
- primitiveRestartFixedIndexEnabled, nullptr);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(StreamInIndexBuffer(staticBuffer, bufferData, convertCount, srcType, dstType,
+ primitiveRestartFixedIndexEnabled, nullptr));
}
ASSERT(offsetAligned && staticBuffer->getIndexType() == dstType);
translated->indexBuffer = staticBuffer->getIndexBuffer();
- translated->serial = staticBuffer->getSerial();
- translated->startIndex = (offset >> srcTypeInfo.bytesShift);
+ translated->serial = staticBuffer->getSerial();
+ translated->startIndex = (offset >> srcTypeInfo.bytesShift);
translated->startOffset = (offset >> srcTypeInfo.bytesShift) << dstTypeInfo.bytesShift;
}
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
-gl::Error IndexDataManager::streamIndexData(const GLvoid *data,
+gl::Error IndexDataManager::streamIndexData(const void *data,
unsigned int count,
GLenum srcType,
GLenum dstType,
@@ -290,65 +264,57 @@ gl::Error IndexDataManager::streamIndexData(const GLvoid *data,
const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType);
IndexBufferInterface *indexBuffer = nullptr;
- gl::Error error = getStreamingIndexBuffer(dstType, &indexBuffer);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(getStreamingIndexBuffer(dstType, &indexBuffer));
ASSERT(indexBuffer != nullptr);
unsigned int offset;
- StreamInIndexBuffer(indexBuffer, data, count, srcType, dstType, usePrimitiveRestartFixedIndex,
- &offset);
+ ANGLE_TRY(StreamInIndexBuffer(indexBuffer, data, count, srcType, dstType,
+ usePrimitiveRestartFixedIndex, &offset));
translated->indexBuffer = indexBuffer->getIndexBuffer();
- translated->serial = indexBuffer->getSerial();
- translated->startIndex = (offset >> dstTypeInfo.bytesShift);
+ translated->serial = indexBuffer->getSerial();
+ translated->startIndex = (offset >> dstTypeInfo.bytesShift);
translated->startOffset = offset;
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType,
IndexBufferInterface **outBuffer)
{
ASSERT(outBuffer);
- if (destinationIndexType == GL_UNSIGNED_INT)
- {
- if (!mStreamingBufferInt)
- {
- mStreamingBufferInt = new StreamingIndexBufferInterface(mFactory);
- gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE,
- GL_UNSIGNED_INT);
- if (error.isError())
- {
- SafeDelete(mStreamingBufferInt);
- return error;
- }
- }
+ ASSERT(destinationIndexType == GL_UNSIGNED_SHORT || destinationIndexType == GL_UNSIGNED_INT);
- *outBuffer = mStreamingBufferInt;
- return gl::Error(GL_NO_ERROR);
- }
- else
+ auto &streamingBuffer =
+ (destinationIndexType == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
+
+ if (!streamingBuffer)
{
- ASSERT(destinationIndexType == GL_UNSIGNED_SHORT);
+ StreamingBuffer newBuffer(new StreamingIndexBufferInterface(mFactory));
+ ANGLE_TRY(newBuffer->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, destinationIndexType));
+ streamingBuffer = std::move(newBuffer);
+ }
- if (!mStreamingBufferShort)
+ *outBuffer = streamingBuffer.get();
+ return gl::NoError();
+}
+
+GLenum GetIndexTranslationDestType(GLenum srcType,
+ const gl::HasIndexRange &lazyIndexRange,
+ bool usePrimitiveRestartWorkaround)
+{
+ // Avoid D3D11's primitive restart index value
+ // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
+ if (usePrimitiveRestartWorkaround)
+ {
+ const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value();
+ if (indexRange.end == gl::GetPrimitiveRestartIndex(srcType))
{
- mStreamingBufferShort = new StreamingIndexBufferInterface(mFactory);
- gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE,
- GL_UNSIGNED_SHORT);
- if (error.isError())
- {
- SafeDelete(mStreamingBufferShort);
- return error;
- }
+ return GL_UNSIGNED_INT;
}
-
- *outBuffer = mStreamingBufferShort;
- return gl::Error(GL_NO_ERROR);
}
-}
+ return (srcType == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
}
+
+} // namespace rx