diff options
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp')
-rwxr-xr-x | gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp new file mode 100755 index 000000000..6cd91bd35 --- /dev/null +++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp @@ -0,0 +1,191 @@ +// +// 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/Buffer.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.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); + } + + if (dynamicUsage) + { + d3d11::SetDebugName(mBuffer, "VertexBuffer11 (dynamic)"); + } + else + { + d3d11::SetDebugName(mBuffer, "VertexBuffer11 (static)"); + } + } + + mBufferSize = size; + mDynamicUsage = dynamicUsage; + + return gl::Error(GL_NO_ERROR); +} + +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, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) +{ + if (!mBuffer) + { + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } + + int inputStride = static_cast<int>(ComputeVertexAttributeStride(attrib)); + + // This will map the resource if it isn't already mapped. + ANGLE_TRY(mapResource()); + + uint8_t *output = mMappedResourceData + offset; + + const uint8_t *input = sourceData; + + if (instances == 0 || attrib.divisor == 0) + { + input += inputStride * start; + } + + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValueType); + const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; + const d3d11::VertexFormat &vertexFormatInfo = + d3d11::GetVertexFormatInfo(vertexFormatType, featureLevel); + ASSERT(vertexFormatInfo.copyFunction != NULL); + vertexFormatInfo.copyFunction(input, inputStride, count, output); + + return gl::NoError(); +} + +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; +} + +} // namespace rx |