1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//
263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell// Use of this source code is governed by a BSD-style license that can be
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell// found in the LICENSE file.
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner//
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner
763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell
9589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#include "libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h"
10589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
11589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
12589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnernamespace rx
13589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner{
14589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
15551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid SpencerIndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
16551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer{
17589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner    mIndexBuffer = NULL;
188b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva    mBufferSize = 0;
19c7365a9ec96ff434d93d0d8052812283b33e537dReid Spencer    mIndexType = 0;
20c7365a9ec96ff434d93d0d8052812283b33e537dReid Spencer    mDynamic = false;
21d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke}
22d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
23589df88ba03a81b2b3dc9d084c191a3a74724ecdChris LattnerIndexBuffer9::~IndexBuffer9()
247e70829632f82de15db187845666aaca6e04b792Chris Lattner{
25589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner    SafeRelease(mIndexBuffer);
26589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
277e70829632f82de15db187845666aaca6e04b792Chris Lattner
287e70829632f82de15db187845666aaca6e04b792Chris Lattnergl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
297e70829632f82de15db187845666aaca6e04b792Chris Lattner{
307e70829632f82de15db187845666aaca6e04b792Chris Lattner    SafeRelease(mIndexBuffer);
317e70829632f82de15db187845666aaca6e04b792Chris Lattner
327e70829632f82de15db187845666aaca6e04b792Chris Lattner    updateSerial();
337e70829632f82de15db187845666aaca6e04b792Chris Lattner
347e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (bufferSize > 0)
357e70829632f82de15db187845666aaca6e04b792Chris Lattner    {
367e70829632f82de15db187845666aaca6e04b792Chris Lattner        D3DFORMAT format = D3DFMT_UNKNOWN;
377e70829632f82de15db187845666aaca6e04b792Chris Lattner        if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
387e70829632f82de15db187845666aaca6e04b792Chris Lattner        {
397e70829632f82de15db187845666aaca6e04b792Chris Lattner            format = D3DFMT_INDEX16;
407e70829632f82de15db187845666aaca6e04b792Chris Lattner        }
418b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner        else if (indexType == GL_UNSIGNED_INT)
427e70829632f82de15db187845666aaca6e04b792Chris Lattner        {
437e70829632f82de15db187845666aaca6e04b792Chris Lattner            ASSERT(mRenderer->getRendererExtensions().elementIndexUint);
447e70829632f82de15db187845666aaca6e04b792Chris Lattner            format = D3DFMT_INDEX32;
4521c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman        }
4621c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman        else UNREACHABLE();
4721c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman
488b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva        DWORD usageFlags = D3DUSAGE_WRITEONLY;
490179e977234fef45b1877eb93a3c7565cdd1862dDouglas Gregor        if (dynamic)
500179e977234fef45b1877eb93a3c7565cdd1862dDouglas Gregor        {
510179e977234fef45b1877eb93a3c7565cdd1862dDouglas Gregor            usageFlags |= D3DUSAGE_DYNAMIC;
520179e977234fef45b1877eb93a3c7565cdd1862dDouglas Gregor        }
530179e977234fef45b1877eb93a3c7565cdd1862dDouglas Gregor
547e70829632f82de15db187845666aaca6e04b792Chris Lattner        HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
558b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva        if (FAILED(result))
568b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva        {
578b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
588b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva        }
598b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva    }
608b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva
618b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva    mBufferSize = bufferSize;
628b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva    mIndexType = indexType;
638b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva    mDynamic = dynamic;
648b8fa7b2f403ae2f342413239c4151e075022c97Sean Silva
6521c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    return gl::Error(GL_NO_ERROR);
6621c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman}
6721c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman
687e70829632f82de15db187845666aaca6e04b792Chris LattnerIndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer)
697e70829632f82de15db187845666aaca6e04b792Chris Lattner{
707e70829632f82de15db187845666aaca6e04b792Chris Lattner    ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer));
7121c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    return static_cast<IndexBuffer9*>(indexBuffer);
7221c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman}
7321c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman
747e70829632f82de15db187845666aaca6e04b792Chris Lattnergl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
757e70829632f82de15db187845666aaca6e04b792Chris Lattner{
767e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (!mIndexBuffer)
7721c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    {
7821c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
79f5091b476c46333ecfcf095cd2e422e9748e9546Jordan Rose    }
8021c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman
817e70829632f82de15db187845666aaca6e04b792Chris Lattner    DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
827e70829632f82de15db187845666aaca6e04b792Chris Lattner
837e70829632f82de15db187845666aaca6e04b792Chris Lattner    void *mapPtr = NULL;
8421c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
8521c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    if (FAILED(result))
86f5091b476c46333ecfcf095cd2e422e9748e9546Jordan Rose    {
8721c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman        return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result);
887e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
897e70829632f82de15db187845666aaca6e04b792Chris Lattner
907e70829632f82de15db187845666aaca6e04b792Chris Lattner    *outMappedMemory = mapPtr;
9121c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    return gl::Error(GL_NO_ERROR);
9221c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman}
93f5091b476c46333ecfcf095cd2e422e9748e9546Jordan Rose
9421c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedmangl::Error IndexBuffer9::unmapBuffer()
957e70829632f82de15db187845666aaca6e04b792Chris Lattner{
967e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (!mIndexBuffer)
977e70829632f82de15db187845666aaca6e04b792Chris Lattner    {
9821c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
9921c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    }
10021c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman
10121c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    HRESULT result = mIndexBuffer->Unlock();
10221c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    if (FAILED(result))
10321c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    {
10421c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman        return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result);
10521c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    }
1067e70829632f82de15db187845666aaca6e04b792Chris Lattner
1077e70829632f82de15db187845666aaca6e04b792Chris Lattner    return gl::Error(GL_NO_ERROR);
1087e70829632f82de15db187845666aaca6e04b792Chris Lattner}
10921c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman
11021c60904ce6b937cb0c8744375e9c1a95fe0e495Eli FriedmanGLenum IndexBuffer9::getIndexType() const
11121c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman{
11221c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    return mIndexType;
11321c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman}
11421c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman
11521c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedmanunsigned int IndexBuffer9::getBufferSize() const
11621c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman{
11721c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman    return mBufferSize;
11821c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman}
11921c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman
12021c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedmangl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
12121c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman{
122589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner    if (bufferSize > mBufferSize || indexType != mIndexType)
1237e70829632f82de15db187845666aaca6e04b792Chris Lattner    {
12421c60904ce6b937cb0c8744375e9c1a95fe0e495Eli Friedman        return initialize(bufferSize, indexType, mDynamic);
125589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner    }
126589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner    else
1277e70829632f82de15db187845666aaca6e04b792Chris Lattner    {
1287e70829632f82de15db187845666aaca6e04b792Chris Lattner        return gl::Error(GL_NO_ERROR);
1297e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
1307e70829632f82de15db187845666aaca6e04b792Chris Lattner}
1317e70829632f82de15db187845666aaca6e04b792Chris Lattner
1327e70829632f82de15db187845666aaca6e04b792Chris Lattnergl::Error IndexBuffer9::discard()
1337e70829632f82de15db187845666aaca6e04b792Chris Lattner{
1347e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (!mIndexBuffer)
1357e70829632f82de15db187845666aaca6e04b792Chris Lattner    {
1367e70829632f82de15db187845666aaca6e04b792Chris Lattner        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
1377e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
1387e70829632f82de15db187845666aaca6e04b792Chris Lattner
1397e70829632f82de15db187845666aaca6e04b792Chris Lattner    void *dummy;
1407e70829632f82de15db187845666aaca6e04b792Chris Lattner    HRESULT result;
1417e70829632f82de15db187845666aaca6e04b792Chris Lattner
1427e70829632f82de15db187845666aaca6e04b792Chris Lattner    result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
1437e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (FAILED(result))
1447e70829632f82de15db187845666aaca6e04b792Chris Lattner    {
1457e70829632f82de15db187845666aaca6e04b792Chris Lattner        return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result);
1467e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
1477e70829632f82de15db187845666aaca6e04b792Chris Lattner
1487e70829632f82de15db187845666aaca6e04b792Chris Lattner    result = mIndexBuffer->Unlock();
1497e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (FAILED(result))
1507e70829632f82de15db187845666aaca6e04b792Chris Lattner    {
1517e70829632f82de15db187845666aaca6e04b792Chris Lattner        return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result);
1527e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
1537e70829632f82de15db187845666aaca6e04b792Chris Lattner
1547e70829632f82de15db187845666aaca6e04b792Chris Lattner    return gl::Error(GL_NO_ERROR);
1557e70829632f82de15db187845666aaca6e04b792Chris Lattner}
1567e70829632f82de15db187845666aaca6e04b792Chris Lattner
1577e70829632f82de15db187845666aaca6e04b792Chris LattnerD3DFORMAT IndexBuffer9::getIndexFormat() const
1587e70829632f82de15db187845666aaca6e04b792Chris Lattner{
1597e70829632f82de15db187845666aaca6e04b792Chris Lattner    switch (mIndexType)
1607e70829632f82de15db187845666aaca6e04b792Chris Lattner    {
1617e70829632f82de15db187845666aaca6e04b792Chris Lattner      case GL_UNSIGNED_BYTE:    return D3DFMT_INDEX16;
1627e70829632f82de15db187845666aaca6e04b792Chris Lattner      case GL_UNSIGNED_SHORT:   return D3DFMT_INDEX16;
1637e70829632f82de15db187845666aaca6e04b792Chris Lattner      case GL_UNSIGNED_INT:     return D3DFMT_INDEX32;
1647e70829632f82de15db187845666aaca6e04b792Chris Lattner      default: UNREACHABLE();   return D3DFMT_UNKNOWN;
1657e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
1667e70829632f82de15db187845666aaca6e04b792Chris Lattner}
1677e70829632f82de15db187845666aaca6e04b792Chris Lattner
1687e70829632f82de15db187845666aaca6e04b792Chris LattnerIDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const
1697e70829632f82de15db187845666aaca6e04b792Chris Lattner{
1707e70829632f82de15db187845666aaca6e04b792Chris Lattner    return mIndexBuffer;
1717e70829632f82de15db187845666aaca6e04b792Chris Lattner}
17263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
1735a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner}
1747e70829632f82de15db187845666aaca6e04b792Chris Lattner