diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp | 250 |
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 |