2 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
7 // VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
9 #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
10 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
11 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
12 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
13 #include "libGLESv2/Buffer.h"
14 #include "libGLESv2/VertexAttribute.h"
19 VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer)
23 mDynamicUsage = false;
26 VertexBuffer11::~VertexBuffer11()
31 gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
39 ID3D11Device* dxDevice = mRenderer->getDevice();
41 D3D11_BUFFER_DESC bufferDesc;
42 bufferDesc.ByteWidth = size;
43 bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
44 bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
45 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
46 bufferDesc.MiscFlags = 0;
47 bufferDesc.StructureByteStride = 0;
49 HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
52 return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
57 mDynamicUsage = dynamicUsage;
59 return gl::Error(GL_NO_ERROR);
62 VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
64 ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer));
65 return static_cast<VertexBuffer11*>(vetexBuffer);
68 gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
69 GLint start, GLsizei count, GLsizei instances, unsigned int offset)
73 return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
76 gl::Buffer *buffer = attrib.buffer.get();
77 int inputStride = ComputeVertexAttributeStride(attrib);
78 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
80 D3D11_MAPPED_SUBRESOURCE mappedResource;
81 HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
84 return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result);
87 uint8_t *output = reinterpret_cast<uint8_t*>(mappedResource.pData) + offset;
89 const uint8_t *input = NULL;
94 BufferD3D *storage = BufferD3D::makeFromBuffer(buffer);
95 gl::Error error = storage->getData(&input);
100 input += static_cast<int>(attrib.offset);
104 input = static_cast<const uint8_t*>(attrib.pointer);
109 input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues);
112 if (instances == 0 || attrib.divisor == 0)
114 input += inputStride * start;
117 gl::VertexFormat vertexFormat(attrib, currentValue.Type);
118 const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
119 ASSERT(vertexFormatInfo.copyFunction != NULL);
120 vertexFormatInfo.copyFunction(input, inputStride, count, output);
122 dxContext->Unmap(mBuffer, 0);
124 return gl::Error(GL_NO_ERROR);
127 gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
128 GLsizei instances, unsigned int *outSpaceRequired) const
130 unsigned int elementCount = 0;
133 if (instances == 0 || attrib.divisor == 0)
135 elementCount = count;
139 // Round up to divisor, if possible
140 elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
143 gl::VertexFormat vertexFormat(attrib);
144 const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
145 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat);
146 unsigned int elementSize = dxgiFormatInfo.pixelBytes;
147 if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
149 if (outSpaceRequired)
151 *outSpaceRequired = elementSize * elementCount;
153 return gl::Error(GL_NO_ERROR);
157 return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
162 const unsigned int elementSize = 4;
163 if (outSpaceRequired)
165 *outSpaceRequired = elementSize * 4;
167 return gl::Error(GL_NO_ERROR);
171 unsigned int VertexBuffer11::getBufferSize() const
176 gl::Error VertexBuffer11::setBufferSize(unsigned int size)
178 if (size > mBufferSize)
180 return initialize(size, mDynamicUsage);
184 return gl::Error(GL_NO_ERROR);
188 gl::Error VertexBuffer11::discard()
192 return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
195 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
197 D3D11_MAPPED_SUBRESOURCE mappedResource;
198 HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
201 return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer for discarding, HRESULT: 0x%08x", result);
204 dxContext->Unmap(mBuffer, 0);
206 return gl::Error(GL_NO_ERROR);
209 ID3D11Buffer *VertexBuffer11::getBuffer() const