Vulkan: Always use LOAD for RenderPass attachments.

The RenderPass load/store ops allow us to specify how we want to use
the data from the attachments. Previously we had the load op set to
CLEAR always, which would prevent us from doing multiple kinds of
operation. Using LOAD should conversatively work in any situation
as long as we can ensure each Image is cleared before we use it.

To this effect this patch also inserts a preliminary clear into each
Texture or Renderbuffer Image's initialization. We already had this
for Surfaces.

In the future we'll improve this by inserting proper load/store ops,
but this unblocks a lot more functionality in the interim.

Bug: angleproject:2361
Change-Id: I7610eaa39d81b23dd74b4a24b7f28a66a6dfffc6
Reviewed-on: https://chromium-review.googlesource.com/948782
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 45641c0..8d22dbf 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -467,7 +467,8 @@
     return gl::InternalError() << "getSamplePosition is unimplemented.";
 }
 
-gl::Error FramebufferVk::getRenderNode(const gl::Context *context, vk::CommandGraphNode **nodeOut)
+gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
+                                                    vk::CommandGraphNode **nodeOut)
 {
     ContextVk *contextVk = vk::GetImpl(context);
     RendererVk *renderer = contextVk->getRenderer();
@@ -487,6 +488,10 @@
 
     std::vector<VkClearValue> attachmentClearValues;
 
+    vk::CommandBuffer *commandBuffer = nullptr;
+    ANGLE_TRY(node->beginOutsideRenderPassRecording(renderer->getDevice(),
+                                                    renderer->getCommandPool(), &commandBuffer));
+
     // Initialize RenderPass info.
     // TODO(jmadill): Could cache this info, would require dependent state change messaging.
     const auto &colorAttachments = mState.getColorAttachments();
@@ -498,8 +503,11 @@
             RenderTargetVk *renderTarget = nullptr;
             ANGLE_SWALLOW_ERR(colorAttachment.getRenderTarget(context, &renderTarget));
 
-            // TODO(jmadill): May need layout transition.
-            renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+            // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
+            renderTarget->image->changeLayoutWithStages(
+                VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                commandBuffer);
             node->appendColorRenderTarget(currentSerial, renderTarget);
             attachmentClearValues.emplace_back(contextVk->getClearColorValue());
         }
@@ -511,8 +519,15 @@
         RenderTargetVk *renderTarget = nullptr;
         ANGLE_SWALLOW_ERR(depthStencilAttachment->getRenderTarget(context, &renderTarget));
 
-        // TODO(jmadill): May need layout transition.
-        renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+        // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
+        const angle::Format &format    = renderTarget->format->textureFormat();
+        VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
+                                         (format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
+
+        renderTarget->image->changeLayoutWithStages(
+            aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+            VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+            commandBuffer);
         node->appendDepthStencilRenderTarget(currentSerial, renderTarget);
         attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
     }