summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
new file mode 100644
index 0000000000..adc64cef5e
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -0,0 +1,244 @@
+//
+// Copyright (c) 2013 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.
+//
+
+// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
+
+#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/VertexAttribute.h"
+
+namespace rx
+{
+
+VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
+{
+ mBuffer = NULL;
+ mBufferSize = 0;
+ mDynamicUsage = false;
+ mMappedResourceData = NULL;
+}
+
+VertexBuffer11::~VertexBuffer11()
+{
+ ASSERT(mMappedResourceData == NULL);
+ SafeRelease(mBuffer);
+}
+
+gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
+{
+ SafeRelease(mBuffer);
+
+ updateSerial();
+
+ if (size > 0)
+ {
+ ID3D11Device* dxDevice = mRenderer->getDevice();
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = size;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
+ }
+ }
+
+ mBufferSize = size;
+ mDynamicUsage = dynamicUsage;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer));
+ return static_cast<VertexBuffer11*>(vetexBuffer);
+}
+
+gl::Error VertexBuffer11::mapResource()
+{
+ if (mMappedResourceData == NULL)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+
+ HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result);
+ }
+
+ mMappedResourceData = reinterpret_cast<uint8_t*>(mappedResource.pData);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+void VertexBuffer11::hintUnmapResource()
+{
+ if (mMappedResourceData != NULL)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+ dxContext->Unmap(mBuffer, 0);
+
+ mMappedResourceData = NULL;
+ }
+}
+
+gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ GLint start, GLsizei count, GLsizei instances, unsigned int offset)
+{
+ if (!mBuffer)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
+ }
+
+ gl::Buffer *buffer = attrib.buffer.get();
+ int inputStride = ComputeVertexAttributeStride(attrib);
+
+ // This will map the resource if it isn't already mapped.
+ gl::Error error = mapResource();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ uint8_t *output = mMappedResourceData + offset;
+
+ const uint8_t *input = NULL;
+ if (attrib.enabled)
+ {
+ if (buffer)
+ {
+ BufferD3D *storage = GetImplAs<BufferD3D>(buffer);
+ error = storage->getData(&input);
+ if (error.isError())
+ {
+ return error;
+ }
+ input += static_cast<int>(attrib.offset);
+ }
+ else
+ {
+ input = static_cast<const uint8_t*>(attrib.pointer);
+ }
+ }
+ else
+ {
+ input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues);
+ }
+
+ if (instances == 0 || attrib.divisor == 0)
+ {
+ input += inputStride * start;
+ }
+
+ gl::VertexFormat vertexFormat(attrib, currentValue.Type);
+ const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mRenderer->getFeatureLevel());
+ ASSERT(vertexFormatInfo.copyFunction != NULL);
+ vertexFormatInfo.copyFunction(input, inputStride, count, output);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
+ GLsizei instances, unsigned int *outSpaceRequired) const
+{
+ unsigned int elementCount = 0;
+ if (attrib.enabled)
+ {
+ if (instances == 0 || attrib.divisor == 0)
+ {
+ elementCount = count;
+ }
+ else
+ {
+ // Round up to divisor, if possible
+ elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
+ }
+
+ gl::VertexFormat vertexFormat(attrib);
+ const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mRenderer->getFeatureLevel());
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat);
+ unsigned int elementSize = dxgiFormatInfo.pixelBytes;
+ if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
+ {
+ if (outSpaceRequired)
+ {
+ *outSpaceRequired = elementSize * elementCount;
+ }
+ return gl::Error(GL_NO_ERROR);
+ }
+ else
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
+ }
+ }
+ else
+ {
+ const unsigned int elementSize = 4;
+ if (outSpaceRequired)
+ {
+ *outSpaceRequired = elementSize * 4;
+ }
+ return gl::Error(GL_NO_ERROR);
+ }
+}
+
+unsigned int VertexBuffer11::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+gl::Error VertexBuffer11::setBufferSize(unsigned int size)
+{
+ if (size > mBufferSize)
+ {
+ return initialize(size, mDynamicUsage);
+ }
+ else
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+}
+
+gl::Error VertexBuffer11::discard()
+{
+ if (!mBuffer)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
+ }
+
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer for discarding, HRESULT: 0x%08x", result);
+ }
+
+ dxContext->Unmap(mBuffer, 0);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+ID3D11Buffer *VertexBuffer11::getBuffer() const
+{
+ return mBuffer;
+}
+
+}