1 #include "precompiled.h" 2 // 3 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 // 7 8 // VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. 9 10 #include "libGLESv2/renderer/d3d11/VertexBuffer11.h" 11 #include "libGLESv2/renderer/BufferStorage.h" 12 13 #include "libGLESv2/Buffer.h" 14 #include "libGLESv2/renderer/d3d11/Renderer11.h" 15 #include "libGLESv2/VertexAttribute.h" 16 #include "libGLESv2/renderer/d3d11/formatutils11.h" 17 18 namespace rx 19 { 20 21 VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) 22 { 23 mBuffer = NULL; 24 mBufferSize = 0; 25 mDynamicUsage = false; 26 } 27 28 VertexBuffer11::~VertexBuffer11() 29 { 30 SafeRelease(mBuffer); 31 } 32 33 bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) 34 { 35 SafeRelease(mBuffer); 36 37 updateSerial(); 38 39 if (size > 0) 40 { 41 ID3D11Device* dxDevice = mRenderer->getDevice(); 42 43 D3D11_BUFFER_DESC bufferDesc; 44 bufferDesc.ByteWidth = size; 45 bufferDesc.Usage = D3D11_USAGE_DYNAMIC; 46 bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 47 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 48 bufferDesc.MiscFlags = 0; 49 bufferDesc.StructureByteStride = 0; 50 51 HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); 52 if (FAILED(result)) 53 { 54 return false; 55 } 56 } 57 58 mBufferSize = size; 59 mDynamicUsage = dynamicUsage; 60 return true; 61 } 62 63 VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) 64 { 65 ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer)); 66 return static_cast<VertexBuffer11*>(vetexBuffer); 67 } 68 69 bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, 70 GLint start, GLsizei count, GLsizei instances, unsigned int offset) 71 { 72 if (mBuffer) 73 { 74 gl::Buffer *buffer = attrib.mBoundBuffer.get(); 75 int inputStride = attrib.stride(); 76 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 77 78 D3D11_MAPPED_SUBRESOURCE mappedResource; 79 HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); 80 if (FAILED(result)) 81 { 82 ERR("Vertex buffer map failed with error 0x%08x", result); 83 return false; 84 } 85 86 char* output = reinterpret_cast<char*>(mappedResource.pData) + offset; 87 88 const char *input = NULL; 89 if (attrib.mArrayEnabled) 90 { 91 if (buffer) 92 { 93 BufferStorage *storage = buffer->getStorage(); 94 input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset); 95 } 96 else 97 { 98 input = static_cast<const char*>(attrib.mPointer); 99 } 100 } 101 else 102 { 103 input = reinterpret_cast<const char*>(currentValue.FloatValues); 104 } 105 106 if (instances == 0 || attrib.mDivisor == 0) 107 { 108 input += inputStride * start; 109 } 110 111 gl::VertexFormat vertexFormat(attrib, currentValue.Type); 112 VertexCopyFunction conversionFunc = gl_d3d11::GetVertexCopyFunction(vertexFormat); 113 ASSERT(conversionFunc != NULL); 114 conversionFunc(input, inputStride, count, output); 115 116 dxContext->Unmap(mBuffer, 0); 117 118 return true; 119 } 120 else 121 { 122 ERR("Vertex buffer not initialized."); 123 return false; 124 } 125 } 126 127 bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, 128 GLsizei instances, unsigned int *outSpaceRequired) const 129 { 130 unsigned int elementCount = 0; 131 if (attrib.mArrayEnabled) 132 { 133 if (instances == 0 || attrib.mDivisor == 0) 134 { 135 elementCount = count; 136 } 137 else 138 { 139 if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1)) 140 { 141 // Round up 142 elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.mDivisor); 143 } 144 else 145 { 146 elementCount = instances / attrib.mDivisor; 147 } 148 } 149 150 gl::VertexFormat vertexFormat(attrib); 151 unsigned int elementSize = static_cast<unsigned int>(gl_d3d11::GetVertexElementSize(vertexFormat)); 152 if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) 153 { 154 if (outSpaceRequired) 155 { 156 *outSpaceRequired = elementSize * elementCount; 157 } 158 return true; 159 } 160 else 161 { 162 return false; 163 } 164 } 165 else 166 { 167 const unsigned int elementSize = 4; 168 if (outSpaceRequired) 169 { 170 *outSpaceRequired = elementSize * 4; 171 } 172 return true; 173 } 174 } 175 176 unsigned int VertexBuffer11::getBufferSize() const 177 { 178 return mBufferSize; 179 } 180 181 bool VertexBuffer11::setBufferSize(unsigned int size) 182 { 183 if (size > mBufferSize) 184 { 185 return initialize(size, mDynamicUsage); 186 } 187 else 188 { 189 return true; 190 } 191 } 192 193 bool VertexBuffer11::discard() 194 { 195 if (mBuffer) 196 { 197 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 198 199 D3D11_MAPPED_SUBRESOURCE mappedResource; 200 HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); 201 if (FAILED(result)) 202 { 203 ERR("Vertex buffer map failed with error 0x%08x", result); 204 return false; 205 } 206 207 dxContext->Unmap(mBuffer, 0); 208 209 return true; 210 } 211 else 212 { 213 ERR("Vertex buffer not initialized."); 214 return false; 215 } 216 } 217 218 ID3D11Buffer *VertexBuffer11::getBuffer() const 219 { 220 return mBuffer; 221 } 222 223 } 224