Home | History | Annotate | Download | only in renderer
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2012 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 // IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
      9 
     10 #include "libGLESv2/renderer/IndexBuffer11.h"
     11 #include "libGLESv2/renderer/Renderer11.h"
     12 
     13 namespace rx
     14 {
     15 
     16 IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
     17 {
     18     mBuffer = NULL;
     19     mBufferSize = 0;
     20     mDynamicUsage = false;
     21 }
     22 
     23 IndexBuffer11::~IndexBuffer11()
     24 {
     25     if (mBuffer)
     26     {
     27         mBuffer->Release();
     28         mBuffer = NULL;
     29     }
     30 }
     31 
     32 bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
     33 {
     34     if (mBuffer)
     35     {
     36         mBuffer->Release();
     37         mBuffer = NULL;
     38     }
     39 
     40     updateSerial();
     41 
     42     if (bufferSize > 0)
     43     {
     44         ID3D11Device* dxDevice = mRenderer->getDevice();
     45 
     46         D3D11_BUFFER_DESC bufferDesc;
     47         bufferDesc.ByteWidth = bufferSize;
     48         bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
     49         bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
     50         bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
     51         bufferDesc.MiscFlags = 0;
     52         bufferDesc.StructureByteStride = 0;
     53 
     54         HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
     55         if (FAILED(result))
     56         {
     57             return false;
     58         }
     59     }
     60 
     61     mBufferSize = bufferSize;
     62     mIndexType = indexType;
     63     mDynamicUsage = dynamic;
     64 
     65     return true;
     66 }
     67 
     68 IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
     69 {
     70     ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer));
     71     return static_cast<IndexBuffer11*>(indexBuffer);
     72 }
     73 
     74 bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
     75 {
     76     if (mBuffer)
     77     {
     78         if (offset + size > mBufferSize)
     79         {
     80             ERR("Index buffer map range is not inside the buffer.");
     81             return false;
     82         }
     83 
     84         ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
     85 
     86         D3D11_MAPPED_SUBRESOURCE mappedResource;
     87         HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
     88         if (FAILED(result))
     89         {
     90             ERR("Index buffer map failed with error 0x%08x", result);
     91             return false;
     92         }
     93 
     94         *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
     95         return true;
     96     }
     97     else
     98     {
     99         ERR("Index buffer not initialized.");
    100         return false;
    101     }
    102 }
    103 
    104 bool IndexBuffer11::unmapBuffer()
    105 {
    106     if (mBuffer)
    107     {
    108         ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
    109         dxContext->Unmap(mBuffer, 0);
    110         return true;
    111     }
    112     else
    113     {
    114         ERR("Index buffer not initialized.");
    115         return false;
    116     }
    117 }
    118 
    119 GLenum IndexBuffer11::getIndexType() const
    120 {
    121     return mIndexType;
    122 }
    123 
    124 unsigned int IndexBuffer11::getBufferSize() const
    125 {
    126     return mBufferSize;
    127 }
    128 
    129 bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
    130 {
    131     if (bufferSize > mBufferSize || indexType != mIndexType)
    132     {
    133         return initialize(bufferSize, indexType, mDynamicUsage);
    134     }
    135     else
    136     {
    137         return true;
    138     }
    139 }
    140 
    141 bool IndexBuffer11::discard()
    142 {
    143     if (mBuffer)
    144     {
    145         ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
    146 
    147         D3D11_MAPPED_SUBRESOURCE mappedResource;
    148         HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
    149         if (FAILED(result))
    150         {
    151             ERR("Index buffer map failed with error 0x%08x", result);
    152             return false;
    153         }
    154 
    155         dxContext->Unmap(mBuffer, 0);
    156 
    157         return true;
    158     }
    159     else
    160     {
    161         ERR("Index buffer not initialized.");
    162         return false;
    163     }
    164 }
    165 
    166 DXGI_FORMAT IndexBuffer11::getIndexFormat() const
    167 {
    168     switch (mIndexType)
    169     {
    170       case GL_UNSIGNED_BYTE:    return DXGI_FORMAT_R16_UINT;
    171       case GL_UNSIGNED_SHORT:   return DXGI_FORMAT_R16_UINT;
    172       case GL_UNSIGNED_INT:     return DXGI_FORMAT_R32_UINT;
    173       default: UNREACHABLE();   return DXGI_FORMAT_UNKNOWN;
    174     }
    175 }
    176 
    177 ID3D11Buffer *IndexBuffer11::getBuffer() const
    178 {
    179     return mBuffer;
    180 }
    181 
    182 }