Vulkan: Create TextureVk's Image lazily.

This defers the actual Image initialization until the Image is used
as either a Framebuffer Attachment or OpenGL Texture object. This
will allow us to construct an Image from multiple sub resources, like
when we're initializing a mip chain, or a cube map texture.

Also adds a helper "hasDepthOrStencilBits" function to angle::Format.

Bug: angleproject:2318
Change-Id: Ife861560216581a90fc6da32a583f69886c7daea
Reviewed-on: https://chromium-review.googlesource.com/985202
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.cpp b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
index fe0b95f..ee4403a 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.cpp
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
@@ -12,6 +12,7 @@
 #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
 #include "libANGLE/renderer/vulkan/RendererVk.h"
 #include "libANGLE/renderer/vulkan/vk_format_utils.h"
+#include "libANGLE/renderer/vulkan/vk_helpers.h"
 
 namespace rx
 {
@@ -142,7 +143,8 @@
 
 bool CommandGraphResource::checkResourceInUseAndRefreshDeps(RendererVk *renderer)
 {
-    if (!renderer->isResourceInUse(*this))
+    if (!renderer->isResourceInUse(*this) ||
+        (renderer->getCurrentQueueSerial() > mStoredQueueSerial))
     {
         mCurrentReadingNodes.clear();
         mCurrentWritingNode = nullptr;
@@ -243,6 +245,14 @@
 
 void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget)
 {
+    ASSERT(mOutsideRenderPassCommands.valid());
+
+    // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
+    colorRenderTarget->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,
+        &mOutsideRenderPassCommands);
+
     mRenderPassDesc.packColorAttachment(*colorRenderTarget->image);
     colorRenderTarget->resource->onWriteResource(this, serial);
 }
@@ -250,6 +260,19 @@
 void CommandGraphNode::appendDepthStencilRenderTarget(Serial serial,
                                                       RenderTargetVk *depthStencilRenderTarget)
 {
+    ASSERT(mOutsideRenderPassCommands.valid());
+    ASSERT(depthStencilRenderTarget->image->getFormat().textureFormat().hasDepthOrStencilBits());
+
+    // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
+    const angle::Format &format    = depthStencilRenderTarget->image->getFormat().textureFormat();
+    VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
+                                     (format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
+
+    depthStencilRenderTarget->image->changeLayoutWithStages(
+        aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+        &mOutsideRenderPassCommands);
+
     mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
     depthStencilRenderTarget->resource->onWriteResource(this, serial);
 }