From 0eb38a393348f7038d4e54a9d44a97bf5ea78e8c Mon Sep 17 00:00:00 2001
From: Christian Mattes <christian.mattes@rwth-aachen.de>
Date: Tue, 4 Jun 2019 15:13:50 +0200
Subject: [PATCH] Made TiledDisplay validation-error free

---
 display/lava-extras/display/DisplayWindow.cc | 13 +++-
 display/lava-extras/display/TiledDisplay.cc  | 74 ++++++++++++++------
 display/lava-extras/display/TiledDisplay.hh  |  5 +-
 3 files changed, 64 insertions(+), 28 deletions(-)

diff --git a/display/lava-extras/display/DisplayWindow.cc b/display/lava-extras/display/DisplayWindow.cc
index 86df99b..f8d3b2f 100644
--- a/display/lava-extras/display/DisplayWindow.cc
+++ b/display/lava-extras/display/DisplayWindow.cc
@@ -170,12 +170,19 @@ DisplayWindow::Frame::~Frame() {
     info.pWaitSemaphores = &window->mRenderingComplete;
     info.waitSemaphoreCount = 1;
 
-    try {
-        window->mQueue->handle().presentKHR(info);
-    } catch (vk::OutOfDateKHRError const &) {
+    auto result = vkQueuePresentKHR(window->mQueue->handle(), (VkPresentInfoKHR*)&info);
+    if (result == VK_ERROR_OUT_OF_DATE_KHR) {
+        std::cout << "DisplayWindow: Rebuilding swapchain" << std::endl;
         window->mDevice->handle().waitIdle();
         window->buildSwapchain();
     }
+
+    //try {
+    //    window->mQueue->handle().presentKHR(info);
+    //} catch (vk::OutOfDateKHRError const &) {
+    //    window->mDevice->handle().waitIdle();
+    //    window->buildSwapchain();
+    //}
 }
 
 DisplayWindow::Frame::Frame(DisplayWindow *parent) : window(parent) {}
diff --git a/display/lava-extras/display/TiledDisplay.cc b/display/lava-extras/display/TiledDisplay.cc
index f29329a..50e2e62 100644
--- a/display/lava-extras/display/TiledDisplay.cc
+++ b/display/lava-extras/display/TiledDisplay.cc
@@ -34,10 +34,13 @@ lava::display::TiledDisplay::TiledDisplay(
                   .setMipLevels(1);
 
     for (auto const &d : devices) {
-        auto img = ci.create(d);
-        img->realizeRAM();
-        img->changeLayout(vk::ImageLayout::eGeneral);
-        mHostImages.push_back(img);
+        auto make_img = [&]() {
+            auto img = ci.create(d);
+            img->realizeRAM();
+            img->changeLayout(vk::ImageLayout::eGeneral);
+            return img;
+        };
+        mHostImages.push_back({{make_img(), make_img()}});
     }
 }
 
@@ -49,27 +52,25 @@ void TiledDisplay::submit(const SharedImage &image) {
         throw std::logic_error(
             "For now you should present to the original device, too");
 
-    {
+    // Step 1 - GPUs-Side: Work with mHostImages[gpu_side]
+
+    { // Step 1.1 transfer master image to Host
         auto cmd = mDevices[master_idx]->graphicsQueue().beginCommandBuffer();
-        mHostImages[master_idx]->copyFrom(image, cmd);
-        mHostImages[master_idx]->changeLayout(
+        mHostImages[master_idx][gpu_side]->copyFrom(image, cmd);
+        mHostImages[master_idx][gpu_side]->changeLayout(
             vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eGeneral,
             cmd);
     }
-
-    for (size_t i = 0; i < mDevices.size(); i++)
-        mDevices[i]->graphicsQueue().catchUp(mConfig.max_lag);
-
-    auto master_map = mHostImages[master_idx]->memoryChunk()->map();
-
-    for (size_t i = 0; i < mHostImages.size(); i++) {
-        if (i == master_idx)
-            continue;
-        auto map = mHostImages[i]->memoryChunk()->map();
-        memcpy(map.data(), master_map.data(),
-               mHostImages[master_idx]->levelBytes(0));
+    { // Step 1.2 change (non-master) hostImages layout to transfer_src
+        for (size_t i = 0; i < mDevices.size(); i++) {
+            if (i == master_idx)
+                continue;
+            mHostImages[i][gpu_side]->changeLayout(
+                vk::ImageLayout::eGeneral,
+                vk::ImageLayout::eTransferSrcOptimal);
+        }
     }
-
+    // Step 1.3 blit and present host images
     for (size_t i = 0; i < mConfig.tiles.size(); i++) {
         auto const &tile = mConfig.tiles[i];
         auto const &window = mWindows[i];
@@ -80,8 +81,9 @@ void TiledDisplay::submit(const SharedImage &image) {
             cmd.wait(frame.imageReady());
             cmd.signal(frame.renderingComplete());
 
-            auto src =
-                (tile.device == master_idx) ? image : mHostImages[tile.device];
+            auto src = (tile.device == master_idx)
+                           ? image
+                           : mHostImages[tile.device][gpu_side];
 
             auto sub = vk::ImageSubresourceLayers()
                            .setAspectMask(vk::ImageAspectFlagBits::eColor)
@@ -108,6 +110,34 @@ void TiledDisplay::submit(const SharedImage &image) {
                                         vk::ImageLayout::ePresentSrcKHR, cmd);
         }
     }
+    { // Step 1.4 change (non-master) hostImages layout back to general
+        for (size_t i = 0; i < mDevices.size(); i++) {
+            if (i == master_idx)
+                continue;
+            mHostImages[i][gpu_side]->changeLayout(vk::ImageLayout::eGeneral);
+        }
+    }
+
+    for (size_t i = 0; i < mDevices.size(); i++)
+        if (int(i) != master_idx)
+            mDevices[i]->graphicsQueue().catchUp(1);
+
+    // Step 2: Exchange Data between hostImages
+    auto cpu_side = (gpu_side + 1) % 2;
+    {
+        auto master_map =
+            mHostImages[master_idx][cpu_side]->memoryChunk()->map();
+
+        for (size_t i = 0; i < mHostImages.size(); i++) {
+            if (i == master_idx)
+                continue;
+            auto map = mHostImages[i][cpu_side]->memoryChunk()->map();
+            memcpy(map.data(), master_map.data(),
+                   mHostImages[master_idx][0]->levelBytes(0));
+        }
+    }
+
+    gpu_side = cpu_side;
 }
 
 } // namespace display
diff --git a/display/lava-extras/display/TiledDisplay.hh b/display/lava-extras/display/TiledDisplay.hh
index d85f5b9..13f45eb 100644
--- a/display/lava-extras/display/TiledDisplay.hh
+++ b/display/lava-extras/display/TiledDisplay.hh
@@ -21,8 +21,6 @@ class TiledDisplay {
         int sourceHeight, sourceWidth;
         vk::Format sourceFormat;
         std::vector<TileConfig> tiles;
-
-        int max_lag = 3;
     };
 
     TiledDisplay(std::vector<SharedDevice> const& devices, Config const &config);
@@ -34,7 +32,8 @@ class TiledDisplay {
     std::vector<SharedDisplayWindow> mWindows;
     std::vector<SharedDevice> mDevices;
     std::vector<char> mBuffer;
-    std::vector<SharedImage> mHostImages;
+    std::vector<std::array<SharedImage,2>> mHostImages;
+    uint32_t gpu_side = 0;
 };
 
 } // namespace display
-- 
GitLab