Re-land "Validate that attrib offsets don't overflow buffers."

During draw calls, we wouldn't add the current attrib offset to the
required draw call size when checking attributes. This could lead to
us producing warnings in the D3D11 runtime, and miss returning some
errors.

Re-land with a test data initialization fix, and with some extra
tests merged from another CL.

BUG=angleproject:1339

Change-Id: Ifd549c3b1f6871417dc1693cb3ec534414e92cfd
Reviewed-on: https://chromium-review.googlesource.com/333723
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/tests/test_utils/ANGLETest.cpp b/src/tests/test_utils/ANGLETest.cpp
index ee14e6c..b308e11 100644
--- a/src/tests/test_utils/ANGLETest.cpp
+++ b/src/tests/test_utils/ANGLETest.cpp
@@ -65,7 +65,11 @@
 }  // namespace angle
 
 ANGLETest::ANGLETest()
-    : mEGLWindow(nullptr), mWidth(16), mHeight(16), mIgnoreD3D11SDKLayersWarnings(false)
+    : mEGLWindow(nullptr),
+      mWidth(16),
+      mHeight(16),
+      mIgnoreD3D11SDKLayersWarnings(false),
+      mQuadVertexBuffer(0)
 {
     mEGLWindow =
         new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
@@ -73,6 +77,10 @@
 
 ANGLETest::~ANGLETest()
 {
+    if (mQuadVertexBuffer)
+    {
+        glDeleteBuffers(1, &mQuadVertexBuffer);
+    }
     SafeDelete(mEGLWindow);
 }
 
@@ -183,6 +191,58 @@
     glUseProgram(0);
 }
 
+void ANGLETest::drawIndexedQuad(GLuint program,
+                                const std::string &positionAttribName,
+                                GLfloat positionAttribZ)
+{
+    drawIndexedQuad(program, positionAttribName, positionAttribZ, 1.0f);
+}
+
+void ANGLETest::drawIndexedQuad(GLuint program,
+                                const std::string &positionAttribName,
+                                GLfloat positionAttribZ,
+                                GLfloat positionAttribXYScale)
+{
+    GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
+
+    glUseProgram(program);
+
+    GLuint prevBinding = 0;
+    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, reinterpret_cast<GLint *>(&prevBinding));
+
+    if (mQuadVertexBuffer == 0)
+    {
+        glGenBuffers(1, &mQuadVertexBuffer);
+        const GLfloat vertices[] = {
+            -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale,  positionAttribZ,
+            -1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
+            1.0f * positionAttribXYScale,  -1.0f * positionAttribXYScale, positionAttribZ,
+            1.0f * positionAttribXYScale,  1.0f * positionAttribXYScale,  positionAttribZ,
+        };
+        glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
+        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 4, vertices, GL_STATIC_DRAW);
+    }
+    else
+    {
+        glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
+    }
+
+    glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
+    glEnableVertexAttribArray(positionLocation);
+    glBindBuffer(GL_ARRAY_BUFFER, prevBinding);
+
+    const GLushort indices[] = {
+        0, 1, 2, 0, 2, 3,
+    };
+
+    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+    glDisableVertexAttribArray(positionLocation);
+    glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
+
+    glUseProgram(0);
+}
+
 GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
 {
     GLuint shader = glCreateShader(type);