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/VertexBuffer11.h" 11 #include "libGLESv2/renderer/BufferStorage.h" 12 13 #include "libGLESv2/Buffer.h" 14 #include "libGLESv2/renderer/Renderer11.h" 15 #include "libGLESv2/Context.h" 16 17 namespace rx 18 { 19 20 VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) 21 { 22 mBuffer = NULL; 23 mBufferSize = 0; 24 mDynamicUsage = false; 25 } 26 27 VertexBuffer11::~VertexBuffer11() 28 { 29 if (mBuffer) 30 { 31 mBuffer->Release(); 32 mBuffer = NULL; 33 } 34 } 35 36 bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) 37 { 38 if (mBuffer) 39 { 40 mBuffer->Release(); 41 mBuffer = NULL; 42 } 43 44 updateSerial(); 45 46 if (size > 0) 47 { 48 ID3D11Device* dxDevice = mRenderer->getDevice(); 49 50 D3D11_BUFFER_DESC bufferDesc; 51 bufferDesc.ByteWidth = size; 52 bufferDesc.Usage = D3D11_USAGE_DYNAMIC; 53 bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 54 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 55 bufferDesc.MiscFlags = 0; 56 bufferDesc.StructureByteStride = 0; 57 58 HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); 59 if (FAILED(result)) 60 { 61 return false; 62 } 63 } 64 65 mBufferSize = size; 66 mDynamicUsage = dynamicUsage; 67 return true; 68 } 69 70 VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) 71 { 72 ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer)); 73 return static_cast<VertexBuffer11*>(vetexBuffer); 74 } 75 76 bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, 77 GLsizei instances, unsigned int offset) 78 { 79 if (mBuffer) 80 { 81 gl::Buffer *buffer = attrib.mBoundBuffer.get(); 82 83 int inputStride = attrib.stride(); 84 const VertexConverter &converter = getVertexConversion(attrib); 85 86 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 87 88 D3D11_MAPPED_SUBRESOURCE mappedResource; 89 HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); 90 if (FAILED(result)) 91 { 92 ERR("Vertex buffer map failed with error 0x%08x", result); 93 return false; 94 } 95 96 char* output = reinterpret_cast<char*>(mappedResource.pData) + offset; 97 98 const char *input = NULL; 99 if (buffer) 100 { 101 BufferStorage *storage = buffer->getStorage(); 102 input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset); 103 } 104 else 105 { 106 input = static_cast<const char*>(attrib.mPointer); 107 } 108 109 if (instances == 0 || attrib.mDivisor == 0) 110 { 111 input += inputStride * start; 112 } 113 114 converter.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::storeRawData(const void* data, unsigned int size, unsigned int offset) 128 { 129 if (mBuffer) 130 { 131 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 132 133 D3D11_MAPPED_SUBRESOURCE mappedResource; 134 HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); 135 if (FAILED(result)) 136 { 137 ERR("Vertex buffer map failed with error 0x%08x", result); 138 return false; 139 } 140 141 char* bufferData = static_cast<char*>(mappedResource.pData); 142 memcpy(bufferData + offset, data, size); 143 144 dxContext->Unmap(mBuffer, 0); 145 146 return true; 147 } 148 else 149 { 150 ERR("Vertex buffer not initialized."); 151 return false; 152 } 153 } 154 155 unsigned int VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, 156 GLsizei instances) const 157 { 158 unsigned int elementSize = getVertexConversion(attrib).outputElementSize; 159 160 if (instances == 0 || attrib.mDivisor == 0) 161 { 162 return elementSize * count; 163 } 164 else 165 { 166 return elementSize * ((instances + attrib.mDivisor - 1) / attrib.mDivisor); 167 } 168 } 169 170 bool VertexBuffer11::requiresConversion(const gl::VertexAttribute &attrib) const 171 { 172 return !getVertexConversion(attrib).identity; 173 } 174 175 unsigned int VertexBuffer11::getBufferSize() const 176 { 177 return mBufferSize; 178 } 179 180 bool VertexBuffer11::setBufferSize(unsigned int size) 181 { 182 if (size > mBufferSize) 183 { 184 return initialize(size, mDynamicUsage); 185 } 186 else 187 { 188 return true; 189 } 190 } 191 192 bool VertexBuffer11::discard() 193 { 194 if (mBuffer) 195 { 196 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 197 198 D3D11_MAPPED_SUBRESOURCE mappedResource; 199 HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); 200 if (FAILED(result)) 201 { 202 ERR("Vertex buffer map failed with error 0x%08x", result); 203 return false; 204 } 205 206 dxContext->Unmap(mBuffer, 0); 207 208 return true; 209 } 210 else 211 { 212 ERR("Vertex buffer not initialized."); 213 return false; 214 } 215 } 216 217 unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &attrib) const 218 { 219 return getVertexConversion(attrib).outputElementSize; 220 } 221 222 DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &attrib) const 223 { 224 return getVertexConversion(attrib).dxgiFormat; 225 } 226 227 ID3D11Buffer *VertexBuffer11::getBuffer() const 228 { 229 return mBuffer; 230 } 231 232 template <typename T, unsigned int componentCount, bool widen, bool normalized> 233 static void copyVertexData(const void *input, unsigned int stride, unsigned int count, void *output) 234 { 235 unsigned int attribSize = sizeof(T) * componentCount; 236 237 if (attribSize == stride && !widen) 238 { 239 memcpy(output, input, count * attribSize); 240 } 241 else 242 { 243 unsigned int outputStride = widen ? 4 : componentCount; 244 T defaultVal = normalized ? std::numeric_limits<T>::max() : T(1); 245 246 for (unsigned int i = 0; i < count; i++) 247 { 248 const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + i * stride); 249 T *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride; 250 251 for (unsigned int j = 0; j < componentCount; j++) 252 { 253 offsetOutput[j] = offsetInput[j]; 254 } 255 256 if (widen) 257 { 258 offsetOutput[3] = defaultVal; 259 } 260 } 261 } 262 } 263 264 template <unsigned int componentCount> 265 static void copyFixedVertexData(const void* input, unsigned int stride, unsigned int count, void* output) 266 { 267 static const float divisor = 1.0f / (1 << 16); 268 269 for (unsigned int i = 0; i < count; i++) 270 { 271 const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(reinterpret_cast<const char*>(input) + stride * i); 272 float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; 273 274 for (unsigned int j = 0; j < componentCount; j++) 275 { 276 offsetOutput[j] = static_cast<float>(offsetInput[j]) * divisor; 277 } 278 } 279 } 280 281 template <typename T, unsigned int componentCount, bool normalized> 282 static void copyToFloatVertexData(const void* input, unsigned int stride, unsigned int count, void* output) 283 { 284 typedef std::numeric_limits<T> NL; 285 286 for (unsigned int i = 0; i < count; i++) 287 { 288 const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + stride * i); 289 float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; 290 291 for (unsigned int j = 0; j < componentCount; j++) 292 { 293 if (normalized) 294 { 295 if (NL::is_signed) 296 { 297 const float divisor = 1.0f / (2 * static_cast<float>(NL::max()) + 1); 298 offsetOutput[j] = (2 * static_cast<float>(offsetInput[j]) + 1) * divisor; 299 } 300 else 301 { 302 offsetOutput[j] = static_cast<float>(offsetInput[j]) / NL::max(); 303 } 304 } 305 else 306 { 307 offsetOutput[j] = static_cast<float>(offsetInput[j]); 308 } 309 } 310 } 311 } 312 313 const VertexBuffer11::VertexConverter VertexBuffer11::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = 314 { 315 { // GL_BYTE 316 { // unnormalized 317 { ©ToFloatVertexData<GLbyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 318 { ©ToFloatVertexData<GLbyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 319 { ©ToFloatVertexData<GLbyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 320 { ©ToFloatVertexData<GLbyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 321 }, 322 { // normalized 323 { ©VertexData<GLbyte, 1, false, true>, true, DXGI_FORMAT_R8_SNORM, 1 }, 324 { ©VertexData<GLbyte, 2, false, true>, true, DXGI_FORMAT_R8G8_SNORM, 2 }, 325 { ©VertexData<GLbyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, 326 { ©VertexData<GLbyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, 327 }, 328 }, 329 { // GL_UNSIGNED_BYTE 330 { // unnormalized 331 { ©ToFloatVertexData<GLubyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 332 { ©ToFloatVertexData<GLubyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 333 { ©ToFloatVertexData<GLubyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 334 { ©ToFloatVertexData<GLubyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 335 }, 336 { // normalized 337 { ©VertexData<GLubyte, 1, false, true>, true, DXGI_FORMAT_R8_UNORM, 1 }, 338 { ©VertexData<GLubyte, 2, false, true>, true, DXGI_FORMAT_R8G8_UNORM, 2 }, 339 { ©VertexData<GLubyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, 340 { ©VertexData<GLubyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, 341 }, 342 }, 343 { // GL_SHORT 344 { // unnormalized 345 { ©ToFloatVertexData<GLshort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 346 { ©ToFloatVertexData<GLshort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 347 { ©ToFloatVertexData<GLshort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 348 { ©ToFloatVertexData<GLshort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 349 }, 350 { // normalized 351 { ©VertexData<GLshort, 1, false, true>, true, DXGI_FORMAT_R16_SNORM, 2 }, 352 { ©VertexData<GLshort, 2, false, true>, true, DXGI_FORMAT_R16G16_SNORM, 4 }, 353 { ©VertexData<GLshort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, 354 { ©VertexData<GLshort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, 355 }, 356 }, 357 { // GL_UNSIGNED_SHORT 358 { // unnormalized 359 { ©ToFloatVertexData<GLushort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 360 { ©ToFloatVertexData<GLushort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 361 { ©ToFloatVertexData<GLushort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 362 { ©ToFloatVertexData<GLushort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 363 }, 364 { // normalized 365 { ©VertexData<GLushort, 1, false, true>, true, DXGI_FORMAT_R16_UNORM, 2 }, 366 { ©VertexData<GLushort, 2, false, true>, true, DXGI_FORMAT_R16G16_UNORM, 4 }, 367 { ©VertexData<GLushort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, 368 { ©VertexData<GLushort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, 369 }, 370 }, 371 { // GL_FIXED 372 { // unnormalized 373 { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 374 { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 375 { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 376 { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 377 }, 378 { // normalized 379 { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 380 { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 381 { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 382 { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 383 }, 384 }, 385 { // GL_FLOAT 386 { // unnormalized 387 { ©VertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 }, 388 { ©VertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, 389 { ©VertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 390 { ©VertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 391 }, 392 { // normalized 393 { ©VertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 }, 394 { ©VertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, 395 { ©VertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 396 { ©VertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 397 }, 398 }, 399 }; 400 401 const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute) 402 { 403 unsigned int typeIndex = 0; 404 switch (attribute.mType) 405 { 406 case GL_BYTE: typeIndex = 0; break; 407 case GL_UNSIGNED_BYTE: typeIndex = 1; break; 408 case GL_SHORT: typeIndex = 2; break; 409 case GL_UNSIGNED_SHORT: typeIndex = 3; break; 410 case GL_FIXED: typeIndex = 4; break; 411 case GL_FLOAT: typeIndex = 5; break; 412 default: UNREACHABLE(); break; 413 } 414 415 return mPossibleTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1]; 416 } 417 418 } 419