summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-04-22 09:04:29 +0200
committerLiang Qi <liang.qi@theqtcompany.com>2015-04-22 09:25:54 +0200
commitaed5a7168354c6ae47687d20b4bd3f0adcc14f8e (patch)
treed2060479a7c12fdba8c1955e5d363754feffabb8 /src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp
parentd3d10cf23d61f4a011f1a7e9abdee1a92717e80f (diff)
parent628fa13ea4d6ff0e2e2ee76c9adfc78676de3c59 (diff)
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts: src/corelib/statemachine/qstatemachine.cpp src/corelib/statemachine/qstatemachine_p.h src/gui/painting/qdrawhelper.cpp src/plugins/platforms/xcb/qxcbnativeinterface.cpp src/plugins/platforms/xcb/qxcbwindow.cpp src/plugins/platforms/xcb/qxcbwindow.h src/testlib/qtestblacklist.cpp src/tools/qdoc/node.cpp src/tools/qdoc/node.h tests/auto/gui/painting/qcolor/tst_qcolor.cpp Change-Id: I6c78b7b162001712d5774293f501b06b4ff32684
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp311
1 files changed, 311 insertions, 0 deletions
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 &currentValue,
+ 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 &currentValue) const
+{
+ gl::Buffer *buffer = attrib.buffer.get();
+ BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(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<size_t>(outputElementSize, 4);
+
+ // TODO(jmadill): add VertexFormatCaps
+ requiresConversion = (mFactory->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0;
+ }
+
+ bool isAligned = (static_cast<size_t>(ComputeVertexAttributeStride(attrib)) % alignment == 0) &&
+ (static_cast<size_t>(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<size_t>(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 &currentValue,
+ 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<size_t>(attrib.offset) % ComputeVertexAttributeStride(attrib);
+ VertexElement element = { attrib.type, attrib.size, static_cast<GLuint>(ComputeVertexAttributeStride(attrib)), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset };
+ mCache.push_back(element);
+
+ if (outStreamOffset)
+ {
+ *outStreamOffset = streamOffset;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+}