Add a flag to reuse vulkan instance across tests.

BUG=chromium:936705
TEST=./vkbench -t Clear --iterations=4

Change-Id: I00675aead6a59d05626aebc8816165e2a554351a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vkbench/+/2500542
Reviewed-by: Po-Hsien Wang <pwang@chromium.org>
Tested-by: Po-Hsien Wang <pwang@chromium.org>
Commit-Queue: Po-Hsien Wang <pwang@chromium.org>
Auto-Submit: Po-Hsien Wang <pwang@chromium.org>
diff --git a/src/clearTest.cc b/src/clearTest.cc
index c0aeac3..67aec4e 100644
--- a/src/clearTest.cc
+++ b/src/clearTest.cc
@@ -43,6 +43,7 @@
   device.destroyFramebuffer(frame_buffer_);
   device.destroyRenderPass(render_pass_);
   device.freeCommandBuffers(vk->GetCommandPool(), cmd_buffers_);
+  smt_infos_.clear();
 }
 
 void ClearTest::CreateRenderPass() {
diff --git a/src/drawSizeTest.cc b/src/drawSizeTest.cc
index 6e30d6d..777827e 100644
--- a/src/drawSizeTest.cc
+++ b/src/drawSizeTest.cc
@@ -13,7 +13,7 @@
   cmd_buffers_ = vk->GetDevice().allocateCommandBuffers(
       {vk->GetCommandPool(), vk::CommandBufferLevel::ePrimary, 1});
   for (const auto& buffer : cmd_buffers_) {
-    buffer.begin({});
+    buffer.begin(vk::CommandBufferBeginInfo());
     vk::ClearValue clear_color(std::array<float, 4>{0.f, 0.f, 0.f});
     vk::RenderPassBeginInfo render_pass_info;
     render_pass_info.setFramebuffer(frame_buffer_)
@@ -27,7 +27,6 @@
     buffer.endRenderPass();
     buffer.end();
   }
-
   vk::SubmitInfo info;
   info.setCommandBufferCount(1).setPCommandBuffers(cmd_buffers_.data());
   smt_infos_.push_back(info);
@@ -48,6 +47,7 @@
   device.destroyPipeline(graphics_pipeline_);
   device.destroyPipelineLayout(pipeline_layout_);
   device.freeCommandBuffers(vk->GetCommandPool(), cmd_buffers_);
+  smt_infos_.clear();
 }
 
 void DrawSizeTest::CreateRenderPass() {
diff --git a/src/main.cc b/src/main.cc
index 29a0543..ea66c7c 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -21,6 +21,9 @@
 int g_verbose = false;
 // g_vlayer enables the vulkan verification layer if it is set.
 int g_vlayer = false;
+// g_hasty enables the hasty mode. Tests would tries to reuse vulkan instance if
+// possible.
+int g_hasty = false;
 
 // kLongOptions defines the options for argument options.
 const static struct option kLongOptions[] = {
@@ -31,6 +34,7 @@
     {"help", no_argument, nullptr, 'h'},
     {"vlayer", no_argument, &g_vlayer, 1},
     {"verbose", no_argument, &g_verbose, 1},
+    {"hasty", no_argument, &g_hasty, 1},
     {0, 0, 0, 0}};
 
 // TimeTest times the test by looping it iteration times.
@@ -106,7 +110,8 @@
   -b, --blacklist=TESTS  Tests to not run in colon separated form.
   --list                 List the tests available.
   --verbose              Show verbose messages.
-  --vlayer               Enable vulkan verification layer.),")
+  --vlayer               Enable vulkan verification layer.
+  --hasty                Enable hasty mode.),")
 }
 
 bool prefixFind(std::vector<std::string> list, std::string name) {
@@ -202,16 +207,12 @@
   PrintDateTime();
   for (auto i = 0; i < all_tests.size(); i++) {
     auto& test = all_tests[i];
-    bool reuse_vulkan = false;
-    if (i + 1 < all_tests.size() && all_tests[i]->vk == all_tests[i + 1]->vk) {
-      reuse_vulkan = true;
-    }
-
     for (auto iter = 0; iter < g_iteration; iter++) {
       try {
-        test->vk->Initialize();
+        if (!test->vk->IsInitialized())
+          test->vk->Initialize();
         Run(test, 1000000);
-        if (!reuse_vulkan)
+        if (!g_hasty)
           test->vk->Destroy();
       } catch (const ERROR_TYPE& type) {
         switch (type) {
@@ -229,6 +230,13 @@
         LOG("Runtime Error: %s", error.what());
       }
     }
+
+    // keep test->vk initialized for the next test.
+    if (g_hasty && test->vk->IsInitialized()) {
+      if (i + 1 >= all_tests.size() || test->vk != all_tests[i + 1]->vk) {
+        test->vk->Destroy();
+      }
+    }
   }
   PrintDateTime();
   LOG("@TEST_END")
diff --git a/src/vkBase.cc b/src/vkBase.cc
index a8adb7d..4f3a862 100644
--- a/src/vkBase.cc
+++ b/src/vkBase.cc
@@ -143,8 +143,6 @@
 }
 
 void vkBase::Initialize() {
-  if (initialized_)
-    return;
   CreateInstance();
   ChoosePhysicalDevice();
   CreateLogicalDevice();
@@ -152,6 +150,10 @@
   initialized_ = true;
 }
 
+bool vkBase::IsInitialized() const {
+  return initialized_;
+}
+
 void vkBase::CreateInstance() {
   vk::ApplicationInfo appInfo("vkbench", 1, "Vulkan.hpp", 1,
                               VK_API_VERSION_1_1);
@@ -248,10 +250,6 @@
 }
 
 void vkBase::Destroy() {
-  if (!initialized_) {
-    ERROR("Can't destroy any resource without initialization.")
-    return;
-  }
   if (cmd_pool_)
     device_.destroy(cmd_pool_, nullptr);
   device_.destroy();
diff --git a/src/vkBase.h b/src/vkBase.h
index 642679f..057cb54 100644
--- a/src/vkBase.h
+++ b/src/vkBase.h
@@ -35,6 +35,7 @@
  public:
   virtual ~vkBase() = default;
   virtual void Initialize();
+  virtual bool IsInitialized() const;
   virtual void Destroy();
 
   const vk::Device& GetDevice() const { return device_; }