SpiecsEngine
 
Loading...
Searching...
No Matches
VulkanSwapChain.cpp
Go to the documentation of this file.
1/**
2* @file VulkanSwapChain.cpp.
3* @brief The VulkanSwapChain Class Implementation.
4* @author Spices.
5*/
6
7#include "Pchheader.h"
9
10namespace Spices {
11
13 VulkanState& vulkanState ,
14 std::shared_ptr<VulkanDevice> vulkanDevice
15 )
16 : VulkanObject(vulkanState)
18 {
20
21 /**
22 * @brief Create s SwapChian.
23 */
25
26 /**
27 * @brief Create CreateSyncObjects.
28 */
30 }
31
33 {
35
36 /**
37 * @brief Destroy SyncObjects.
38 */
40
41 /**
42 * @brief Destroy the SwapChian.
43 */
45 }
46
47 VkFormat VulkanSwapChain::FindDepthFormat(const VkPhysicalDevice& physicalDevice)
48 {
50
51 /**
52 * @brief Call findSupportedFormat with specific parameters.
53 */
54 return findSupportedFormat(
55 physicalDevice,
56 { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },
57 VK_IMAGE_TILING_OPTIMAL,
58 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
59 );
60 }
61
62 VkFormat VulkanSwapChain::findSupportedFormat(
63 const VkPhysicalDevice& physicalDevice ,
64 const std::vector<VkFormat>& candidates ,
65 VkImageTiling tiling ,
66 VkFormatFeatureFlags features
67 )
68 {
70
71 /**
72 * @brief Iter all candidates.
73 */
74 for (const VkFormat format : candidates)
75 {
76 VkFormatProperties props;
77 vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props);
78
79 if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) {
80 return format;
81 }
82 else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) {
83 return format;
84 }
85
86 SPICES_CORE_WARN("VulkanSwapChain::Not find a suitable format.");
87 }
88
89 /**
90 * @brief Return one if not find.
91 */
92 return candidates[0];
93 }
94
95 void VulkanSwapChain::Create() const
96 {
98
99 /**
100 * @brief Instance a VkSwapchainCreateInfoKHR.
101 */
102 VkSwapchainCreateInfoKHR createInfo{};
103 createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
104 createInfo.surface = m_VulkanState.m_Surface; // With Specific Surface, we might not change surface size after all.
105 createInfo.minImageCount = MaxFrameInFlight; // 2.
106 createInfo.imageFormat = m_VulkanDevice->GetSwapChainSupport().format.format; // RGBA8 Linear.
107 createInfo.imageColorSpace = m_VulkanDevice->GetSwapChainSupport().format.colorSpace;
108 createInfo.imageExtent = m_VulkanDevice->GetSwapChainSupport().surfaceSize;
109 createInfo.imageArrayLayers = 1; // Might be used with MultipleViewPort.
110 createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
111
112 uint32_t queueFamilyIndices[2] =
113 {
114 m_VulkanDevice->GetQueueHelper().graphicqueuefamily.value(),
115 m_VulkanDevice->GetQueueHelper().presentqueuefamily.value()
116 };
117
118 if (queueFamilyIndices[0] != queueFamilyIndices[1])
119 {
120 createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
121 createInfo.queueFamilyIndexCount = 2;
122 createInfo.pQueueFamilyIndices = queueFamilyIndices;
123 }
124 else
125 {
126 createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
127 createInfo.queueFamilyIndexCount = 0;
128 createInfo.pQueueFamilyIndices = nullptr;
129 }
130
131 createInfo.preTransform = m_VulkanDevice->GetSwapChainSupport().capabilities.currentTransform;
132 createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
133 createInfo.presentMode = m_VulkanDevice->GetSwapChainSupport().presentMode;
134 createInfo.clipped = VK_TRUE;
135 createInfo.oldSwapchain = VK_NULL_HANDLE;
136
137 /**
138 * @breif Create SwapChain.
139 */
140 VK_CHECK(vkCreateSwapchainKHR(m_VulkanState.m_Device, &createInfo, nullptr, &m_VulkanState.m_SwapChain));
141 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_SWAPCHAIN_KHR, reinterpret_cast<uint64_t>(m_VulkanState.m_SwapChain), m_VulkanState.m_Device, "SpicesEngineSwapChainKHR")
142
143 /**
144 * @brief Get Swapchain images created by SwapChain automatically.
145 */
146 uint32_t imageCount = MaxFrameInFlight;
147 vkGetSwapchainImagesKHR(m_VulkanState.m_Device, m_VulkanState.m_SwapChain, &imageCount, m_VulkanState.m_SwapChainImages.data());
148
149 /**
150 * @breif Create SwapChianImage Resources.
151 */
152 for (size_t i = 0; i < MaxFrameInFlight; i++)
153 {
154 /**
155 * @brief Create ImageView.
156 */
157 {
158 /**
159 * @brief Instance a VkImageViewCreateInfo.
160 */
161 VkImageViewCreateInfo info{};
162 info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
163 info.image = m_VulkanState.m_SwapChainImages[i];
164
165 info.viewType = VK_IMAGE_VIEW_TYPE_2D;
166 info.format = m_VulkanDevice->GetSwapChainSupport().format.format;
167
168 info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
169 info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
170 info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
171 info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
172
173 info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
174 info.subresourceRange.baseMipLevel = 0;
175 info.subresourceRange.levelCount = 1;
176 info.subresourceRange.baseArrayLayer = 0;
177 info.subresourceRange.layerCount = 1;
178
179 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_IMAGE, reinterpret_cast<uint64_t>(m_VulkanState.m_SwapChainImages[i]), m_VulkanState.m_Device, "SwapChainImage")
180
181 VK_CHECK(vkCreateImageView(m_VulkanState.m_Device, &info, nullptr, &m_VulkanState.m_SwapChainImageViews[i]))
182 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_IMAGE_VIEW, reinterpret_cast<uint64_t>(m_VulkanState.m_SwapChainImageViews[i]), m_VulkanState.m_Device, "SwapChainImageView")
183 }
184
185 /**
186 * @brief Create Sampler.
187 */
188 {
189 /**
190 * @brief Instance a VkSamplerCreateInfo.
191 */
192 VkSamplerCreateInfo samplerInfo{};
193 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
194 samplerInfo.magFilter = VK_FILTER_LINEAR;
195 samplerInfo.minFilter = VK_FILTER_LINEAR;
196 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
197 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
198 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
199 samplerInfo.anisotropyEnable = VK_TRUE;
200
201 VkPhysicalDeviceProperties properties{};
202 vkGetPhysicalDeviceProperties(m_VulkanState.m_PhysicalDevice, &properties);
203
204 samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
205 samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
206 samplerInfo.unnormalizedCoordinates = VK_FALSE;
207 samplerInfo.compareEnable = VK_FALSE;
208 samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
209
210 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
211 samplerInfo.mipLodBias = 0.0f;
212 samplerInfo.minLod = 0.0f;
213 samplerInfo.maxLod = static_cast<float>(0);
214
215 VK_CHECK(vkCreateSampler(m_VulkanState.m_Device, &samplerInfo, nullptr, &m_VulkanState.m_SwapChainImageSamplers[i]))
216 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_SAMPLER, reinterpret_cast<uint64_t>(m_VulkanState.m_SwapChainImageSamplers[i]), m_VulkanState.m_Device, "SwapChainImageSampler")
217 }
218 }
219 }
220
222 {
224
225 /**
226 * @brief Destroy ImageView.
227 */
228 for (const auto imageView : m_VulkanState.m_SwapChainImageViews)
229 {
230 vkDestroyImageView(m_VulkanState.m_Device, imageView, nullptr);
231 }
232
233 /**
234 * @brief Destroy Sampler.
235 */
236 for (const auto sampler : m_VulkanState.m_SwapChainImageSamplers)
237 {
238 vkDestroySampler(m_VulkanState.m_Device, sampler, nullptr);
239 }
240
241 /**
242 * @brief Destroy SwapChain.
243 */
244 vkDestroySwapchainKHR(m_VulkanState.m_Device, m_VulkanState.m_SwapChain, nullptr);
245 m_VulkanState.m_SwapChain = nullptr;
246 }
247
249 {
251
252 /**
253 * @brief Instance a VkSemaphoreCreateInfo.
254 */
255 VkSemaphoreCreateInfo semaphoreInfo {};
256 semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
257
258 /**
259 * @brief Instance a VkFenceCreateInfo.
260 */
261 VkFenceCreateInfo fenceInfo {};
262 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
263 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
264
265 /**
266 * @brief Create SyncObkects.
267 */
268 for (size_t i = 0; i < MaxFrameInFlight; i++)
269 {
270 // Graphic SyncObjects.
271 VK_CHECK(vkCreateSemaphore(m_VulkanState.m_Device, &semaphoreInfo, nullptr, &m_VulkanState.m_GraphicImageSemaphore[i]))
272 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_SEMAPHORE, reinterpret_cast<uint64_t>(m_VulkanState.m_GraphicImageSemaphore[i]), m_VulkanState.m_Device, "GraphicImageSemaphore")
273
274 VK_CHECK(vkCreateSemaphore(m_VulkanState.m_Device, &semaphoreInfo, nullptr, &m_VulkanState.m_GraphicQueueSemaphore[i]))
275 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_SEMAPHORE, reinterpret_cast<uint64_t>(m_VulkanState.m_GraphicQueueSemaphore[i]), m_VulkanState.m_Device, "GraphicQueueSemaphore")
276
277 VK_CHECK(vkCreateFence(m_VulkanState.m_Device, &fenceInfo, nullptr, &m_VulkanState.m_GraphicFence[i]))
278 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_FENCE, reinterpret_cast<uint64_t>(m_VulkanState.m_GraphicFence[i]), m_VulkanState.m_Device, "GraphicFence")
279
280 // Compute SyncObjects.
281 VK_CHECK(vkCreateSemaphore(m_VulkanState.m_Device, &semaphoreInfo, nullptr, &m_VulkanState.m_ComputeQueueSemaphore[i]))
282 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_SEMAPHORE, reinterpret_cast<uint64_t>(m_VulkanState.m_ComputeQueueSemaphore[i]), m_VulkanState.m_Device, "ComputeQueueSemaphore")
283
284 VK_CHECK(vkCreateFence(m_VulkanState.m_Device, &fenceInfo, nullptr, &m_VulkanState.m_ComputeFence[i]))
285 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_FENCE, reinterpret_cast<uint64_t>(m_VulkanState.m_ComputeFence[i]), m_VulkanState.m_Device, "ComputeFence")
286 }
287 }
288
290 {
292
293 /**
294 * @brief Destroy SyncObkects.
295 */
296 for (size_t i = 0; i < MaxFrameInFlight; i++)
297 {
298 // Graphic SyncObjects.
299 vkDestroySemaphore(m_VulkanState.m_Device, m_VulkanState.m_GraphicImageSemaphore[i], nullptr);
300 vkDestroySemaphore(m_VulkanState.m_Device, m_VulkanState.m_GraphicQueueSemaphore[i], nullptr);
301 vkDestroyFence(m_VulkanState.m_Device, m_VulkanState.m_GraphicFence[i], nullptr);
302
303 // Compute SyncObjects.
304 vkDestroySemaphore(m_VulkanState.m_Device, m_VulkanState.m_ComputeQueueSemaphore[i], nullptr);
305 vkDestroyFence(m_VulkanState.m_Device, m_VulkanState.m_ComputeFence[i], nullptr);
306 }
307 }
308}
#define SPICES_PROFILE_ZONE
#define VK_CHECK(expr)
Vulkan Check macro. Verify Vulkan API Effectiveness.
Definition VulkanUtils.h:68
VulkanInstance Class. This class defines the VulkanDevice behave. This class is just a wrapper of vkd...
VulkanState & m_VulkanState
The global VulkanState Referenced from VulkanRenderBackend.
VulkanObject(VulkanState &vulkanState)
Constructor Function. Init member variables.
VulkanObject Class. This class defines the basic behaves of VulkanObject. When we create an new Vulka...
VulkanSwapChain(VulkanState &vulkanState, std::shared_ptr< VulkanDevice > vulkanDevice)
Constructor Function. Create vkInstance and vkSurface.
void DestroySyncObjects() const
Destroy Sync Objects.
void Destroy() const
Destroy this.
void Create() const
Create this.
virtual ~VulkanSwapChain() override
Destructor Function.
void CreateSyncObjects() const
Create Sync Objects.
VulkanSwapChain Class. This class defines the VulkanSwapChain behaves. This class is just a wrapper o...
This struct contains all Vulkan object in used global.
Definition VulkanUtils.h:74