Home | History | Annotate | Download | only in d3d9
      1 //
      2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
      8 
      9 #include "libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h"
     10 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
     11 
     12 namespace rx
     13 {
     14 
     15 IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
     16 {
     17     mIndexBuffer = NULL;
     18     mBufferSize = 0;
     19     mIndexType = 0;
     20     mDynamic = false;
     21 }
     22 
     23 IndexBuffer9::~IndexBuffer9()
     24 {
     25     SafeRelease(mIndexBuffer);
     26 }
     27 
     28 gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
     29 {
     30     SafeRelease(mIndexBuffer);
     31 
     32     updateSerial();
     33 
     34     if (bufferSize > 0)
     35     {
     36         D3DFORMAT format = D3DFMT_UNKNOWN;
     37         if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
     38         {
     39             format = D3DFMT_INDEX16;
     40         }
     41         else if (indexType == GL_UNSIGNED_INT)
     42         {
     43             ASSERT(mRenderer->getRendererExtensions().elementIndexUint);
     44             format = D3DFMT_INDEX32;
     45         }
     46         else UNREACHABLE();
     47 
     48         DWORD usageFlags = D3DUSAGE_WRITEONLY;
     49         if (dynamic)
     50         {
     51             usageFlags |= D3DUSAGE_DYNAMIC;
     52         }
     53 
     54         HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
     55         if (FAILED(result))
     56         {
     57             return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
     58         }
     59     }
     60 
     61     mBufferSize = bufferSize;
     62     mIndexType = indexType;
     63     mDynamic = dynamic;
     64 
     65     return gl::Error(GL_NO_ERROR);
     66 }
     67 
     68 IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer)
     69 {
     70     ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer));
     71     return static_cast<IndexBuffer9*>(indexBuffer);
     72 }
     73 
     74 gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
     75 {
     76     if (!mIndexBuffer)
     77     {
     78         return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
     79     }
     80 
     81     DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
     82 
     83     void *mapPtr = NULL;
     84     HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
     85     if (FAILED(result))
     86     {
     87         return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result);
     88     }
     89 
     90     *outMappedMemory = mapPtr;
     91     return gl::Error(GL_NO_ERROR);
     92 }
     93 
     94 gl::Error IndexBuffer9::unmapBuffer()
     95 {
     96     if (!mIndexBuffer)
     97     {
     98         return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
     99     }
    100 
    101     HRESULT result = mIndexBuffer->Unlock();
    102     if (FAILED(result))
    103     {
    104         return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result);
    105     }
    106 
    107     return gl::Error(GL_NO_ERROR);
    108 }
    109 
    110 GLenum IndexBuffer9::getIndexType() const
    111 {
    112     return mIndexType;
    113 }
    114 
    115 unsigned int IndexBuffer9::getBufferSize() const
    116 {
    117     return mBufferSize;
    118 }
    119 
    120 gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
    121 {
    122     if (bufferSize > mBufferSize || indexType != mIndexType)
    123     {
    124         return initialize(bufferSize, indexType, mDynamic);
    125     }
    126     else
    127     {
    128         return gl::Error(GL_NO_ERROR);
    129     }
    130 }
    131 
    132 gl::Error IndexBuffer9::discard()
    133 {
    134     if (!mIndexBuffer)
    135     {
    136         return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
    137     }
    138 
    139     void *dummy;
    140     HRESULT result;
    141 
    142     result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
    143     if (FAILED(result))
    144     {
    145         return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result);
    146     }
    147 
    148     result = mIndexBuffer->Unlock();
    149     if (FAILED(result))
    150     {
    151         return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result);
    152     }
    153 
    154     return gl::Error(GL_NO_ERROR);
    155 }
    156 
    157 D3DFORMAT IndexBuffer9::getIndexFormat() const
    158 {
    159     switch (mIndexType)
    160     {
    161       case GL_UNSIGNED_BYTE:    return D3DFMT_INDEX16;
    162       case GL_UNSIGNED_SHORT:   return D3DFMT_INDEX16;
    163       case GL_UNSIGNED_INT:     return D3DFMT_INDEX32;
    164       default: UNREACHABLE();   return D3DFMT_UNKNOWN;
    165     }
    166 }
    167 
    168 IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const
    169 {
    170     return mIndexBuffer;
    171 }
    172 
    173 }
    174