Vulkan: Handle errors when creating VkRenderPass

BUG=dawn:19

Change-Id: I6007fb594a7c073b835554ca6914453a67608947
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11863
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp
index 327bf4f..0e2d003 100644
--- a/src/dawn_native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn_native/vulkan/CommandBufferVk.cpp
@@ -29,6 +29,7 @@
 #include "dawn_native/vulkan/RenderPipelineVk.h"
 #include "dawn_native/vulkan/TextureVk.h"
 #include "dawn_native/vulkan/UtilsVulkan.h"
+#include "dawn_native/vulkan/VulkanError.h"
 
 namespace dawn_native { namespace vulkan {
 
@@ -105,9 +106,9 @@
             }
         };
 
-        void RecordBeginRenderPass(CommandRecordingContext* recordingContext,
-                                   Device* device,
-                                   BeginRenderPassCmd* renderPass) {
+        MaybeError RecordBeginRenderPass(CommandRecordingContext* recordingContext,
+                                         Device* device,
+                                         BeginRenderPassCmd* renderPass) {
             VkCommandBuffer commands = recordingContext->commandBuffer;
 
             // Query a VkRenderPass from the cache
@@ -197,7 +198,7 @@
 
                 query.SetSampleCount(renderPass->attachmentState->GetSampleCount());
 
-                renderPassVK = device->GetRenderPassCache()->GetRenderPass(query);
+                DAWN_TRY_ASSIGN(renderPassVK, device->GetRenderPassCache()->GetRenderPass(query));
             }
 
             // Create a framebuffer that will be used once for the render pass and gather the clear
@@ -260,10 +261,10 @@
                 createInfo.height = renderPass->height;
                 createInfo.layers = 1;
 
-                if (device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo, nullptr,
-                                                 &framebuffer) != VK_SUCCESS) {
-                    ASSERT(false);
-                }
+                DAWN_TRY(
+                    CheckVkSuccess(device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo,
+                                                                nullptr, &framebuffer),
+                                   "CreateFramebuffer"));
 
                 // We don't reuse VkFramebuffers so mark the framebuffer for deletion as soon as the
                 // commands currently being recorded are finished.
@@ -283,6 +284,8 @@
             beginInfo.pClearValues = clearValues.data();
 
             device->fn.CmdBeginRenderPass(commands, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+            return {};
         }
     }  // anonymous namespace
 
@@ -354,7 +357,7 @@
         recordingContext->tempBuffers.emplace_back(tempBuffer);
     }
 
-    void CommandBuffer::RecordCommands(CommandRecordingContext* recordingContext) {
+    MaybeError CommandBuffer::RecordCommands(CommandRecordingContext* recordingContext) {
         Device* device = ToBackend(GetDevice());
         VkCommandBuffer commands = recordingContext->commandBuffer;
 
@@ -525,7 +528,7 @@
                     BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
 
                     TransitionForPass(recordingContext, passResourceUsages[nextPassNumber]);
-                    RecordRenderPass(recordingContext, cmd);
+                    DAWN_TRY(RecordRenderPass(recordingContext, cmd));
 
                     nextPassNumber++;
                 } break;
@@ -542,6 +545,8 @@
                 default: { UNREACHABLE(); } break;
             }
         }
+
+        return {};
     }
 
     void CommandBuffer::RecordComputePass(CommandRecordingContext* recordingContext) {
@@ -649,12 +654,13 @@
         // EndComputePass should have been called
         UNREACHABLE();
     }
