|
@@ -18,6 +18,12 @@ typedef struct {
|
|
|
} VulkanData;
|
|
|
static VulkanData vk = {0};
|
|
|
|
|
|
+typedef struct {
|
|
|
+ size_t amount;
|
|
|
+ VkImage* images;
|
|
|
+ VkImageView* imageViews;
|
|
|
+} SwapchainImages;
|
|
|
+
|
|
|
#define VK_ERROR_CASE(error) \
|
|
|
case error: return #error
|
|
|
|
|
@@ -237,16 +243,70 @@ static bool initSwapchain() {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+static bool createImageView(VkImage image, VkImageView* view) {
|
|
|
+ VkImageViewCreateInfo info = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
|
|
+ .image = image,
|
|
|
+ .viewType = VK_IMAGE_VIEW_TYPE_2D,
|
|
|
+ .format = VK_FORMAT_B8G8R8A8_UNORM,
|
|
|
+ .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
+ .baseMipLevel = 0,
|
|
|
+ .levelCount = 1,
|
|
|
+ .baseArrayLayer = 0,
|
|
|
+ .layerCount = 1}};
|
|
|
+ VK_ASSERT(vkCreateImageView(vk.device, &info, nullptr, view));
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static void removeSwapchainImages(SwapchainImages* i) {
|
|
|
+ for(size_t x = 0; x < i->amount; x++) {
|
|
|
+ vkDestroyImageView(vk.device, i->imageViews[x], nullptr);
|
|
|
+ }
|
|
|
+ coreFree(i->images);
|
|
|
+ coreFree(i->imageViews);
|
|
|
+ *i = (SwapchainImages){0};
|
|
|
+}
|
|
|
+
|
|
|
+static bool createSwapchainImages(SwapchainImages* i) {
|
|
|
+ *i = (SwapchainImages){0};
|
|
|
+ u32 c = 0;
|
|
|
+ VK_ASSERT(vkGetSwapchainImagesKHR(vk.device, vk.swapchain, &c, nullptr));
|
|
|
+ LOG_INFO("Found %u images", c);
|
|
|
+ i->amount = c;
|
|
|
+ i->images = coreAllocate(sizeof(VkImage) * c);
|
|
|
+ i->imageViews = coreZeroAllocate(sizeof(VkImageView) * c);
|
|
|
+ VK_ASSERT(vkGetSwapchainImagesKHR(vk.device, vk.swapchain, &c, i->images));
|
|
|
+ for(u32 x = 0; x < c; x++) {
|
|
|
+ if(createImageView(i->images[x], i->imageViews + x)) {
|
|
|
+ removeSwapchainImages(i);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
bool initVulkan() {
|
|
|
vk.width = 400;
|
|
|
vk.height = 300;
|
|
|
- return initInstance() || initPhysicalDevice() || initDevice() ||
|
|
|
- initSurface() || initSwapchain();
|
|
|
+ if(initInstance() || initPhysicalDevice() || initDevice() ||
|
|
|
+ initSurface() || initSwapchain()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ SwapchainImages images;
|
|
|
+ if(createSwapchainImages(&images)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ removeSwapchainImages(&images);
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
void destroyVulkan(void) {
|
|
|
- vkDestroySwapchainKHR(vk.device, vk.swapchain, nullptr);
|
|
|
- vkDestroySurfaceKHR(vk.instance, vk.surface, nullptr);
|
|
|
+ if(vk.device != VK_NULL_HANDLE) {
|
|
|
+ vkDestroySwapchainKHR(vk.device, vk.swapchain, nullptr);
|
|
|
+ }
|
|
|
+ if(vk.instance != VK_NULL_HANDLE) {
|
|
|
+ vkDestroySurfaceKHR(vk.instance, vk.surface, nullptr);
|
|
|
+ }
|
|
|
vkDestroyDevice(vk.device, nullptr);
|
|
|
vkDestroyInstance(vk.instance, nullptr);
|
|
|
}
|