Vulkan: Implement PACK_STATE dirty bit and remove warning

- also enables all dEQP tests for functional.read_pixels.*

Bug: angleproject:2480

Change-Id: Ib7bcd6b046ff8b0ecf110e70f735036bedf17902
Reviewed-on: https://chromium-review.googlesource.com/1058149
Commit-Queue: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 25f6edb..5fb95b9 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -520,7 +520,8 @@
                 WARN() << "DIRTY_BIT_UNPACK_BUFFER_BINDING unimplemented";
                 break;
             case gl::State::DIRTY_BIT_PACK_STATE:
-                WARN() << "DIRTY_BIT_PACK_STATE unimplemented";
+                // This is a no-op, its only important to use the right pack state when we do
+                // call readPixels later on.
                 break;
             case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
                 WARN() << "DIRTY_BIT_PACK_BUFFER_BINDING unimplemented";
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 8a2be4c..c1151a0 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -38,7 +38,7 @@
         renderTarget->image->getFormat().textureFormat().fboImplementationInternalFormat;
     return gl::GetSizedInternalFormatInfo(implFormat);
 }
-}  // anonymous namespace
+}  // anonymous namespace<
 
 // static
 FramebufferVk *FramebufferVk::CreateUserFBO(const gl::FramebufferState &state)
@@ -276,12 +276,33 @@
                                     GLenum type,
                                     void *pixels)
 {
+    // Clip read area to framebuffer.
+    const gl::Extents &fbSize = getState().getReadAttachment()->getSize();
+    const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
+    gl::Rectangle clippedArea;
+    if (!ClipRectangle(area, fbRect, &clippedArea))
+    {
+        // nothing to read
+        return gl::NoError();
+    }
+
     const gl::State &glState = context->getGLState();
     RenderTargetVk *renderTarget = getColorReadRenderTarget();
     ASSERT(renderTarget);
 
-    const angle::Format &angleFormat = renderTarget->image->getFormat().textureFormat();
-    GLuint outputPitch               = angleFormat.pixelBytes * area.width;
+    const gl::PixelPackState &packState       = context->getGLState().getPackState();
+    const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type);
+
+    GLuint outputPitch = 0;
+    ANGLE_TRY_RESULT(
+        sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength),
+        outputPitch);
+    GLuint outputSkipBytes = 0;
+    ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, packState, false),
+                     outputSkipBytes);
+
+    outputSkipBytes += (clippedArea.x - area.x) * sizedFormatInfo.pixelBytes +
+                       (clippedArea.y - area.y) * outputPitch;
 
     PackPixelsParams params;
     params.area        = area;
@@ -293,7 +314,8 @@
 
     vk::CommandBuffer *commandBuffer = nullptr;
     ANGLE_TRY(beginWriteResource(vk::GetImpl(context)->getRenderer(), &commandBuffer));
-    return ReadPixelsFromRenderTarget(context, area, params, renderTarget, commandBuffer, pixels);
+    return ReadPixelsFromRenderTarget(context, clippedArea, params, renderTarget, commandBuffer,
+                                      reinterpret_cast<uint8_t *>(pixels) + outputSkipBytes);
 }
 
 RenderTargetVk *FramebufferVk::getColorReadRenderTarget()
diff --git a/src/tests/deqp_support/deqp_gles2_test_expectations.txt b/src/tests/deqp_support/deqp_gles2_test_expectations.txt
index ec3528d..07056e7 100644
--- a/src/tests/deqp_support/deqp_gles2_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles2_test_expectations.txt
@@ -283,7 +283,6 @@
 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.basic_array_assign_partial.multiple_basic_array.* = SKIP
 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.unused_uniforms.* = SKIP
 2161 VULKAN : dEQP-GLES2.functional.uniform_api.random.* = SKIP
-2161 VULKAN : dEQP-GLES2.functional.read_pixels.* = SKIP
 2161 VULKAN : dEQP-GLES2.functional.dither.* = SKIP
 2161 VULKAN : dEQP-GLES2.functional.state_query.* = SKIP
 2161 VULKAN : dEQP-GLES2.functional.clipping.* = SKIP