VertexBuffer11.cpp (5122B)
1 // 2 // Copyright 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. 5 // 6 7 // VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. 8 9 #include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" 10 11 #include "libANGLE/Buffer.h" 12 #include "libANGLE/Context.h" 13 #include "libANGLE/VertexAttribute.h" 14 #include "libANGLE/formatutils.h" 15 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" 16 #include "libANGLE/renderer/d3d/d3d11/Context11.h" 17 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" 18 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" 19 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" 20 21 namespace rx 22 { 23 24 VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) 25 : mRenderer(renderer), 26 mBuffer(), 27 mBufferSize(0), 28 mDynamicUsage(false), 29 mMappedResourceData(nullptr) 30 {} 31 32 VertexBuffer11::~VertexBuffer11() 33 { 34 ASSERT(mMappedResourceData == nullptr); 35 } 36 37 angle::Result VertexBuffer11::initialize(const gl::Context *context, 38 unsigned int size, 39 bool dynamicUsage) 40 { 41 mBuffer.reset(); 42 updateSerial(); 43 44 if (size > 0) 45 { 46 D3D11_BUFFER_DESC bufferDesc; 47 bufferDesc.ByteWidth = size; 48 bufferDesc.Usage = D3D11_USAGE_DYNAMIC; 49 bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 50 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 51 bufferDesc.MiscFlags = 0; 52 bufferDesc.StructureByteStride = 0; 53 54 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferDesc, &mBuffer)); 55 56 if (dynamicUsage) 57 { 58 mBuffer.setInternalName("VertexBuffer11(dynamic)"); 59 } 60 else 61 { 62 mBuffer.setInternalName("VertexBuffer11(static)"); 63 } 64 } 65 66 mBufferSize = size; 67 mDynamicUsage = dynamicUsage; 68 69 return angle::Result::Continue; 70 } 71 72 angle::Result VertexBuffer11::mapResource(const gl::Context *context) 73 { 74 if (mMappedResourceData == nullptr) 75 { 76 D3D11_MAPPED_SUBRESOURCE mappedResource; 77 78 ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, 79 &mappedResource)); 80 81 mMappedResourceData = static_cast<uint8_t *>(mappedResource.pData); 82 } 83 84 return angle::Result::Continue; 85 } 86 87 void VertexBuffer11::hintUnmapResource() 88 { 89 if (mMappedResourceData != nullptr) 90 { 91 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 92 dxContext->Unmap(mBuffer.get(), 0); 93 94 mMappedResourceData = nullptr; 95 } 96 } 97 98 angle::Result VertexBuffer11::storeVertexAttributes(const gl::Context *context, 99 const gl::VertexAttribute &attrib, 100 const gl::VertexBinding &binding, 101 gl::VertexAttribType currentValueType, 102 GLint start, 103 size_t count, 104 GLsizei instances, 105 unsigned int offset, 106 const uint8_t *sourceData) 107 { 108 ASSERT(mBuffer.valid()); 109 110 int inputStride = static_cast<int>(ComputeVertexAttributeStride(attrib, binding)); 111 112 // This will map the resource if it isn't already mapped. 113 ANGLE_TRY(mapResource(context)); 114 115 uint8_t *output = mMappedResourceData + offset; 116 117 const uint8_t *input = sourceData; 118 119 if (instances == 0 || binding.getDivisor() == 0) 120 { 121 input += inputStride * start; 122 } 123 124 angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, currentValueType); 125 const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; 126 const d3d11::VertexFormat &vertexFormatInfo = 127 d3d11::GetVertexFormatInfo(vertexFormatID, featureLevel); 128 ASSERT(vertexFormatInfo.copyFunction != nullptr); 129 vertexFormatInfo.copyFunction(input, inputStride, count, output); 130 131 return angle::Result::Continue; 132 } 133 134 unsigned int VertexBuffer11::getBufferSize() const 135 { 136 return mBufferSize; 137 } 138 139 angle::Result VertexBuffer11::setBufferSize(const gl::Context *context, unsigned int size) 140 { 141 if (size > mBufferSize) 142 { 143 return initialize(context, size, mDynamicUsage); 144 } 145 146 return angle::Result::Continue; 147 } 148 149 angle::Result VertexBuffer11::discard(const gl::Context *context) 150 { 151 ASSERT(mBuffer.valid()); 152 153 D3D11_MAPPED_SUBRESOURCE mappedResource; 154 ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, 155 &mappedResource)); 156 157 mRenderer->getDeviceContext()->Unmap(mBuffer.get(), 0); 158 159 return angle::Result::Continue; 160 } 161 162 const d3d11::Buffer &VertexBuffer11::getBuffer() const 163 { 164 return mBuffer; 165 } 166 167 } // namespace rx