Implement max elements indices and vertices.

ES3 has integer queries for the maximum recommended number
of vertices and indices per draw call. These are roughly
correlated to D3D's resource limits -- however, while ES3
has recommended limits D3D has hard limits.

Change-Id: Ib653bc27e61607c78d0c5e70b0d97fea7af6464f
Reviewed-on: https://chromium-review.googlesource.com/179670
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
Commit-Queue: Nicolas Capens <nicolascapens@chromium.org>
Tested-by: Nicolas Capens <nicolascapens@chromium.org>
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index db2ddb3..2c4ffe8 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1688,6 +1688,8 @@
       case GL_MAX_COMBINED_UNIFORM_BLOCKS:              *params = getMaximumCombinedUniformBufferBindings();            break;
       case GL_MAJOR_VERSION:                            *params = mClientVersion;                                       break;
       case GL_MINOR_VERSION:                            *params = 0;                                                    break;
+      case GL_MAX_ELEMENTS_INDICES:                     *params = mRenderer->getMaxRecommendedElementsIndices();        break;
+      case GL_MAX_ELEMENTS_VERTICES:                    *params = mRenderer->getMaxRecommendedElementsVertices();       break;
       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:  *params = 0; UNIMPLEMENTED();                                   break;
       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   
         params[0] = mNumCompressedTextureFormats;
@@ -2227,6 +2229,8 @@
       case GL_NUM_EXTENSIONS:
       case GL_MAJOR_VERSION:
       case GL_MINOR_VERSION:
+      case GL_MAX_ELEMENTS_INDICES:
+      case GL_MAX_ELEMENTS_VERTICES:
         {
             *type = GL_INT;
             *numParams = 1;
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 912fe90..7e06fc2 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -198,6 +198,8 @@
     virtual bool getShareHandleSupport() const = 0;
     virtual bool getDerivativeInstructionSupport() const = 0;
     virtual bool getPostSubBufferSupport() const = 0;
+    virtual int getMaxRecommendedElementsIndices() const = 0;
+    virtual int getMaxRecommendedElementsVertices() const = 0;
 
     virtual int getMajorShaderModel() const = 0;
     virtual float getMaxPointSize() const = 0;
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index 652d1bc..233aa63 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -2165,6 +2165,24 @@
     return false;
 }
 
+int Renderer11::getMaxRecommendedElementsIndices() const
+{
+    META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
+    META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
+
+    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience.
+    return std::numeric_limits<GLint>::max();
+}
+
+int Renderer11::getMaxRecommendedElementsVertices() const
+{
+    META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
+    META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
+
+    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience.
+    return std::numeric_limits<GLint>::max();
+}
+
 int Renderer11::getMajorShaderModel() const
 {
     switch (mFeatureLevel)
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d11/Renderer11.h
index 4169bbe..30d5b22 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.h
@@ -136,6 +136,8 @@
     virtual bool getShareHandleSupport() const;
     virtual bool getDerivativeInstructionSupport() const;
     virtual bool getPostSubBufferSupport() const;
+    virtual int getMaxRecommendedElementsIndices() const;
+    virtual int getMaxRecommendedElementsVertices() const;
 
     virtual int getMajorShaderModel() const;
     virtual float getMaxPointSize() const;
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
index 87e6420..c47cf1c 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
@@ -1413,7 +1413,7 @@
     {
         return err;
     }
-    
+
     return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw);
 }
 
@@ -1442,7 +1442,7 @@
 void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
 {
     startScene();
-        
+
     if (mode == GL_LINE_LOOP)
     {
         drawLineLoop(count, GL_NONE, NULL, 0, NULL);
@@ -2521,6 +2521,20 @@
     return true;
 }
 
+int Renderer9::getMaxRecommendedElementsIndices() const
+{
+    // ES3 only
+    UNREACHABLE();
+    return 0;
+}
+
+int Renderer9::getMaxRecommendedElementsVertices() const
+{
+    // ES3 only
+    UNREACHABLE();
+    return 0;
+}
+
 int Renderer9::getMajorShaderModel() const
 {
     return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
@@ -2597,7 +2611,7 @@
 {
     D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this);
     MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format);
-    
+
     unsigned int numCounts = 0;
     if (iter != mMultiSampleSupport.end())
     {
@@ -2726,7 +2740,7 @@
         {
             IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false);
             IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false);
-            
+
             result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
 
             SafeRelease(srcSurf);
@@ -3029,7 +3043,7 @@
     return true;
 }
 
-void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, 
+void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
                            GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
 {
     RenderTarget9 *renderTarget = NULL;
@@ -3040,7 +3054,7 @@
     {
         renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
     }
-    
+
     if (renderTarget)
     {
         surface = renderTarget->getSurface();
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d9/Renderer9.h
index d7a1b28..314cfd6 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.h
@@ -149,6 +149,8 @@
     virtual bool getShareHandleSupport() const;
     virtual bool getDerivativeInstructionSupport() const;
     virtual bool getPostSubBufferSupport() const;
+    virtual int getMaxRecommendedElementsIndices() const;
+    virtual int getMaxRecommendedElementsVertices() const;
 
     virtual int getMajorShaderModel() const;
     virtual float getMaxPointSize() const;