Implement glDrawArraysInstanced by constructing a 'counting' index buffer since D3D9 only supports instancing on indexed draw calls.

TRAC #19489
Signed-off-by: Daniel Koch
Author: Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/trunk@972 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/IndexDataManager.cpp b/src/libGLESv2/IndexDataManager.cpp
index e6630b1..e2e307d 100644
--- a/src/libGLESv2/IndexDataManager.cpp
+++ b/src/libGLESv2/IndexDataManager.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-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.
 //
@@ -48,12 +48,15 @@
     {
         ERR("Failed to allocate the streaming index buffer(s).");
     }
+
+    mCountingBuffer = NULL;
 }
 
 IndexDataManager::~IndexDataManager()
 {
     delete mStreamingBufferShort;
     delete mStreamingBufferInt;
+    delete mCountingBuffer;
 }
 
 void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
@@ -228,6 +231,61 @@
     }
 }
 
+StaticIndexBuffer *IndexDataManager::getCountingIndices(GLsizei count)
+{
+    if (count <= 65536)   // 16-bit indices
+    {
+        const unsigned int spaceNeeded = count * sizeof(unsigned short);
+
+        if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
+        {
+            delete mCountingBuffer;
+            mCountingBuffer = new StaticIndexBuffer(mDevice);
+            mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
+
+            UINT offset;
+            unsigned short *data = static_cast<unsigned short*>(mCountingBuffer->map(spaceNeeded, &offset));
+        
+            if (data)
+            {
+                for(int i = 0; i < count; i++)
+                {
+                    data[i] = i;
+                }
+
+                mCountingBuffer->unmap();
+            }
+        }
+    }
+    else if (mStreamingBufferInt)   // 32-bit indices supported
+    {
+        const unsigned int spaceNeeded = count * sizeof(unsigned int);
+
+        if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
+        {
+            delete mCountingBuffer;
+            mCountingBuffer = new StaticIndexBuffer(mDevice);
+            mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
+
+            UINT offset;
+            unsigned int *data = static_cast<unsigned int*>(mCountingBuffer->map(spaceNeeded, &offset));
+        
+            if (data)
+            {
+                for(int i = 0; i < count; i++)
+                {
+                    data[i] = i;
+                }
+                
+                mCountingBuffer->unmap();
+            }
+        }
+    }
+    else return NULL;
+    
+    return mCountingBuffer;
+}
+
 IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL)
 {
     if (size > 0)