-    void CommandBuffer::RecordRenderPass(CommandRecordingContext* recordingContext,
-                                         BeginRenderPassCmd* renderPassCmd) {
+
+    MaybeError CommandBuffer::RecordRenderPass(CommandRecordingContext* recordingContext,
+                                               BeginRenderPassCmd* renderPassCmd) {
         Device* device = ToBackend(GetDevice());
         VkCommandBuffer commands = recordingContext->commandBuffer;
 
-        RecordBeginRenderPass(recordingContext, device, renderPassCmd);
+        DAWN_TRY(RecordBeginRenderPass(recordingContext, device, renderPassCmd));
 
         // Set the default value for the dynamic state
         {
@@ -834,7 +840,7 @@
                 case Command::EndRenderPass: {
                     mCommands.NextCommand<EndRenderPassCmd>();
                     device->fn.CmdEndRenderPass(commands);
-                    return;
+                    return {};
                 } break;
 
                 case Command::SetBlendColor: {
diff --git a/src/dawn_native/vulkan/CommandBufferVk.h b/src/dawn_native/vulkan/CommandBufferVk.h
index 1029681..e1b2e5a 100644
--- a/src/dawn_native/vulkan/CommandBufferVk.h
+++ b/src/dawn_native/vulkan/CommandBufferVk.h
@@ -37,14 +37,14 @@
                                      const CommandBufferDescriptor* descriptor);
         ~CommandBuffer();
 
-        void RecordCommands(CommandRecordingContext* recordingContext);
+        MaybeError RecordCommands(CommandRecordingContext* recordingContext);
 
       private:
         CommandBuffer(CommandEncoderBase* encoder, const CommandBufferDescriptor* descriptor);
 
         void RecordComputePass(CommandRecordingContext* recordingContext);
-        void RecordRenderPass(CommandRecordingContext* recordingContext,
-                              BeginRenderPassCmd* renderPass);
+        MaybeError RecordRenderPass(CommandRecordingContext* recordingContext,
+                                    BeginRenderPassCmd* renderPass);
         void RecordCopyImageWithTemporaryBuffer(CommandRecordingContext* recordingContext,
                                                 const TextureCopy& srcCopy,
                                                 const TextureCopy& dstCopy,
diff --git a/src/dawn_native/vulkan/QueueVk.cpp b/src/dawn_native/vulkan/QueueVk.cpp
index 544ad95..379eb07 100644
--- a/src/dawn_native/vulkan/QueueVk.cpp
+++ b/src/dawn_native/vulkan/QueueVk.cpp
@@ -35,7 +35,7 @@
 
         CommandRecordingContext* recordingContext = device->GetPendingRecordingContext();
         for (uint32_t i = 0; i < commandCount; ++i) {
-            ToBackend(commands[i])->RecordCommands(recordingContext);
+            DAWN_TRY(ToBackend(commands[i])->RecordCommands(recordingContext));
         }
 
         device->SubmitPendingCommands();
diff --git a/src/dawn_native/vulkan/RenderPassCache.cpp b/src/dawn_native/vulkan/RenderPassCache.cpp
index daeb5a4..e6c79f1 100644
--- a/src/dawn_native/vulkan/RenderPassCache.cpp
+++ b/src/dawn_native/vulkan/RenderPassCache.cpp
@@ -18,6 +18,7 @@
 #include "common/HashUtils.h"
 #include "dawn_native/vulkan/DeviceVk.h"
 #include "dawn_native/vulkan/TextureVk.h"
+#include "dawn_native/vulkan/VulkanError.h"
 
 namespace dawn_native { namespace vulkan {
 
@@ -71,18 +72,19 @@
         mCache.clear();
     }
 
-    VkRenderPass RenderPassCache::GetRenderPass(const RenderPassCacheQuery& query) {
+    ResultOrError<VkRenderPass> RenderPassCache::GetRenderPass(const RenderPassCacheQuery& query) {
         auto it = mCache.find(query);
         if (it != mCache.end()) {
-            return it->second;
+            return VkRenderPass(it->second);
         }
 
-        VkRenderPass renderPass = CreateRenderPassForQuery(query);
+        VkRenderPass renderPass;
+        DAWN_TRY_ASSIGN(renderPass, CreateRenderPassForQuery(query));
         mCache.emplace(query, renderPass);
         return renderPass;
     }
 
-    VkRenderPass RenderPassCache::CreateRenderPassForQuery(
+    ResultOrError<VkRenderPass> RenderPassCache::CreateRenderPassForQuery(
         const RenderPassCacheQuery& query) const {
         // The Vulkan subpasses want to know the layout of the attachments with VkAttachmentRef.
         // Precompute them as they must be pointer-chained in VkSubpassDescription
@@ -189,11 +191,9 @@
 
         // Create the render pass from the zillion parameters
         VkRenderPass renderPass;
-        if (mDevice->fn.CreateRenderPass(mDevice->GetVkDevice(), &createInfo, nullptr,
-                                         &renderPass) != VK_SUCCESS) {
-            ASSERT(false);
-        }
-
+        DAWN_TRY(CheckVkSuccess(
+            mDevice->fn.CreateRenderPass(mDevice->GetVkDevice(), &createInfo, nullptr, &renderPass),
+            "CreateRenderPass"));
         return renderPass;
     }
 
diff --git a/src/dawn_native/vulkan/RenderPassCache.h b/src/dawn_native/vulkan/RenderPassCache.h
index 8410cea..3a4eeee 100644
--- a/src/dawn_native/vulkan/RenderPassCache.h
+++ b/src/dawn_native/vulkan/RenderPassCache.h
@@ -15,9 +15,9 @@
 #ifndef DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_
 #define DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_
 
-#include "common/vulkan_platform.h"
-
 #include "common/Constants.h"
+#include "common/vulkan_platform.h"
+#include "dawn_native/Error.h"
 #include "dawn_native/dawn_platform.h"
 
 #include <array>
@@ -66,11 +66,12 @@
         RenderPassCache(Device* device);
         ~RenderPassCache();
 
-        VkRenderPass GetRenderPass(const RenderPassCacheQuery& query);
+        ResultOrError<VkRenderPass> GetRenderPass(const RenderPassCacheQuery& query);
 
       private:
         // Does the actual VkRenderPass creation on a cache miss.
-        VkRenderPass CreateRenderPassForQuery(const RenderPassCacheQuery& query) const;
+        ResultOrError<VkRenderPass> CreateRenderPassForQuery(
+            const RenderPassCacheQuery& query) const;
 
         // Implements the functors necessary for to use RenderPassCacheQueries as unordered_map
         // keys.
diff --git a/src/dawn_native/vulkan/RenderPipelineVk.cpp b/src/dawn_native/vulkan/RenderPipelineVk.cpp
index a5d13f6..2e84df0 100644
--- a/src/dawn_native/vulkan/RenderPipelineVk.cpp
+++ b/src/dawn_native/vulkan/RenderPipelineVk.cpp
@@ -474,7 +474,7 @@
 
             query.SetSampleCount(GetSampleCount());
 
-            renderPass = device->GetRenderPassCache()->GetRenderPass(query);
+            DAWN_TRY_ASSIGN(renderPass, device->GetRenderPassCache()->GetRenderPass(query));
         }
 
         // The create info chains in a bunch of things created on the stack here or inside state