1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libGLESv2/renderer/VertexBuffer11.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,440 @@ 1.4 +#include "precompiled.h" 1.5 +// 1.6 +// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. 1.7 +// Use of this source code is governed by a BSD-style license that can be 1.8 +// found in the LICENSE file. 1.9 +// 1.10 + 1.11 +// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. 1.12 + 1.13 +#include "libGLESv2/renderer/VertexBuffer11.h" 1.14 +#include "libGLESv2/renderer/BufferStorage.h" 1.15 + 1.16 +#include "libGLESv2/Buffer.h" 1.17 +#include "libGLESv2/renderer/Renderer11.h" 1.18 +#include "libGLESv2/Context.h" 1.19 + 1.20 +namespace rx 1.21 +{ 1.22 + 1.23 +VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) 1.24 +{ 1.25 + mBuffer = NULL; 1.26 + mBufferSize = 0; 1.27 + mDynamicUsage = false; 1.28 +} 1.29 + 1.30 +VertexBuffer11::~VertexBuffer11() 1.31 +{ 1.32 + if (mBuffer) 1.33 + { 1.34 + mBuffer->Release(); 1.35 + mBuffer = NULL; 1.36 + } 1.37 +} 1.38 + 1.39 +bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) 1.40 +{ 1.41 + if (mBuffer) 1.42 + { 1.43 + mBuffer->Release(); 1.44 + mBuffer = NULL; 1.45 + } 1.46 + 1.47 + updateSerial(); 1.48 + 1.49 + if (size > 0) 1.50 + { 1.51 + ID3D11Device* dxDevice = mRenderer->getDevice(); 1.52 + 1.53 + D3D11_BUFFER_DESC bufferDesc; 1.54 + bufferDesc.ByteWidth = size; 1.55 + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; 1.56 + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 1.57 + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 1.58 + bufferDesc.MiscFlags = 0; 1.59 + bufferDesc.StructureByteStride = 0; 1.60 + 1.61 + HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); 1.62 + if (FAILED(result)) 1.63 + { 1.64 + return false; 1.65 + } 1.66 + } 1.67 + 1.68 + mBufferSize = size; 1.69 + mDynamicUsage = dynamicUsage; 1.70 + return true; 1.71 +} 1.72 + 1.73 +VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) 1.74 +{ 1.75 + ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer)); 1.76 + return static_cast<VertexBuffer11*>(vetexBuffer); 1.77 +} 1.78 + 1.79 +bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, 1.80 + GLsizei instances, unsigned int offset) 1.81 +{ 1.82 + if (mBuffer) 1.83 + { 1.84 + gl::Buffer *buffer = attrib.mBoundBuffer.get(); 1.85 + 1.86 + int inputStride = attrib.stride(); 1.87 + const VertexConverter &converter = getVertexConversion(attrib); 1.88 + 1.89 + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 1.90 + 1.91 + D3D11_MAPPED_SUBRESOURCE mappedResource; 1.92 + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); 1.93 + if (FAILED(result)) 1.94 + { 1.95 + ERR("Vertex buffer map failed with error 0x%08x", result); 1.96 + return false; 1.97 + } 1.98 + 1.99 + char* output = reinterpret_cast<char*>(mappedResource.pData) + offset; 1.100 + 1.101 + const char *input = NULL; 1.102 + if (buffer) 1.103 + { 1.104 + BufferStorage *storage = buffer->getStorage(); 1.105 + input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset); 1.106 + } 1.107 + else 1.108 + { 1.109 + input = static_cast<const char*>(attrib.mPointer); 1.110 + } 1.111 + 1.112 + if (instances == 0 || attrib.mDivisor == 0) 1.113 + { 1.114 + input += inputStride * start; 1.115 + } 1.116 + 1.117 + converter.conversionFunc(input, inputStride, count, output); 1.118 + 1.119 + dxContext->Unmap(mBuffer, 0); 1.120 + 1.121 + return true; 1.122 + } 1.123 + else 1.124 + { 1.125 + ERR("Vertex buffer not initialized."); 1.126 + return false; 1.127 + } 1.128 +} 1.129 + 1.130 +bool VertexBuffer11::storeRawData(const void* data, unsigned int size, unsigned int offset) 1.131 +{ 1.132 + if (mBuffer) 1.133 + { 1.134 + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 1.135 + 1.136 + D3D11_MAPPED_SUBRESOURCE mappedResource; 1.137 + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); 1.138 + if (FAILED(result)) 1.139 + { 1.140 + ERR("Vertex buffer map failed with error 0x%08x", result); 1.141 + return false; 1.142 + } 1.143 + 1.144 + char* bufferData = static_cast<char*>(mappedResource.pData); 1.145 + memcpy(bufferData + offset, data, size); 1.146 + 1.147 + dxContext->Unmap(mBuffer, 0); 1.148 + 1.149 + return true; 1.150 + } 1.151 + else 1.152 + { 1.153 + ERR("Vertex buffer not initialized."); 1.154 + return false; 1.155 + } 1.156 +} 1.157 + 1.158 +bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, 1.159 + GLsizei instances, unsigned int *outSpaceRequired) const 1.160 +{ 1.161 + unsigned int elementSize = getVertexConversion(attrib).outputElementSize; 1.162 + 1.163 + unsigned int elementCount = 0; 1.164 + if (instances == 0 || attrib.mDivisor == 0) 1.165 + { 1.166 + elementCount = count; 1.167 + } 1.168 + else 1.169 + { 1.170 + if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1)) 1.171 + { 1.172 + // Round up 1.173 + elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; 1.174 + } 1.175 + else 1.176 + { 1.177 + elementCount = instances / attrib.mDivisor; 1.178 + } 1.179 + } 1.180 + 1.181 + if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) 1.182 + { 1.183 + if (outSpaceRequired) 1.184 + { 1.185 + *outSpaceRequired = elementSize * elementCount; 1.186 + } 1.187 + return true; 1.188 + } 1.189 + else 1.190 + { 1.191 + return false; 1.192 + } 1.193 +} 1.194 + 1.195 +bool VertexBuffer11::requiresConversion(const gl::VertexAttribute &attrib) const 1.196 +{ 1.197 + return !getVertexConversion(attrib).identity; 1.198 +} 1.199 + 1.200 +unsigned int VertexBuffer11::getBufferSize() const 1.201 +{ 1.202 + return mBufferSize; 1.203 +} 1.204 + 1.205 +bool VertexBuffer11::setBufferSize(unsigned int size) 1.206 +{ 1.207 + if (size > mBufferSize) 1.208 + { 1.209 + return initialize(size, mDynamicUsage); 1.210 + } 1.211 + else 1.212 + { 1.213 + return true; 1.214 + } 1.215 +} 1.216 + 1.217 +bool VertexBuffer11::discard() 1.218 +{ 1.219 + if (mBuffer) 1.220 + { 1.221 + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 1.222 + 1.223 + D3D11_MAPPED_SUBRESOURCE mappedResource; 1.224 + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); 1.225 + if (FAILED(result)) 1.226 + { 1.227 + ERR("Vertex buffer map failed with error 0x%08x", result); 1.228 + return false; 1.229 + } 1.230 + 1.231 + dxContext->Unmap(mBuffer, 0); 1.232 + 1.233 + return true; 1.234 + } 1.235 + else 1.236 + { 1.237 + ERR("Vertex buffer not initialized."); 1.238 + return false; 1.239 + } 1.240 +} 1.241 + 1.242 +unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &attrib) const 1.243 +{ 1.244 + return getVertexConversion(attrib).outputElementSize; 1.245 +} 1.246 + 1.247 +DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &attrib) const 1.248 +{ 1.249 + return getVertexConversion(attrib).dxgiFormat; 1.250 +} 1.251 + 1.252 +ID3D11Buffer *VertexBuffer11::getBuffer() const 1.253 +{ 1.254 + return mBuffer; 1.255 +} 1.256 + 1.257 +template <typename T, unsigned int componentCount, bool widen, bool normalized> 1.258 +static void copyVertexData(const void *input, unsigned int stride, unsigned int count, void *output) 1.259 +{ 1.260 + unsigned int attribSize = sizeof(T) * componentCount; 1.261 + 1.262 + if (attribSize == stride && !widen) 1.263 + { 1.264 + memcpy(output, input, count * attribSize); 1.265 + } 1.266 + else 1.267 + { 1.268 + unsigned int outputStride = widen ? 4 : componentCount; 1.269 + T defaultVal = normalized ? std::numeric_limits<T>::max() : T(1); 1.270 + 1.271 + for (unsigned int i = 0; i < count; i++) 1.272 + { 1.273 + const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + i * stride); 1.274 + T *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride; 1.275 + 1.276 + for (unsigned int j = 0; j < componentCount; j++) 1.277 + { 1.278 + offsetOutput[j] = offsetInput[j]; 1.279 + } 1.280 + 1.281 + if (widen) 1.282 + { 1.283 + offsetOutput[3] = defaultVal; 1.284 + } 1.285 + } 1.286 + } 1.287 +} 1.288 + 1.289 +template <unsigned int componentCount> 1.290 +static void copyFixedVertexData(const void* input, unsigned int stride, unsigned int count, void* output) 1.291 +{ 1.292 + static const float divisor = 1.0f / (1 << 16); 1.293 + 1.294 + for (unsigned int i = 0; i < count; i++) 1.295 + { 1.296 + const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(reinterpret_cast<const char*>(input) + stride * i); 1.297 + float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; 1.298 + 1.299 + for (unsigned int j = 0; j < componentCount; j++) 1.300 + { 1.301 + offsetOutput[j] = static_cast<float>(offsetInput[j]) * divisor; 1.302 + } 1.303 + } 1.304 +} 1.305 + 1.306 +template <typename T, unsigned int componentCount, bool normalized> 1.307 +static void copyToFloatVertexData(const void* input, unsigned int stride, unsigned int count, void* output) 1.308 +{ 1.309 + typedef std::numeric_limits<T> NL; 1.310 + 1.311 + for (unsigned int i = 0; i < count; i++) 1.312 + { 1.313 + const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + stride * i); 1.314 + float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; 1.315 + 1.316 + for (unsigned int j = 0; j < componentCount; j++) 1.317 + { 1.318 + if (normalized) 1.319 + { 1.320 + if (NL::is_signed) 1.321 + { 1.322 + const float divisor = 1.0f / (2 * static_cast<float>(NL::max()) + 1); 1.323 + offsetOutput[j] = (2 * static_cast<float>(offsetInput[j]) + 1) * divisor; 1.324 + } 1.325 + else 1.326 + { 1.327 + offsetOutput[j] = static_cast<float>(offsetInput[j]) / NL::max(); 1.328 + } 1.329 + } 1.330 + else 1.331 + { 1.332 + offsetOutput[j] = static_cast<float>(offsetInput[j]); 1.333 + } 1.334 + } 1.335 + } 1.336 +} 1.337 + 1.338 +const VertexBuffer11::VertexConverter VertexBuffer11::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = 1.339 +{ 1.340 + { // GL_BYTE 1.341 + { // unnormalized 1.342 + { ©ToFloatVertexData<GLbyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 1.343 + { ©ToFloatVertexData<GLbyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 1.344 + { ©ToFloatVertexData<GLbyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 1.345 + { ©ToFloatVertexData<GLbyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 1.346 + }, 1.347 + { // normalized 1.348 + { ©VertexData<GLbyte, 1, false, true>, true, DXGI_FORMAT_R8_SNORM, 1 }, 1.349 + { ©VertexData<GLbyte, 2, false, true>, true, DXGI_FORMAT_R8G8_SNORM, 2 }, 1.350 + { ©VertexData<GLbyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, 1.351 + { ©VertexData<GLbyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, 1.352 + }, 1.353 + }, 1.354 + { // GL_UNSIGNED_BYTE 1.355 + { // unnormalized 1.356 + { ©ToFloatVertexData<GLubyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 1.357 + { ©ToFloatVertexData<GLubyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 1.358 + { ©ToFloatVertexData<GLubyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 1.359 + { ©ToFloatVertexData<GLubyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 1.360 + }, 1.361 + { // normalized 1.362 + { ©VertexData<GLubyte, 1, false, true>, true, DXGI_FORMAT_R8_UNORM, 1 }, 1.363 + { ©VertexData<GLubyte, 2, false, true>, true, DXGI_FORMAT_R8G8_UNORM, 2 }, 1.364 + { ©VertexData<GLubyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, 1.365 + { ©VertexData<GLubyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, 1.366 + }, 1.367 + }, 1.368 + { // GL_SHORT 1.369 + { // unnormalized 1.370 + { ©ToFloatVertexData<GLshort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 1.371 + { ©ToFloatVertexData<GLshort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 1.372 + { ©ToFloatVertexData<GLshort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 1.373 + { ©ToFloatVertexData<GLshort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 1.374 + }, 1.375 + { // normalized 1.376 + { ©VertexData<GLshort, 1, false, true>, true, DXGI_FORMAT_R16_SNORM, 2 }, 1.377 + { ©VertexData<GLshort, 2, false, true>, true, DXGI_FORMAT_R16G16_SNORM, 4 }, 1.378 + { ©VertexData<GLshort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, 1.379 + { ©VertexData<GLshort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, 1.380 + }, 1.381 + }, 1.382 + { // GL_UNSIGNED_SHORT 1.383 + { // unnormalized 1.384 + { ©ToFloatVertexData<GLushort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 1.385 + { ©ToFloatVertexData<GLushort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 1.386 + { ©ToFloatVertexData<GLushort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 1.387 + { ©ToFloatVertexData<GLushort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 1.388 + }, 1.389 + { // normalized 1.390 + { ©VertexData<GLushort, 1, false, true>, true, DXGI_FORMAT_R16_UNORM, 2 }, 1.391 + { ©VertexData<GLushort, 2, false, true>, true, DXGI_FORMAT_R16G16_UNORM, 4 }, 1.392 + { ©VertexData<GLushort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, 1.393 + { ©VertexData<GLushort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, 1.394 + }, 1.395 + }, 1.396 + { // GL_FIXED 1.397 + { // unnormalized 1.398 + { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 1.399 + { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 1.400 + { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 1.401 + { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 1.402 + }, 1.403 + { // normalized 1.404 + { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, 1.405 + { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, 1.406 + { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 1.407 + { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 1.408 + }, 1.409 + }, 1.410 + { // GL_FLOAT 1.411 + { // unnormalized 1.412 + { ©VertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 }, 1.413 + { ©VertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, 1.414 + { ©VertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 1.415 + { ©VertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 1.416 + }, 1.417 + { // normalized 1.418 + { ©VertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 }, 1.419 + { ©VertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, 1.420 + { ©VertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, 1.421 + { ©VertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, 1.422 + }, 1.423 + }, 1.424 +}; 1.425 + 1.426 +const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute) 1.427 +{ 1.428 + unsigned int typeIndex = 0; 1.429 + switch (attribute.mType) 1.430 + { 1.431 + case GL_BYTE: typeIndex = 0; break; 1.432 + case GL_UNSIGNED_BYTE: typeIndex = 1; break; 1.433 + case GL_SHORT: typeIndex = 2; break; 1.434 + case GL_UNSIGNED_SHORT: typeIndex = 3; break; 1.435 + case GL_FIXED: typeIndex = 4; break; 1.436 + case GL_FLOAT: typeIndex = 5; break; 1.437 + default: UNREACHABLE(); break; 1.438 + } 1.439 + 1.440 + return mPossibleTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1]; 1.441 +} 1.442 + 1.443 +}