gfx/angle/src/libGLESv2/renderer/VertexBuffer11.cpp

changeset 0
6474c204b198
     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 +            { &copyToFloatVertexData<GLbyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
   1.343 +            { &copyToFloatVertexData<GLbyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
   1.344 +            { &copyToFloatVertexData<GLbyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
   1.345 +            { &copyToFloatVertexData<GLbyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
   1.346 +        },
   1.347 +        { // normalized
   1.348 +            { &copyVertexData<GLbyte, 1, false, true>, true, DXGI_FORMAT_R8_SNORM, 1 },
   1.349 +            { &copyVertexData<GLbyte, 2, false, true>, true, DXGI_FORMAT_R8G8_SNORM, 2 },
   1.350 +            { &copyVertexData<GLbyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_SNORM, 4 },
   1.351 +            { &copyVertexData<GLbyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_SNORM, 4 },
   1.352 +        },
   1.353 +    },
   1.354 +    { // GL_UNSIGNED_BYTE
   1.355 +        { // unnormalized
   1.356 +            { &copyToFloatVertexData<GLubyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
   1.357 +            { &copyToFloatVertexData<GLubyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
   1.358 +            { &copyToFloatVertexData<GLubyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
   1.359 +            { &copyToFloatVertexData<GLubyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
   1.360 +        },
   1.361 +        { // normalized
   1.362 +            { &copyVertexData<GLubyte, 1, false, true>, true, DXGI_FORMAT_R8_UNORM, 1 },
   1.363 +            { &copyVertexData<GLubyte, 2, false, true>, true, DXGI_FORMAT_R8G8_UNORM, 2 },
   1.364 +            { &copyVertexData<GLubyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
   1.365 +            { &copyVertexData<GLubyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
   1.366 +        },
   1.367 +    },
   1.368 +    { // GL_SHORT
   1.369 +        { // unnormalized
   1.370 +            { &copyToFloatVertexData<GLshort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
   1.371 +            { &copyToFloatVertexData<GLshort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
   1.372 +            { &copyToFloatVertexData<GLshort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
   1.373 +            { &copyToFloatVertexData<GLshort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
   1.374 +        },
   1.375 +        { // normalized
   1.376 +            { &copyVertexData<GLshort, 1, false, true>, true, DXGI_FORMAT_R16_SNORM, 2 },
   1.377 +            { &copyVertexData<GLshort, 2, false, true>, true, DXGI_FORMAT_R16G16_SNORM, 4 },
   1.378 +            { &copyVertexData<GLshort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_SNORM, 8 },
   1.379 +            { &copyVertexData<GLshort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_SNORM, 8 },
   1.380 +        },
   1.381 +    },
   1.382 +    { // GL_UNSIGNED_SHORT
   1.383 +        { // unnormalized
   1.384 +            { &copyToFloatVertexData<GLushort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
   1.385 +            { &copyToFloatVertexData<GLushort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
   1.386 +            { &copyToFloatVertexData<GLushort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
   1.387 +            { &copyToFloatVertexData<GLushort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
   1.388 +        },
   1.389 +        { // normalized
   1.390 +            { &copyVertexData<GLushort, 1, false, true>, true, DXGI_FORMAT_R16_UNORM, 2 },
   1.391 +            { &copyVertexData<GLushort, 2, false, true>, true, DXGI_FORMAT_R16G16_UNORM, 4 },
   1.392 +            { &copyVertexData<GLushort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_UNORM, 8 },
   1.393 +            { &copyVertexData<GLushort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 },
   1.394 +        },
   1.395 +    },
   1.396 +    { // GL_FIXED
   1.397 +        { // unnormalized
   1.398 +            { &copyFixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 },
   1.399 +            { &copyFixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
   1.400 +            { &copyFixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
   1.401 +            { &copyFixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
   1.402 +        },
   1.403 +        { // normalized
   1.404 +            { &copyFixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 },
   1.405 +            { &copyFixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
   1.406 +            { &copyFixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
   1.407 +            { &copyFixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
   1.408 +        },
   1.409 +    },
   1.410 +    { // GL_FLOAT
   1.411 +        { // unnormalized
   1.412 +            { &copyVertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 },
   1.413 +            { &copyVertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 },
   1.414 +            { &copyVertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
   1.415 +            { &copyVertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
   1.416 +        },
   1.417 +        { // normalized
   1.418 +            { &copyVertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 },
   1.419 +            { &copyVertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 },
   1.420 +            { &copyVertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
   1.421 +            { &copyVertexData<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 +}

mercurial