Home | History | Annotate | Download | only in renderer
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2002-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 // Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
      9 
     10 #include "libGLESv2/renderer/IndexBuffer9.h"
     11 #include "libGLESv2/renderer/Renderer9.h"
     12 
     13 namespace rx
     14 {
     15 
     16 IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
     17 {
     18     mIndexBuffer = NULL;
     19     mBufferSize = 0;
     20     mIndexType = 0;
     21     mDynamic = false;
     22 }
     23 
     24 IndexBuffer9::~IndexBuffer9()
     25 {
     26     if (mIndexBuffer)
     27     {
     28         mIndexBuffer->Release();
     29         mIndexBuffer = NULL;
     30     }
     31 }
     32 
     33 bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
     34 {
     35     if (mIndexBuffer)
     36     {
     37         mIndexBuffer->Release();
     38         mIndexBuffer = NULL;
     39     }
     40 
     41     updateSerial();
     42 
     43     if (bufferSize > 0)
     44     {
     45         D3DFORMAT format;
     46         if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
     47         {
     48             format = D3DFMT_INDEX16;
     49         }
     50         else if (indexType == GL_UNSIGNED_INT)
     51         {
     52             if (mRenderer->get32BitIndexSupport())
     53             {
     54                 format = D3DFMT_INDEX32;
     55             }
     56             else
     57             {
     58                 ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices.");
     59                 return false;
     60             }
     61         }
     62         else
     63         {
     64             ERR("Invalid index type %u.", indexType);
     65             return false;
     66         }
     67 
     68         DWORD usageFlags = D3DUSAGE_WRITEONLY;
     69         if (dynamic)
     70         {
     71             usageFlags |= D3DUSAGE_DYNAMIC;
     72         }
     73 
     74         HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
     75         if (FAILED(result))
     76         {
     77             ERR("Failed to create an index buffer of size %u, result: 0x%08x.", mBufferSize, result);
     78             return false;
     79         }
     80     }
     81 
     82     mBufferSize = bufferSize;
     83     mIndexType = indexType;
     84     mDynamic = dynamic;
     85 
     86     return true;
     87 }
     88 
     89 IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer)
     90 {
     91     ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer));
     92     return static_cast<IndexBuffer9*>(indexBuffer);
     93 }
     94 
     95 bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
     96 {
     97     if (mIndexBuffer)
     98     {
     99         DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
    100 
    101         void *mapPtr = NULL;
    102         HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
    103         if (FAILED(result))
    104         {
    105             ERR("Index buffer lock failed with error 0x%08x", result);
    106             return false;
    107         }
    108 
    109         *outMappedMemory = mapPtr;
    110         return true;
    111     }
    112     else
    113     {
    114         ERR("Index buffer not initialized.");
    115         return false;
    116     }
    117 }
    118 
    119 bool IndexBuffer9::unmapBuffer()
    120 {
    121     if (mIndexBuffer)
    122     {
    123         HRESULT result = mIndexBuffer->Unlock();
    124         if (FAILED(result))
    125         {
    126             ERR("Index buffer unlock failed with error 0x%08x", result);
    127             return false;
    128         }
    129 
    130         return true;
    131     }
    132     else
    133     {
    134         ERR("Index buffer not initialized.");
    135         return false;
    136     }
    137 }
    138 
    139 GLenum IndexBuffer9::getIndexType() const
    140 {
    141     return mIndexType;
    142 }
    143 
    144 unsigned int IndexBuffer9::getBufferSize() const
    145 {
    146     return mBufferSize;
    147 }
    148 
    149 bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
    150 {
    151     if (bufferSize > mBufferSize || indexType != mIndexType)
    152     {
    153         return initialize(bufferSize, indexType, mDynamic);
    154     }
    155     else
    156     {
    157         return true;
    158     }
    159 }
    160 
    161 bool IndexBuffer9::discard()
    162 {
    163     if (mIndexBuffer)
    164     {
    165         void *dummy;
    166         HRESULT result;
    167 
    168         result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
    169         if (FAILED(result))
    170         {
    171             ERR("Discard lock failed with error 0x%08x", result);
    172             return false;
    173         }
    174 
    175         result = mIndexBuffer->Unlock();
    176         if (FAILED(result))
    177         {
    178             ERR("Discard unlock failed with error 0x%08x", result);
    179             return false;
    180         }
    181 
    182         return true;
    183     }
    184     else
    185     {
    186         ERR("Index buffer not initialized.");
    187         return false;
    188     }
    189 }
    190 
    191 D3DFORMAT IndexBuffer9::getIndexFormat() const
    192 {
    193     switch (mIndexType)
    194     {
    195       case GL_UNSIGNED_BYTE:    return D3DFMT_INDEX16;
    196       case GL_UNSIGNED_SHORT:   return D3DFMT_INDEX16;
    197       case GL_UNSIGNED_INT:     return D3DFMT_INDEX32;
    198       default: UNREACHABLE();   return D3DFMT_UNKNOWN;
    199     }
    200 }
    201 
    202 IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const
    203 {
    204     return mIndexBuffer;
    205 }
    206 
    207 }