Vulkan: Implement robustness extensions.

Device recovery is not possible but device loss can be tracked.

BUG=angleproject:2787

Change-Id: Ib94dd557b6b005a560b7a64275b176f7b1777211
Reviewed-on: https://chromium-review.googlesource.com/1194458
Reviewed-by: Tobin Ehlis <tobine@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 52d62c9..b8ddd83 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -563,7 +563,14 @@
 
 GLenum ContextVk::getResetStatus()
 {
-    UNIMPLEMENTED();
+    if (mRenderer->isDeviceLost())
+    {
+        // TODO(geofflang): It may be possible to track which context caused the device lost and
+        // return either GL_GUILTY_CONTEXT_RESET or GL_INNOCENT_CONTEXT_RESET.
+        // http://anglebug.com/2787
+        return GL_UNKNOWN_CONTEXT_RESET;
+    }
+
     return GL_NO_ERROR;
 }
 
@@ -1175,6 +1182,11 @@
     errorStream << "Internal Vulkan error: " << VulkanResultString(errorCode) << ", in " << file
                 << ", line " << line << ".";
 
+    if (errorCode == VK_ERROR_DEVICE_LOST)
+    {
+        mRenderer->markDeviceLost();
+    }
+
     mErrors->handleError(gl::Error(glErrorCode, glErrorCode, errorStream.str()));
 }
 
diff --git a/src/libANGLE/renderer/vulkan/DisplayVk.cpp b/src/libANGLE/renderer/vulkan/DisplayVk.cpp
index 324d52a..43ce101 100644
--- a/src/libANGLE/renderer/vulkan/DisplayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/DisplayVk.cpp
@@ -52,14 +52,14 @@
 
 bool DisplayVk::testDeviceLost()
 {
-    // TODO(jmadill): Figure out how to do device lost in Vulkan.
-    return false;
+    return mRenderer->isDeviceLost();
 }
 
 egl::Error DisplayVk::restoreLostDevice(const egl::Display *display)
 {
-    UNIMPLEMENTED();
-    return egl::EglBadAccess();
+    // A vulkan device cannot be restored, the entire renderer would have to be re-created along
+    // with any other EGL objects that reference it.
+    return egl::EglBadDisplay();
 }
 
 std::string DisplayVk::getVendorString() const
@@ -165,6 +165,7 @@
 
 void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
 {
+    outExtensions->createContextRobustness  = true;
     outExtensions->surfaceOrientation       = true;
     outExtensions->displayTextureShareGroup = true;
 
@@ -193,6 +194,11 @@
     errorStream << "Internal Vulkan error: " << VulkanResultString(result) << ", in " << file
                 << ", line " << line << ".";
     mStoredErrorString = errorStream.str();
+
+    if (result == VK_ERROR_DEVICE_LOST)
+    {
+        mRenderer->markDeviceLost();
+    }
 }
 
 // TODO(jmadill): Remove this. http://anglebug.com/2491
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index cd474fd..dfb0619 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -299,6 +299,7 @@
       mDevice(VK_NULL_HANDLE),
       mLastCompletedQueueSerial(mQueueSerialFactory.generate()),
       mCurrentQueueSerial(mQueueSerialFactory.generate()),
+      mDeviceLost(false),
       mPipelineCacheVkUpdateTimeout(kPipelineCacheVkUpdatePeriod)
 {
 }
@@ -355,6 +356,16 @@
     mPhysicalDevice = VK_NULL_HANDLE;
 }
 
+void RendererVk::markDeviceLost()
+{
+    mDeviceLost = true;
+}
+
+bool RendererVk::isDeviceLost() const
+{
+    return mDeviceLost;
+}
+
 angle::Result RendererVk::initialize(DisplayVk *displayVk,
                                      const egl::AttributeMap &attribs,
                                      const char *wsiName)
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.h b/src/libANGLE/renderer/vulkan/RendererVk.h
index 0c02e50..ce4592b 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.h
+++ b/src/libANGLE/renderer/vulkan/RendererVk.h
@@ -48,6 +48,9 @@
                              const char *wsiName);
     void onDestroy(vk::Context *context);
 
+    void markDeviceLost();
+    bool isDeviceLost() const;
+
     std::string getVendorString() const;
     std::string getRendererDescription() const;
 
@@ -183,6 +186,8 @@
     Serial mLastCompletedQueueSerial;
     Serial mCurrentQueueSerial;
 
+    bool mDeviceLost;
+
     struct CommandBatch final : angle::NonCopyable
     {
         CommandBatch();
diff --git a/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp b/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
index e4040e3..9be57d9 100644
--- a/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
@@ -46,6 +46,7 @@
     outExtensions->framebufferBlit = true;
     outExtensions->copyTexture     = true;
     outExtensions->debugMarker     = true;
+    outExtensions->robustness      = true;
 
     // TODO(lucferron): Eventually remove everything above this line in this function as the caps
     // get implemented.