Home | History | Annotate | Download | only in d3d11
      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 &currentValue,
     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