Implement copies from pack buffers to native buffers.

Full support for using pack buffers as vertex buffers or other
binding points requires us to copy through the staging buffer.

BUG=angle:511

Change-Id: Ife0f5390a1a83dfbe0fa0b19db72f3a8b82b6b83
Reviewed-on: https://chromium-review.googlesource.com/198435
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/tests/angle_tests/ReadPixelsTest.cpp b/tests/angle_tests/ReadPixelsTest.cpp
index de38838..70efe99 100644
--- a/tests/angle_tests/ReadPixelsTest.cpp
+++ b/tests/angle_tests/ReadPixelsTest.cpp
@@ -240,3 +240,56 @@
     glUnmapBuffer(GL_ARRAY_BUFFER);
     EXPECT_GL_NO_ERROR();
 }
+
+TEST_F(ReadPixelsTest, draw_with_pbo)
+{
+    unsigned char data[4] = { 1, 2, 3, 4 };
+
+    glBindTexture(GL_TEXTURE_2D, mTexture);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
+    EXPECT_GL_NO_ERROR();
+
+    // glReadBuffer(GL_COLOR_ATTACHMENT0); // FIXME: currently UNIMPLEMENTED
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+    EXPECT_GL_NO_ERROR();
+
+    float positionData[] = { 0.5f, 0.5f };
+
+    glUseProgram(mProgram);
+    glViewport(0, 0, 1, 1);
+    glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
+    glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
+    EXPECT_GL_NO_ERROR();
+
+    GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
+    EXPECT_NE(-1, positionLocation);
+
+    GLint testLocation = glGetAttribLocation(mProgram, "aTest");
+    EXPECT_NE(-1, testLocation);
+
+    glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
+    glEnableVertexAttribArray(positionLocation);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
+    glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
+    glEnableVertexAttribArray(testLocation);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    memset(data, 0, 4);
+    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_EQ(1, data[0]);
+    EXPECT_EQ(2, data[1]);
+    EXPECT_EQ(3, data[2]);
+    EXPECT_EQ(4, data[3]);
+}