Implemented IndexBuffer11.

TRAC #22237

Author: Geoff Lang
Signed-off-by: Shannon Woods
Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1608 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/build_angle.gypi b/src/build_angle.gypi
index 0b35ca3..7aef523 100644
--- a/src/build_angle.gypi
+++ b/src/build_angle.gypi
@@ -262,6 +262,8 @@
             'libGLESv2/renderer/IndexBuffer.h',
             'libGLESv2/renderer/IndexBuffer9.cpp',
             'libGLESv2/renderer/IndexBuffer9.h',
+            'libGLESv2/renderer/IndexBuffer11.cpp',
+            'libGLESv2/renderer/IndexBuffer11.h',
             'libGLESv2/renderer/IndexDataManager.cpp',
             'libGLESv2/renderer/IndexDataManager.h',
             'libGLESv2/renderer/Renderer.cpp',
diff --git a/src/libGLESv2/libGLESv2.vcxproj b/src/libGLESv2/libGLESv2.vcxproj
index 9eeb532..093d454 100644
--- a/src/libGLESv2/libGLESv2.vcxproj
+++ b/src/libGLESv2/libGLESv2.vcxproj
@@ -248,6 +248,7 @@
     <ClCompile Include="renderer\Image.cpp" />

     <ClCompile Include="renderer\Image9.cpp" />

     <ClCompile Include="renderer\IndexBuffer.cpp" />

+    <ClCompile Include="renderer\IndexBuffer11.cpp" />

     <ClCompile Include="renderer\IndexBuffer9.cpp" />

     <ClCompile Include="renderer\IndexDataManager.cpp" />

     <ClCompile Include="renderer\ImageSSE2.cpp" />

@@ -302,6 +303,7 @@
     <ClInclude Include="renderer\Image11.h" />

     <ClInclude Include="renderer\Image9.h" />

     <ClInclude Include="renderer\IndexBuffer.h" />

+    <ClInclude Include="renderer\IndexBuffer11.h" />

     <ClInclude Include="renderer\IndexBuffer9.h" />

     <ClInclude Include="renderer\IndexDataManager.h" />

     <ClInclude Include="renderer\Renderer.h" />

diff --git a/src/libGLESv2/libGLESv2.vcxproj.filters b/src/libGLESv2/libGLESv2.vcxproj.filters
index bec23d8..bf0c4c9 100644
--- a/src/libGLESv2/libGLESv2.vcxproj.filters
+++ b/src/libGLESv2/libGLESv2.vcxproj.filters
@@ -158,6 +158,9 @@
     <ClCompile Include="renderer\IndexBuffer9.cpp">

       <Filter>Renderer</Filter>

     </ClCompile>

+    <ClCompile Include="renderer\IndexBuffer11.cpp">

+      <Filter>Renderer</Filter>

+    </ClCompile>

     <ClCompile Include="renderer\Image11.cpp">

       <Filter>Renderer</Filter>

     </ClCompile>

@@ -331,6 +334,9 @@
     <ClInclude Include="renderer\IndexBuffer9.h">

       <Filter>Renderer</Filter>

     </ClInclude>

+    <ClInclude Include="renderer\IndexBuffer11.h">

+      <Filter>Renderer</Filter>

+    </ClInclude>

     <ClInclude Include="renderer\Image11.h">

       <Filter>Renderer</Filter>

     </ClInclude>

