Vulkan: Only init RenderPass once per frame.

This saves some time spent in the driver, by making multiple draw
calls happen inside a single RenderPass.

This also makes the ReadPixels impl method non-const. I think in
the future we should avoid making const Impl methods unless they're
totally trivial.

BUG=angleproject:1898

Change-Id: I39172270a2f7dc5c1c2e3d4cc50af3bac8a29fa1
Reviewed-on: https://chromium-review.googlesource.com/672148
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index c124d27..07559c3 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -81,12 +81,20 @@
 }
 
 FramebufferVk::FramebufferVk(const gl::FramebufferState &state)
-    : FramebufferImpl(state), mBackbuffer(nullptr), mRenderPass(), mFramebuffer()
+    : FramebufferImpl(state),
+      mBackbuffer(nullptr),
+      mRenderPass(),
+      mFramebuffer(),
+      mInRenderPass(false)
 {
 }
 
 FramebufferVk::FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer)
-    : FramebufferImpl(state), mBackbuffer(backbuffer), mRenderPass(), mFramebuffer()
+    : FramebufferImpl(state),
+      mBackbuffer(backbuffer),
+      mRenderPass(),
+      mFramebuffer(),
+      mInRenderPass(false)
 {
 }
 
@@ -96,6 +104,8 @@
 
 void FramebufferVk::destroy(const gl::Context *context)
 {
+    ASSERT(!mInRenderPass);
+
     VkDevice device = GetImplAs<ContextVk>(context)->getDevice();
 
     mRenderPass.destroy(device);
@@ -257,7 +267,7 @@
                                     const gl::Rectangle &area,
                                     GLenum format,
                                     GLenum type,
-                                    void *pixels) const
+                                    void *pixels)
 {
     const auto &glState         = context->getGLState();
     const auto *readFramebuffer = glState.getReadFramebuffer();
@@ -278,6 +288,9 @@
     vk::CommandBuffer *commandBuffer = nullptr;
     ANGLE_TRY(contextVk->getStartedCommandBuffer(&commandBuffer));
 
+    // End render pass if we're in one.
+    endRenderPass(commandBuffer);
+
     stagingImage.getImage().changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
                                             commandBuffer);
 
@@ -543,12 +556,19 @@
     return gl::InternalError() << "getSamplePosition is unimplemented.";
 }
 
-gl::Error FramebufferVk::beginRenderPass(const gl::Context *context,
-                                         VkDevice device,
-                                         vk::CommandBuffer *commandBuffer,
-                                         Serial queueSerial,
-                                         const gl::State &glState)
+gl::Error FramebufferVk::ensureInRenderPass(const gl::Context *context,
+                                            VkDevice device,
+                                            vk::CommandBuffer *commandBuffer,
+                                            Serial queueSerial,
+                                            const gl::State &glState)
 {
+    if (mInRenderPass)
+    {
+        return gl::NoError();
+    }
+
+    mInRenderPass = true;
+
     // TODO(jmadill): Cache render targets.
     for (const auto &colorAttachment : mState.getColorAttachments())
     {
@@ -607,4 +627,13 @@
     return gl::NoError();
 }
 
+void FramebufferVk::endRenderPass(vk::CommandBuffer *commandBuffer)
+{
+    if (mInRenderPass)
+    {
+        commandBuffer->endRenderPass();
+        mInRenderPass = false;
+    }
+}
+
 }  // namespace rx