Vulkan: Implement EGL Images for 2D and Renderbuffer sources.

No support for non-zero mipmaps as sources yet.

Suppress dEQP tests due to apparent driver bugs with scissored clears on depth
or stencil attachments.

BUG=angleproject:2668

Change-Id: Idaa5e70ce9b0c91232fbb989cbf4de1b9134aafb
Reviewed-on: https://chromium-review.googlesource.com/c/1415010
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
index 9eb9445..5640703 100644
--- a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
@@ -10,7 +10,9 @@
 #include "libANGLE/renderer/vulkan/RenderbufferVk.h"
 
 #include "libANGLE/Context.h"
+#include "libANGLE/Image.h"
 #include "libANGLE/renderer/vulkan/ContextVk.h"
+#include "libANGLE/renderer/vulkan/ImageVk.h"
 #include "libANGLE/renderer/vulkan/RendererVk.h"
 
 namespace rx
@@ -24,7 +26,7 @@
 }  // anonymous namespace
 
 RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
-    : RenderbufferImpl(state), mImage(nullptr)
+    : RenderbufferImpl(state), mOwnsImage(false), mImage(nullptr)
 {}
 
 RenderbufferVk::~RenderbufferVk() {}
@@ -33,15 +35,7 @@
 {
     ContextVk *contextVk = vk::GetImpl(context);
     RendererVk *renderer = contextVk->getRenderer();
-
-    if (mImage)
-    {
-        mImage->releaseImage(renderer);
-        mImage->releaseStagingBuffer(renderer);
-        SafeDelete(mImage);
-    }
-
-    renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
+    releaseAndDeleteImage(context, renderer);
 }
 
 angle::Result RenderbufferVk::setStorage(const gl::Context *context,
@@ -53,6 +47,11 @@
     RendererVk *renderer       = contextVk->getRenderer();
     const vk::Format &vkFormat = renderer->getFormat(internalformat);
 
+    if (!mOwnsImage)
+    {
+        releaseAndDeleteImage(context, renderer);
+    }
+
     if (mImage != nullptr && mImage->valid())
     {
         // Check against the state if we need to recreate the storage.
@@ -60,8 +59,7 @@
             static_cast<GLsizei>(width) != mState.getWidth() ||
             static_cast<GLsizei>(height) != mState.getHeight())
         {
-            mImage->releaseImage(renderer);
-            renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
+            releaseImage(context, renderer);
         }
     }
 
@@ -69,7 +67,8 @@
     {
         if (mImage == nullptr)
         {
-            mImage = new vk::ImageHelper();
+            mImage     = new vk::ImageHelper();
+            mOwnsImage = true;
         }
 
         const angle::Format &textureFormat = vkFormat.textureFormat();
@@ -126,8 +125,26 @@
 angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *context,
                                                        egl::Image *image)
 {
-    ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
-    return angle::Result::Stop;
+    ContextVk *contextVk = vk::GetImpl(context);
+    RendererVk *renderer = contextVk->getRenderer();
+
+    releaseAndDeleteImage(context, renderer);
+
+    ImageVk *imageVk = vk::GetImpl(image);
+    mImage           = imageVk->getImage();
+    mOwnsImage       = false;
+
+    const vk::Format &vkFormat = renderer->getFormat(image->getFormat().info->sizedInternalFormat);
+    const angle::Format &textureFormat = vkFormat.textureFormat();
+
+    VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
+
+    ANGLE_TRY(mImage->initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
+                                    &mImageView, 1));
+
+    mRenderTarget.init(mImage, &mImageView, 0, nullptr);
+
+    return angle::Result::Continue;
 }
 
 angle::Result RenderbufferVk::getAttachmentRenderTarget(const gl::Context *context,
@@ -147,4 +164,34 @@
     return angle::Result::Continue;
 }
 
+void RenderbufferVk::releaseOwnershipOfImage(const gl::Context *context)
+{
+    ContextVk *contextVk = vk::GetImpl(context);
+    RendererVk *renderer = contextVk->getRenderer();
+
+    mOwnsImage = false;
+    releaseAndDeleteImage(context, renderer);
+}
+
+void RenderbufferVk::releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer)
+{
+    releaseImage(context, renderer);
+    SafeDelete(mImage);
+}
+
+void RenderbufferVk::releaseImage(const gl::Context *context, RendererVk *renderer)
+{
+    if (mImage && mOwnsImage)
+    {
+        mImage->releaseImage(renderer);
+        mImage->releaseStagingBuffer(renderer);
+    }
+    else
+    {
+        mImage = nullptr;
+    }
+
+    renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
+}
+
 }  // namespace rx