Lugdunum  0.1.0
Swapchain.cpp
Go to the documentation of this file.
2 
5 
6 namespace lug {
7 namespace Graphics {
8 namespace Vulkan {
9 namespace API {
10 namespace Builder {
11 
12 Swapchain::Swapchain(const API::Device& device): _device(device) {}
13 
16 
17  // Set the present mode (_presentMode)
18  {
19  bool presentModeFound = false;
20  for (auto presentMode : _preferences->presentModes) {
21  if (std::find(info->swapchain.presentModes.begin(), info->swapchain.presentModes.end(), presentMode) != info->swapchain.presentModes.end()) {
22  LUG_LOG.info("Swapchain::build: Use present mode {}", API::RTTI::toStr(presentMode));
23 
24  _presentMode = presentMode;
25  presentModeFound = true;
26  break;
27  }
28  }
29 
30  if (!presentModeFound) {
31  LUG_LOG.error("Swapchain::build: Missing present mode supported by Lugdunum");
32  return false;
33  }
34  }
35 
36  // Set the format (_imageFormat)
37  {
38  if (_imageColorSpace == VK_COLOR_SPACE_MAX_ENUM_KHR) {
39  LUG_LOG.error("Swapchain::build: Missing imageColorSpace parameter. Call Builder::Swapchain::setImageColorSpace()");
40  return false;
41  }
42 
43  bool formatFound = false;
44  auto& localColorSpace = _imageColorSpace; // Define a local variable for lamda capture below
45  for (auto imageFormat : _preferences->formats) {
46  if (std::find_if(info->swapchain.formats.begin(), info->swapchain.formats.end(), [&localColorSpace, &imageFormat](const VkSurfaceFormatKHR& lhs) {
47  return lhs.colorSpace == localColorSpace && imageFormat == lhs.format;
48  }) != info->swapchain.formats.end()) {
49  LUG_LOG.info("Swapchain::build: Use format {}", API::RTTI::toStr(imageFormat));
50 
51  _imageFormat = imageFormat;
52  formatFound = true;
53  break;
54  }
55  }
56 
57  if (!formatFound) {
58  LUG_LOG.error("Swapchain::build: Missing swapchain format supported by Lugdunum");
59  return false;
60  }
61  }
62 
63  // Set the composite alpha (_compositeAlpha)
64  {
65  bool compositeAlphaFound = false;
66  for (auto compositeAlpha : _preferences->compositeAlphas) {
67  if (info->swapchain.capabilities.supportedCompositeAlpha & compositeAlpha) {
68  LUG_LOG.info("Swapchain::build: Use composite alpha {}", API::RTTI::toStr(compositeAlpha));
69 
70  _compositeAlpha = compositeAlpha;
71  compositeAlphaFound = true;
72  break;
73  }
74  }
75 
76  if (!compositeAlphaFound) {
77  LUG_LOG.error("Swapchain::build: Missing composite alpha supported by Lugdunum");
78  return false;
79  }
80  }
81 
82  return true;
83 }
84 
85 bool Swapchain::build(API::Swapchain& swapchain, VkResult* returnResult) {
87 
88  std::vector<uint32_t> queueFamilyIndices(_queueFamilyIndices.begin(), _queueFamilyIndices.end());
89  VkSharingMode sharingMode = VK_SHARING_MODE_EXCLUSIVE;
90  // If we have move than one queueFamilyIndices and exclusive was not manually set
91  if (queueFamilyIndices.size() > 1 && !_exclusive) {
92  sharingMode = VK_SHARING_MODE_CONCURRENT;
93  }
94 
95  // Check the image counts
96  if (info->swapchain.capabilities.maxImageCount > 0 && info->swapchain.capabilities.maxImageCount < _minImageCount) {
97  LUG_LOG.error("RendererWindow: Not enough images ({} required), found {}", _minImageCount, info->swapchain.capabilities.maxImageCount);
98  return false;
99  }
100 
101  if (_preferences != nullptr && !setFromPreferences()) {
102  return false;
103  }
104 
105  // Create the swapchain creation information for vkCreateSwapchain
106  const VkSwapchainCreateInfoKHR createInfo{
107  /* createInfo.sType */ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
108  /* createInfo.pNext */ nullptr,
109  /* createInfo.flags */ 0,
110  /* createInfo.surface */ _surface,
111  /* createInfo.minImageCount */ _minImageCount,
112  /* createInfo.imageFormat */ _imageFormat,
113  /* createInfo.imageColorSpace */ _imageColorSpace,
114  /* createInfo.imageExtent */ {_imageExtent.width, _imageExtent.height},
115  /* createInfo.imageArrayLayers */ 1,
116  /* createInfo.imageUsage */ _imageUsage,
117  /* createInfo.imageSharingMode */ sharingMode,
118  /* createInfo.queueFamilyIndexCount */ static_cast<uint32_t>(queueFamilyIndices.size()),
119  /* createInfo.pQueueFamilyIndices */ queueFamilyIndices.data(), // Convert the set to raw data, // Convert the set to raw data
120  /* createInfo.preTransform */ _preTransform,
121  /* createInfo.compositeAlpha */ _compositeAlpha,
122  /* createInfo.presentMode */ _presentMode,
123  /* createInfo.clipped */ _clipped,
124  /* createInfo.oldSwapchain */ _oldSwapchain
125  };
126 
127  // Create the swapchain
128  VkSwapchainKHR vkSwapchain{VK_NULL_HANDLE};
129  VkResult result = vkCreateSwapchainKHR(static_cast<VkDevice>(_device), &createInfo, nullptr, &vkSwapchain);
130 
131  if (returnResult) {
132  *returnResult = result;
133  }
134 
135  if (result != VK_SUCCESS) {
136  return false;
137  }
138 
139  swapchain = API::Swapchain(vkSwapchain, &_device, {_imageFormat, _imageColorSpace}, _imageExtent);
140 
141  return swapchain.init();
142 }
143 
144 std::unique_ptr<API::Swapchain> Swapchain::build(VkResult* returnResult) {
145  std::unique_ptr<API::Swapchain> swapchain = std::make_unique<API::Swapchain>();
146  return build(*swapchain, returnResult) ? std::move(swapchain) : nullptr;
147 }
148 
149 } // Builder
150 } // API
151 } // Vulkan
152 } // Graphics
153 } // lug
bool build(API::Swapchain &instance, VkResult *returnResult=nullptr)
Definition: Swapchain.cpp:85
struct lug::Graphics::Vulkan::PhysicalDeviceInfo::Swapchain swapchain
std::vector< VkCompositeAlphaFlagBitsKHR > compositeAlphas
Definition: Renderer.hpp:46
VkSurfaceTransformFlagBitsKHR _preTransform
Definition: Swapchain.hpp:65
std::vector< VkPresentModeKHR > presentModes
Definition: Vulkan.hpp:196
const PhysicalDeviceInfo * getPhysicalDeviceInfo() const
Definition: Device.inl:6
std::vector< VkSurfaceFormatKHR > formats
Definition: Vulkan.hpp:195
const Renderer::Preferences::Swapchain * _preferences
Definition: Swapchain.hpp:56
const char * toStr(VkResult enumVal)
#define LUG_LOG
Definition: Logger.hpp:73
std::vector< VkPresentModeKHR > presentModes
Definition: Renderer.hpp:44
VkCompositeAlphaFlagBitsKHR _compositeAlpha
Definition: Swapchain.hpp:66