From a218a252c4200cfe7048de81a46f7e48349084d5 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 8 Apr 2015 17:04:36 +0300 Subject: Upgrade ANGLE to 2.1~99f075dade7c This aligns with Chromium branch 2356. This version brings more complete OpenGL ES 3 support as well as various bug fixes and performance improvements. The following changes were made to earlier patches: -0000-General-fixes-for-ANGLE-2.1 Removed. All changes are now handled elsewhere. +0001-ANGLE-Improve-Windows-Phone-support Consolidated remaining parts from 0009/0010. +0002-ANGLE-Fix-compilation-with-MinGW Remaining issues from patch 0016. +0003-ANGLE-Fix-compilation-with-MSVC2010 Remaining issues from patch 0015. +0004-ANGLE-Dynamically-load-D3D-compiler-from-list Renamed from patch 0008. +0005-ANGLE-Add-support-for-querying-platform-device Renamed from patch 0013. -0004-Make-it-possible-to-link-ANGLE-statically-for-single Removed. Fixed by adding defines to project files. -0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t Renamed to patch 0005. -0009-ANGLE-Support-WinRT Removed. Mostly fixed upstream; remaining parts in patch 0001. -0010-ANGLE-Enable-D3D11-for-feature-level-9-cards Removed. Mostly fixed upstream; remaining parts in patch 0001. -0012-ANGLE-fix-semantic-index-lookup Removed. Fixed upstream. -0013-ANGLE-Add-support-for-querying-platform-device Renamed to patch 0005. -0014-Let-ANGLE-use-multithreaded-devices-if-necessary Removed. No longer needed. -0015-ANGLE-Fix-angle-d3d11-on-MSVC2010 Moved remaining parts to patch 0003. -0016-ANGLE-Fix-compilation-with-MinGW-D3D11 Moved remaining parts to patch 0002. -0017-ANGLE-Fix-compilation-with-D3D9 Removed. Fixed upstream. -0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11 Removed. Fixed upstream. -0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt Removed. Fixed upstream. -0020-ANGLE-Do-not-use-std-strlen Removed. Fixed upstream. -0020-ANGLE-Fix-compilation-with-MSVC2013-Update4 Removed. Fixed upstream. [ChangeLog][Third-party libraries] ANGLE was updated to Chromium branch 2356 (2.1~99f075dade7c). Change-Id: I32ccbfe95e10986bd94be7191dfd53445ea09158 Task-number: QTBUG-44815 Task-number: QTBUG-37660 Task-number: QTBUG-44694 Task-number: QTBUG-42443 Reviewed-by: Andrew Knight Reviewed-by: Friedemann Kleint --- .../src/libANGLE/renderer/d3d/VertexBuffer.cpp | 311 +++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp') diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp new file mode 100644 index 0000000000..19bd548fce --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp @@ -0,0 +1,311 @@ +// +// Copyright (c) 2002-2012 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. +// + +// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface +// class with derivations, classes that perform graphics API agnostic vertex buffer operations. + +#include "libANGLE/renderer/d3d/VertexBuffer.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/VertexAttribute.h" + +#include "common/mathutil.h" + +namespace rx +{ + +unsigned int VertexBuffer::mNextSerial = 1; + +VertexBuffer::VertexBuffer() +{ + updateSerial(); +} + +VertexBuffer::~VertexBuffer() +{ +} + +void VertexBuffer::updateSerial() +{ + mSerial = mNextSerial++; +} + +unsigned int VertexBuffer::getSerial() const +{ + return mSerial; +} + +VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic) + : mFactory(factory) +{ + mDynamic = dynamic; + mWritePosition = 0; + mReservedSpace = 0; + + mVertexBuffer = factory->createVertexBuffer(); +} + +VertexBufferInterface::~VertexBufferInterface() +{ + delete mVertexBuffer; +} + +unsigned int VertexBufferInterface::getSerial() const +{ + return mVertexBuffer->getSerial(); +} + +unsigned int VertexBufferInterface::getBufferSize() const +{ + return mVertexBuffer->getBufferSize(); +} + +gl::Error VertexBufferInterface::setBufferSize(unsigned int size) +{ + if (mVertexBuffer->getBufferSize() == 0) + { + return mVertexBuffer->initialize(size, mDynamic); + } + else + { + return mVertexBuffer->setBufferSize(size); + } +} + +unsigned int VertexBufferInterface::getWritePosition() const +{ + return mWritePosition; +} + +void VertexBufferInterface::setWritePosition(unsigned int writePosition) +{ + mWritePosition = writePosition; +} + +gl::Error VertexBufferInterface::discard() +{ + return mVertexBuffer->discard(); +} + +gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) +{ + gl::Error error(GL_NO_ERROR); + + unsigned int spaceRequired; + error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired); + if (error.isError()) + { + return error; + } + + if (mWritePosition + spaceRequired < mWritePosition) + { + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow."); + } + + error = reserveSpace(mReservedSpace); + if (error.isError()) + { + return error; + } + mReservedSpace = 0; + + error = mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition); + if (error.isError()) + { + return error; + } + + if (outStreamOffset) + { + *outStreamOffset = mWritePosition; + } + + mWritePosition += spaceRequired; + + // Align to 16-byte boundary + mWritePosition = roundUp(mWritePosition, 16u); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) +{ + gl::Error error(GL_NO_ERROR); + + unsigned int requiredSpace; + error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace); + if (error.isError()) + { + return error; + } + + // Protect against integer overflow + if (mReservedSpace + requiredSpace < mReservedSpace) + { + return gl::Error(GL_OUT_OF_MEMORY, "Unable to reserve %u extra bytes in internal vertex buffer, " + "it would result in an overflow.", requiredSpace); + } + + mReservedSpace += requiredSpace; + + // Align to 16-byte boundary + mReservedSpace = roundUp(mReservedSpace, 16u); + + return gl::Error(GL_NO_ERROR); +} + +VertexBuffer* VertexBufferInterface::getVertexBuffer() const +{ + return mVertexBuffer; +} + +bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue) const +{ + gl::Buffer *buffer = attrib.buffer.get(); + BufferD3D *storage = buffer ? GetImplAs(buffer) : NULL; + + if (!storage || !storage->supportsDirectBinding()) + { + return false; + } + + // Alignment restrictions: In D3D, vertex data must be aligned to + // the format stride, or to a 4-byte boundary, whichever is smaller. + // (Undocumented, and experimentally confirmed) + size_t alignment = 4; + bool requiresConversion = false; + + if (attrib.type != GL_FLOAT) + { + gl::VertexFormat vertexFormat(attrib, currentValue.Type); + + unsigned int outputElementSize; + getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); + alignment = std::min(outputElementSize, 4); + + // TODO(jmadill): add VertexFormatCaps + requiresConversion = (mFactory->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0; + } + + bool isAligned = (static_cast(ComputeVertexAttributeStride(attrib)) % alignment == 0) && + (static_cast(attrib.offset) % alignment == 0); + + return !requiresConversion && isAligned; +} + +StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize) + : VertexBufferInterface(factory, true) +{ + setBufferSize(initialSize); +} + +StreamingVertexBufferInterface::~StreamingVertexBufferInterface() +{ +} + +gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size) +{ + unsigned int curBufferSize = getBufferSize(); + if (size > curBufferSize) + { + gl::Error error = setBufferSize(std::max(size, 3 * curBufferSize / 2)); + if (error.isError()) + { + return error; + } + setWritePosition(0); + } + else if (getWritePosition() + size > curBufferSize) + { + gl::Error error = discard(); + if (error.isError()) + { + return error; + } + setWritePosition(0); + } + + return gl::Error(GL_NO_ERROR); +} + +StaticVertexBufferInterface::StaticVertexBufferInterface(BufferFactoryD3D *factory) + : VertexBufferInterface(factory, false) +{ +} + +StaticVertexBufferInterface::~StaticVertexBufferInterface() +{ +} + +bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attrib, unsigned int *outStreamOffset) +{ + for (unsigned int element = 0; element < mCache.size(); element++) + { + if (mCache[element].type == attrib.type && + mCache[element].size == attrib.size && + mCache[element].stride == ComputeVertexAttributeStride(attrib) && + mCache[element].normalized == attrib.normalized && + mCache[element].pureInteger == attrib.pureInteger) + { + size_t offset = (static_cast(attrib.offset) % ComputeVertexAttributeStride(attrib)); + if (mCache[element].attributeOffset == offset) + { + if (outStreamOffset) + { + *outStreamOffset = mCache[element].streamOffset; + } + return true; + } + } + } + + return false; +} + +gl::Error StaticVertexBufferInterface::reserveSpace(unsigned int size) +{ + unsigned int curSize = getBufferSize(); + if (curSize == 0) + { + return setBufferSize(size); + } + else if (curSize >= size) + { + return gl::Error(GL_NO_ERROR); + } + else + { + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION, "Internal error, Static vertex buffers can't be resized."); + } +} + +gl::Error StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) +{ + unsigned int streamOffset; + gl::Error error = VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances, &streamOffset); + if (error.isError()) + { + return error; + } + + size_t attributeOffset = static_cast(attrib.offset) % ComputeVertexAttributeStride(attrib); + VertexElement element = { attrib.type, attrib.size, static_cast(ComputeVertexAttributeStride(attrib)), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset }; + mCache.push_back(element); + + if (outStreamOffset) + { + *outStreamOffset = streamOffset; + } + + return gl::Error(GL_NO_ERROR); +} + +} -- cgit v1.2.3