24 #elif (defined __linux__)
30 #include <vulkan/vulkan.h>
31 #include "Wasabi/Core/VkTools/vulkantools.hpp"
34 #include "vulkanandroid.hpp"
37 typedef uint32_t uint;
40 #define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
42 fp##entrypoint = reinterpret_cast<PFN_vk##entrypoint>(vkGetInstanceProcAddr(inst, "vk"#entrypoint)); \
43 if (fp##entrypoint == NULL) \
50 #define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
52 fp##entrypoint = reinterpret_cast<PFN_vk##entrypoint>(vkGetDeviceProcAddr(dev, "vk"#entrypoint)); \
53 if (fp##entrypoint == NULL) \
69 VkPhysicalDevice physicalDevice;
72 PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR;
73 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR;
74 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR;
75 PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR;
76 PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR;
77 PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR;
78 PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR;
79 PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR;
80 PFN_vkQueuePresentKHR fpQueuePresentKHR;
83 VkColorSpaceKHR colorSpace;
85 VkSwapchainKHR swapChain = VK_NULL_HANDLE;
88 std::vector<VkImage> images;
89 std::vector<SwapChainBuffer> buffers;
92 uint32_t queueNodeIndex = UINT32_MAX;
96 bool initSurface(VkSurfaceKHR _surface)
105 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL);
106 assert(queueCount >= 1);
108 std::vector<VkQueueFamilyProperties> queueProps(queueCount);
109 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, queueProps.data());
114 std::vector<VkBool32> supportsPresent(queueCount);
115 for (uint32_t i = 0; i < queueCount; i++)
117 fpGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, &supportsPresent[i]);
122 uint32_t graphicsQueueNodeIndex = UINT32_MAX;
123 uint32_t presentQueueNodeIndex = UINT32_MAX;
124 for (uint32_t i = 0; i < queueCount; i++)
126 if ((queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
128 if (graphicsQueueNodeIndex == UINT32_MAX)
130 graphicsQueueNodeIndex = i;
133 if (supportsPresent[i] == VK_TRUE)
135 graphicsQueueNodeIndex = i;
136 presentQueueNodeIndex = i;
141 if (presentQueueNodeIndex == UINT32_MAX)
145 for (uint32_t i = 0; i < queueCount; ++i)
147 if (supportsPresent[i] == VK_TRUE)
149 presentQueueNodeIndex = i;
156 if (graphicsQueueNodeIndex == UINT32_MAX || presentQueueNodeIndex == UINT32_MAX)
160 if (graphicsQueueNodeIndex != presentQueueNodeIndex)
163 queueNodeIndex = graphicsQueueNodeIndex;
166 uint32_t formatCount;
167 err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, NULL);
169 assert(formatCount > 0);
171 std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
172 err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, surfaceFormats.data());
177 if ((formatCount == 1) && (surfaceFormats[0].format == VK_FORMAT_UNDEFINED))
179 colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
187 colorFormat = surfaceFormats[0].format;
189 colorSpace = surfaceFormats[0].colorSpace;
195 void connect(VkInstance inst, VkPhysicalDevice physDev, VkDevice dev)
197 this->instance = inst;
198 this->physicalDevice = physDev;
200 GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceSupportKHR);
201 GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceCapabilitiesKHR);
202 GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceFormatsKHR);
203 GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfacePresentModesKHR);
204 GET_DEVICE_PROC_ADDR(device, CreateSwapchainKHR);
205 GET_DEVICE_PROC_ADDR(device, DestroySwapchainKHR);
206 GET_DEVICE_PROC_ADDR(device, GetSwapchainImagesKHR);
207 GET_DEVICE_PROC_ADDR(device, AcquireNextImageKHR);
208 GET_DEVICE_PROC_ADDR(device, QueuePresentKHR);
212 void create(VkCommandBuffer cmdBuffer, uint32_t *width, uint32_t *height, uint32_t numDesiredSwapchainImages = std::numeric_limits<uint32_t>::max())
215 VkSwapchainKHR oldSwapchain = swapChain;
218 VkSurfaceCapabilitiesKHR surfCaps;
219 err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfCaps);
223 uint32_t presentModeCount;
224 err = fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL);
226 assert(presentModeCount > 0);
228 std::vector<VkPresentModeKHR> presentModes(presentModeCount);
230 err = fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data());
233 VkExtent2D swapchainExtent = {};
235 if (surfCaps.currentExtent.width == std::numeric_limits<uint32_t>::max())
239 swapchainExtent.width = *width;
240 swapchainExtent.height = *height;
245 swapchainExtent = surfCaps.currentExtent;
246 *width = surfCaps.currentExtent.width;
247 *height = surfCaps.currentExtent.height;
251 VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
252 for (
size_t i = 0; i < presentModeCount; i++)
254 if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
256 swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
259 if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) && (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR))
261 swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
266 uint32_t desiredNumberOfSwapchainImages = numDesiredSwapchainImages;
267 if (desiredNumberOfSwapchainImages == std::numeric_limits<uint32_t>::max())
268 desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;
269 if ((surfCaps.maxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount))
271 desiredNumberOfSwapchainImages = surfCaps.maxImageCount;
274 VkSurfaceTransformFlagBitsKHR preTransform;
275 if (surfCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
277 preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
281 preTransform = surfCaps.currentTransform;
284 VkSwapchainCreateInfoKHR swapchainCI = {};
285 swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
286 swapchainCI.pNext = NULL;
287 swapchainCI.surface = surface;
288 swapchainCI.minImageCount = desiredNumberOfSwapchainImages;
289 swapchainCI.imageFormat = colorFormat;
290 swapchainCI.imageColorSpace = colorSpace;
291 swapchainCI.imageExtent = { swapchainExtent.width, swapchainExtent.height };
292 swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
293 swapchainCI.preTransform = preTransform;
294 swapchainCI.imageArrayLayers = 1;
295 swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
296 swapchainCI.queueFamilyIndexCount = 0;
297 swapchainCI.pQueueFamilyIndices = NULL;
298 swapchainCI.presentMode = swapchainPresentMode;
299 swapchainCI.oldSwapchain = oldSwapchain;
300 swapchainCI.clipped =
true;
301 swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
303 err = fpCreateSwapchainKHR(device, &swapchainCI,
nullptr, &swapChain);
308 if (oldSwapchain != VK_NULL_HANDLE)
310 for (uint32_t i = 0; i < imageCount; i++)
312 vkDestroyImageView(device, buffers[i].view,
nullptr);
314 fpDestroySwapchainKHR(device, oldSwapchain,
nullptr);
317 err = fpGetSwapchainImagesKHR(device, swapChain, &imageCount, NULL);
321 images.resize(imageCount);
322 err = fpGetSwapchainImagesKHR(device, swapChain, &imageCount, images.data());
326 buffers.resize(imageCount);
327 for (uint32_t i = 0; i < imageCount; i++)
329 VkImageViewCreateInfo colorAttachmentView = {};
330 colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
331 colorAttachmentView.pNext = NULL;
332 colorAttachmentView.format = colorFormat;
333 colorAttachmentView.components = {
334 VK_COMPONENT_SWIZZLE_R,
335 VK_COMPONENT_SWIZZLE_G,
336 VK_COMPONENT_SWIZZLE_B,
337 VK_COMPONENT_SWIZZLE_A
339 colorAttachmentView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
340 colorAttachmentView.subresourceRange.baseMipLevel = 0;
341 colorAttachmentView.subresourceRange.levelCount = 1;
342 colorAttachmentView.subresourceRange.baseArrayLayer = 0;
343 colorAttachmentView.subresourceRange.layerCount = 1;
344 colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D;
345 colorAttachmentView.flags = 0;
347 buffers[i].image = images[i];
350 vkTools::setImageLayout(
353 VK_IMAGE_ASPECT_COLOR_BIT,
354 VK_IMAGE_LAYOUT_UNDEFINED,
355 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
357 colorAttachmentView.image = buffers[i].image;
359 err = vkCreateImageView(device, &colorAttachmentView,
nullptr, &buffers[i].view);
365 VkResult acquireNextImage(VkSemaphore presentCompleteSemaphore, uint32_t *currentBuffer)
367 return fpAcquireNextImageKHR(device, swapChain, UINT64_MAX, presentCompleteSemaphore,
nullptr, currentBuffer);
371 VkResult queuePresent(VkQueue queue, uint32_t currentBuffer)
373 VkPresentInfoKHR presentInfo = {};
374 presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
375 presentInfo.pNext = NULL;
376 presentInfo.swapchainCount = 1;
377 presentInfo.pSwapchains = &swapChain;
378 presentInfo.pImageIndices = ¤tBuffer;
379 return fpQueuePresentKHR(queue, &presentInfo);
383 VkResult queuePresent(VkQueue queue, uint32_t currentBuffer, VkSemaphore waitSemaphore)
385 VkPresentInfoKHR presentInfo = {};
386 presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
387 presentInfo.pNext = NULL;
388 presentInfo.swapchainCount = 1;
389 presentInfo.pSwapchains = &swapChain;
390 presentInfo.pImageIndices = ¤tBuffer;
391 if (waitSemaphore != VK_NULL_HANDLE)
393 presentInfo.pWaitSemaphores = &waitSemaphore;
394 presentInfo.waitSemaphoreCount = 1;
396 return fpQueuePresentKHR(queue, &presentInfo);
403 for (uint32_t i = 0; i < imageCount; i++)
405 vkDestroyImageView(device, buffers[i].view,
nullptr);
408 fpDestroySwapchainKHR(device, swapChain,
nullptr);
410 vkDestroySurfaceKHR(instance, surface,
nullptr);
411 swapChain = VK_NULL_HANDLE;
412 surface = VK_NULL_HANDLE;