Fall back to drawing indexed points without indices in d3d9.

TRAC #22633

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1942 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index 6fc3f6b..06e7bfb 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -1427,7 +1427,11 @@
 {
     startScene();
 
-    if (mode == GL_LINE_LOOP)
+    if (mode == GL_POINTS)
+    {
+        drawIndexedPoints(count, type, indices, elementArrayBuffer);
+    }
+    else if (mode == GL_LINE_LOOP)
     {
         drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
     }
@@ -1610,6 +1614,37 @@
     mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
 }
 
+template <typename T>
+static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices)
+{
+    for (int i = 0; i < count; i++)
+    {
+        unsigned int indexValue = static_cast<unsigned int>(static_cast<const T*>(indices)[i]);
+        device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1);
+    }
+}
+
+void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer)
+{
+    // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call
+    // for each individual point. This call is not expected to happen often.
+
+    if (elementArrayBuffer)
+    {
+        BufferStorage *storage = elementArrayBuffer->getStorage();
+        intptr_t offset = reinterpret_cast<intptr_t>(indices);
+        indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+    }
+
+    switch (type)
+    {
+        case GL_UNSIGNED_BYTE:  drawPoints<GLubyte>(mDevice, count, indices);  break;
+        case GL_UNSIGNED_SHORT: drawPoints<GLushort>(mDevice, count, indices); break;
+        case GL_UNSIGNED_INT:   drawPoints<GLuint>(mDevice, count, indices);   break;
+        default: UNREACHABLE();
+    }
+}
+
 void Renderer9::applyShaders(gl::ProgramBinary *programBinary)
 {
     unsigned int programBinarySerial = programBinary->getSerial();
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index d247179..af76014 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -199,6 +199,7 @@
     void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v);
 
     void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
+    void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer);
 
     void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
     bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);