Lugdunum  0.1.0
Swapchain.cpp
Go to the documentation of this file.
2 
7 
8 namespace lug {
9 namespace Graphics {
10 namespace Vulkan {
11 namespace API {
12 
13 Swapchain::Swapchain(VkSwapchainKHR swapchain, const Device* device, const VkSurfaceFormatKHR& swapchainFormat, const VkExtent2D& extent) :
14  _swapchain(swapchain), _device(device), _format(swapchainFormat), _extent(extent) {}
15 
17  _swapchain = swapchain._swapchain;
18  _device = swapchain._device;
19  _images = std::move(swapchain._images);
20  _imagesViews = std::move(swapchain._imagesViews);
21  _format = swapchain._format;
22  _extent = swapchain._extent;
23  swapchain._swapchain = VK_NULL_HANDLE;
24  swapchain._device = nullptr;
25 }
26 
28  destroy();
29 
30  _swapchain = swapchain._swapchain;
31  _device = swapchain._device;
32  _images = std::move(swapchain._images);
33  _imagesViews = std::move(swapchain._imagesViews);
34  _format = swapchain._format;
35  _extent = swapchain._extent;
36  swapchain._swapchain = VK_NULL_HANDLE;
37  swapchain._device = nullptr;
38 
39  return *this;
40 }
41 
43  destroy();
44 }
45 
47  _outOfDate = false;
48 
49  // Delete swapchain images and images views
50  _imagesViews.clear();
51  _images.clear();
52 
53  // Delete swapchain
54  if (_swapchain != VK_NULL_HANDLE) {
55  vkDestroySwapchainKHR(static_cast<VkDevice>(*_device), _swapchain, nullptr);
56  _swapchain = VK_NULL_HANDLE;
57  _device = nullptr;
58  }
59 }
60 
62  // Get swapchain images
63  {
64  VkResult result{VK_SUCCESS};
65  uint32_t imagesCount = 0;
66  std::vector<VkImage> images;
67 
68  result = vkGetSwapchainImagesKHR(static_cast<VkDevice>(*_device), _swapchain, &imagesCount, nullptr);
69 
70  if (result != VK_SUCCESS) {
71  LUG_LOG.error("RendererVulkan: Can't enumerate swapchain images: {}", result);
72  return false;
73  }
74 
75  images.resize(imagesCount);
76  result = vkGetSwapchainImagesKHR(static_cast<VkDevice>(*_device), _swapchain, &imagesCount, images.data());
77 
78  if (result != VK_SUCCESS) {
79  LUG_LOG.error("RendererVulkan: Can't enumerate swapchain images: {}", result);
80  return false;
81  }
82 
83  // Copy VkImage vector to Image vector
84  _images.resize(imagesCount);
85 
86  for (uint8_t i = 0; i < images.size(); ++i) {
87  _images[i] = Image(images[i], _device, {_extent.width, _extent.height}, _format.format, true);
88  }
89  }
90 
91  // Create image views
92  {
93  _imagesViews.resize(_images.size());
94 
95  for (uint8_t i = 0; i < _images.size(); ++i) {
96  VkResult result{VK_SUCCESS};
97  API::Builder::ImageView imageViewBuilder(*_device, _images[i]);
98 
99  imageViewBuilder.setFormat(_format.format);
100 
101  if (!imageViewBuilder.build(_imagesViews[i], &result)) {
102  LUG_LOG.error("Forward::initDepthBuffers: Can't create swapchain image view: {}", result);
103  return false;
104  }
105  }
106  }
107 
108  return true;
109 }
110 
111 bool Swapchain::getNextImage(uint32_t* imageIndex, VkSemaphore semaphore) {
112  // Get next image
113  // TODO: remove UINT64_MAX timeout and ask next image later if VK_NOT_READY is returned
114  VkResult result = vkAcquireNextImageKHR(static_cast<VkDevice>(*_device), _swapchain, UINT64_MAX, semaphore, VK_NULL_HANDLE, imageIndex);
115 
116  if (result == VK_ERROR_OUT_OF_DATE_KHR) {
117  _outOfDate = true;
118  return false;
119  } else if (result != VK_SUCCESS) {
120  LUG_LOG.error("RendererVulkan: getNextImage(): Can't acquire swapchain next image: {}", result);
121  return false;
122  }
123 
124  return true;
125 }
126 
127 bool Swapchain::present(const Queue* presentQueue, uint32_t imageIndex, VkSemaphore semaphore) const {
128  // Present image
129  const VkPresentInfoKHR presentInfo{
130  /* presentInfo.sType */ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
131  /* presentInfo.pNext */ nullptr,
132  /* presentInfo.waitSemaphoreCount */ static_cast<uint32_t>(semaphore != VK_NULL_HANDLE ? 1 : 0),
133  /* presentInfo.pWaitSemaphores */ semaphore != VK_NULL_HANDLE ? &semaphore : nullptr,
134  /* presentInfo.swapchainCount */ 1,
135  /* presentInfo.pSwapchains */ &_swapchain,
136  /* presentInfo.pImageIndices */ &imageIndex,
137  /* presentInfo.pResults */ nullptr
138  };
139 
140  VkResult result = vkQueuePresentKHR(static_cast<VkQueue>(*presentQueue), &presentInfo);
141 
142  if (result != VK_SUCCESS) {
143  LUG_LOG.error("RendererVulkan: present(): Can't acquire swapchain next image: {}", result);
144  return false;
145  }
146 
147  return true;
148 }
149 
150 } // API
151 } // Vulkan
152 } // Graphics
153 } // lug
bool build(API::ImageView &instance, VkResult *returnResult=nullptr)
Definition: ImageView.cpp:14
bool present(const Queue *presentQueue, uint32_t imageIndex, VkSemaphore semaphore=VK_NULL_HANDLE) const
Definition: Swapchain.cpp:127
std::vector< ImageView > _imagesViews
Definition: Swapchain.hpp:65
bool getNextImage(uint32_t *imageIndex, VkSemaphore semaphore=VK_NULL_HANDLE)
Definition: Swapchain.cpp:111
#define LUG_LOG
Definition: Logger.hpp:73
Swapchain & operator=(const Swapchain &)=delete