diff --git a/src/libGLESv2/renderer/IndexBuffer11.cpp b/src/libGLESv2/renderer/IndexBuffer11.cpp
new file mode 100644
index 0000000..48c0c64
--- /dev/null
+++ b/src/libGLESv2/renderer/IndexBuffer11.cpp
@@ -0,0 +1,180 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
+
+#include "libGLESv2/renderer/IndexBuffer11.h"
+
+namespace rx
+{
+
+IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
+{
+    mBuffer = NULL;
+    mBufferSize = 0;
+    mDynamicUsage = false;
+}
+
+IndexBuffer11::~IndexBuffer11()
+{
+    if (mBuffer)
+    {
+        mBuffer->Release();
+        mBuffer = NULL;
+    }
+}
+
+bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+{
+    if (mBuffer)
+    {
+        mBuffer->Release();
+        mBuffer = NULL;
+    }
+
+    updateSerial();
+
+    if (bufferSize > 0)
+    {
+        ID3D11Device* dxDevice = mRenderer->getDevice();
+
+        D3D11_BUFFER_DESC bufferDesc;
+        bufferDesc.ByteWidth = bufferSize;
+        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+        bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        bufferDesc.MiscFlags = 0;
+        bufferDesc.StructureByteStride = 0;
+
+        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+        if (FAILED(result))
+        {
+            return false;
+        }
+    }
+
+    mBufferSize = bufferSize;
+    mIndexType = indexType;
+    mDynamicUsage = dynamic;
+
+    return true;
+}
+
+IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
+{
+    ASSERT(dynamic_cast<IndexBuffer11*>(indexBuffer) != NULL);
+    return static_cast<IndexBuffer11*>(indexBuffer);
+}
+
+bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+{
+    if (mBuffer)
+    {
+        if (offset + size > mBufferSize)
+        {
+            ERR("Index buffer map range is not inside the buffer.");
+            return false;
+        }
+
+        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
+        if (FAILED(result))
+        {
+            ERR("Index buffer map failed with error 0x%08x", result);
+            return false;
+        }
+
+        *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
+        return true;
+    }
+    else
+    {
+        ERR("Index buffer not initialized.");
+        return false;
+    }
+}
+
+bool IndexBuffer11::unmapBuffer()
+{
+    if (mBuffer)
+    {
+        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+        dxContext->Unmap(mBuffer, 0);
+        return true;
+    }
+    else
+    {
+        ERR("Index buffer not initialized.");
+        return false;
+    }
+}
+
+GLenum IndexBuffer11::getIndexType() const
+{
+    return mIndexType;
+}
+
+unsigned int IndexBuffer11::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
+{
+    if (bufferSize > mBufferSize || indexType != mIndexType)
+    {
+        return initialize(bufferSize, indexType, mDynamicUsage);
+    }
+    else
+    {
+        return true;
+    }
+}
+
+bool IndexBuffer11::discard()
+{
+    if (mBuffer)
+    {
+        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+        if (FAILED(result))
+        {
+            ERR("Index buffer map failed with error 0x%08x", result);
+            return false;
+        }
+
+        dxContext->Unmap(mBuffer, 0);
+
+        return true;
+    }
+    else
+    {
+        ERR("Index buffer not initialized.");
+        return false;
+    }
+}
+
+DXGI_FORMAT IndexBuffer11::getIndexFormat() const
+{
+    switch (mIndexType)
+    {
+      case GL_UNSIGNED_BYTE:    return DXGI_FORMAT_R16_UINT;
+      case GL_UNSIGNED_SHORT:   return DXGI_FORMAT_R16_UINT;
+      case GL_UNSIGNED_INT:     return DXGI_FORMAT_R32_UINT;
+      default: UNREACHABLE();   return DXGI_FORMAT_UNKNOWN;
+    }
+}
+
+ID3D11Buffer *IndexBuffer11::getBuffer() const
+{
+    return mBuffer;
+}
+
+}
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/IndexBuffer11.h b/src/libGLESv2/renderer/IndexBuffer11.h
new file mode 100644
index 0000000..658f1bc
--- /dev/null
+++ b/src/libGLESv2/renderer/IndexBuffer11.h
@@ -0,0 +1,55 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexBuffer11.h: Defines the D3D11 IndexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_INDEXBUFFER11_H_
+#define LIBGLESV2_RENDERER_INDEXBUFFER11_H_
+
+#include "libGLESv2/renderer/IndexBuffer.h"
+#include "libGLESv2/renderer/Renderer11.h"
+
+#include <d3d11.h>
+
+namespace rx
+{
+
+class IndexBuffer11 : public IndexBuffer
+{
+  public:
+    explicit IndexBuffer11(Renderer11 *const renderer);
+    virtual ~IndexBuffer11();
+
+    virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+
+    static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer);
+
+    virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
+    virtual bool unmapBuffer();
+
+    virtual GLenum getIndexType() const;
+    virtual unsigned int getBufferSize() const;
+    virtual bool setSize(unsigned int bufferSize, GLenum indexType);
+
+    virtual bool discard();
+
+    DXGI_FORMAT getIndexFormat() const;
+    ID3D11Buffer *getBuffer() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(IndexBuffer11);
+
+    rx::Renderer11 *const mRenderer;
+
+    ID3D11Buffer *mBuffer;
+    unsigned int mBufferSize;
+    GLenum mIndexType;
+    bool mDynamicUsage;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_INDEXBUFFER11_H_
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index d2b222a..626b6d1 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -21,6 +21,7 @@
 #include "libGLESv2/renderer/SwapChain11.h"
 #include "libGLESv2/renderer/Image11.h"
 #include "libGLESv2/renderer/VertexBuffer11.h"
+#include "libGLESv2/renderer/IndexBuffer11.h"
 
 #include "libEGL/Config.h"
 #include "libEGL/Display.h"
@@ -1256,9 +1257,7 @@
 
 IndexBuffer *Renderer11::createIndexBuffer()
 {
-    // TODO
-    UNIMPLEMENTED();
-    return NULL;
+    return new IndexBuffer11(this);
 }
 
 bool Renderer11::blitRect(gl::Framebuffer *readTarget, gl::Rectangle *readRect, gl::Framebuffer *drawTarget, gl::Rectangle *drawRect,