diff --git a/test/testvulkan.c b/test/testvulkan.c index 19465bca7..88707e206 100644 --- a/test/testvulkan.c +++ b/test/testvulkan.c @@ -174,6 +174,7 @@ static const char *getVulkanResultString(VkResult result) typedef struct VulkanContext { + SDL_Window *window; VkInstance instance; VkDevice device; VkSurfaceKHR surface; @@ -202,7 +203,8 @@ typedef struct VulkanContext } VulkanContext; static SDLTest_CommonState *state; -static VulkanContext vulkanContext = {0}; +static VulkanContext *vulkanContexts = NULL; // an array of state->num_windows items +static VulkanContext *vulkanContext = NULL; // for the currently-rendering window static void shutdownVulkan(void); @@ -277,11 +279,11 @@ static void createInstance(void) } instanceCreateInfo.enabledExtensionCount = extensionCount; instanceCreateInfo.ppEnabledExtensionNames = extensions; - result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext.instance); + result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext->instance); SDL_free((void*)extensions); if(result != VK_SUCCESS) { - vulkanContext.instance = VK_NULL_HANDLE; + vulkanContext->instance = VK_NULL_HANDLE; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateInstance(): %s\n", getVulkanResultString(result)); @@ -294,7 +296,7 @@ static void loadInstanceFunctions(void) #define VULKAN_DEVICE_FUNCTION(name) #define VULKAN_GLOBAL_FUNCTION(name) #define VULKAN_INSTANCE_FUNCTION(name) \ - name = (PFN_##name)vkGetInstanceProcAddr(vulkanContext.instance, #name); \ + name = (PFN_##name)vkGetInstanceProcAddr(vulkanContext->instance, #name); \ if(!name) \ { \ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \ @@ -309,11 +311,11 @@ static void loadInstanceFunctions(void) static void createSurface(void) { - if(!SDL_Vulkan_CreateSurface(state->windows[0], - vulkanContext.instance, - &vulkanContext.surface)) + if(!SDL_Vulkan_CreateSurface(vulkanContext->window, + vulkanContext->instance, + &vulkanContext->surface)) { - vulkanContext.surface = VK_NULL_HANDLE; + vulkanContext->surface = VK_NULL_HANDLE; SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError()); quit(2); @@ -331,7 +333,7 @@ static void findPhysicalDevice(void) uint32_t physicalDeviceIndex; VkResult result = - vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, NULL); + vkEnumeratePhysicalDevices(vulkanContext->instance, &physicalDeviceCount, NULL); if(result != VK_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, @@ -352,7 +354,7 @@ static void findPhysicalDevice(void) quit(2); } result = - vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, physicalDevices); + vkEnumeratePhysicalDevices(vulkanContext->instance, &physicalDeviceCount, physicalDevices); if(result != VK_SUCCESS) { SDL_free(physicalDevices); @@ -361,7 +363,7 @@ static void findPhysicalDevice(void) getVulkanResultString(result)); quit(2); } - vulkanContext.physicalDevice = NULL; + vulkanContext->physicalDevice = NULL; for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; physicalDeviceIndex++) { @@ -373,10 +375,10 @@ static void findPhysicalDevice(void) VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex]; - vkGetPhysicalDeviceProperties(physicalDevice, &vulkanContext.physicalDeviceProperties); - if(VK_VERSION_MAJOR(vulkanContext.physicalDeviceProperties.apiVersion) < 1) + vkGetPhysicalDeviceProperties(physicalDevice, &vulkanContext->physicalDeviceProperties); + if(VK_VERSION_MAJOR(vulkanContext->physicalDeviceProperties.apiVersion) < 1) continue; - vkGetPhysicalDeviceFeatures(physicalDevice, &vulkanContext.physicalDeviceFeatures); + vkGetPhysicalDeviceFeatures(physicalDevice, &vulkanContext->physicalDeviceFeatures); vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, NULL); if(queueFamiliesCount == 0) continue; @@ -396,8 +398,8 @@ static void findPhysicalDevice(void) } vkGetPhysicalDeviceQueueFamilyProperties( physicalDevice, &queueFamiliesCount, queueFamiliesProperties); - vulkanContext.graphicsQueueFamilyIndex = queueFamiliesCount; - vulkanContext.presentQueueFamilyIndex = queueFamiliesCount; + vulkanContext->graphicsQueueFamilyIndex = queueFamiliesCount; + vulkanContext->presentQueueFamilyIndex = queueFamiliesCount; for(queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount; queueFamilyIndex++) { @@ -406,9 +408,9 @@ static void findPhysicalDevice(void) if(queueFamiliesProperties[queueFamilyIndex].queueCount == 0) continue; if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) - vulkanContext.graphicsQueueFamilyIndex = queueFamilyIndex; + vulkanContext->graphicsQueueFamilyIndex = queueFamilyIndex; result = vkGetPhysicalDeviceSurfaceSupportKHR( - physicalDevice, queueFamilyIndex, vulkanContext.surface, &supported); + physicalDevice, queueFamilyIndex, vulkanContext->surface, &supported); if(result != VK_SUCCESS) { SDL_free(physicalDevices); @@ -421,14 +423,14 @@ static void findPhysicalDevice(void) } if(supported) { - vulkanContext.presentQueueFamilyIndex = queueFamilyIndex; + vulkanContext->presentQueueFamilyIndex = queueFamilyIndex; if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) break; // use this queue because it can present and do graphics } } - if(vulkanContext.graphicsQueueFamilyIndex == queueFamiliesCount) // no good queues found + if(vulkanContext->graphicsQueueFamilyIndex == queueFamiliesCount) // no good queues found continue; - if(vulkanContext.presentQueueFamilyIndex == queueFamiliesCount) // no good queues found + if(vulkanContext->presentQueueFamilyIndex == queueFamiliesCount) // no good queues found continue; result = vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL); @@ -480,13 +482,13 @@ static void findPhysicalDevice(void) } if(!hasSwapchainExtension) continue; - vulkanContext.physicalDevice = physicalDevice; + vulkanContext->physicalDevice = physicalDevice; break; } SDL_free(physicalDevices); SDL_free(queueFamiliesProperties); SDL_free(deviceExtensions); - if(!vulkanContext.physicalDevice) + if(!vulkanContext->physicalDevice) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan: no viable physical devices found"); quit(2); @@ -504,7 +506,7 @@ static void createDevice(void) VkResult result; deviceQueueCreateInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - deviceQueueCreateInfo->queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex; + deviceQueueCreateInfo->queueFamilyIndex = vulkanContext->graphicsQueueFamilyIndex; deviceQueueCreateInfo->queueCount = 1; deviceQueueCreateInfo->pQueuePriorities = &queuePriority[0]; @@ -515,10 +517,10 @@ static void createDevice(void) deviceCreateInfo.enabledExtensionCount = SDL_arraysize(deviceExtensionNames); deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames; result = vkCreateDevice( - vulkanContext.physicalDevice, &deviceCreateInfo, NULL, &vulkanContext.device); + vulkanContext->physicalDevice, &deviceCreateInfo, NULL, &vulkanContext->device); if(result != VK_SUCCESS) { - vulkanContext.device = VK_NULL_HANDLE; + vulkanContext->device = VK_NULL_HANDLE; SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "vkCreateDevice(): %s\n", getVulkanResultString(result)); quit(2); @@ -528,7 +530,7 @@ static void createDevice(void) static void loadDeviceFunctions(void) { #define VULKAN_DEVICE_FUNCTION(name) \ - name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext.device, #name); \ + name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext->device, #name); \ if(!name) \ { \ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \ @@ -547,17 +549,17 @@ static void loadDeviceFunctions(void) static void getQueues(void) { - vkGetDeviceQueue(vulkanContext.device, - vulkanContext.graphicsQueueFamilyIndex, + vkGetDeviceQueue(vulkanContext->device, + vulkanContext->graphicsQueueFamilyIndex, 0, - &vulkanContext.graphicsQueue); - if(vulkanContext.graphicsQueueFamilyIndex != vulkanContext.presentQueueFamilyIndex) - vkGetDeviceQueue(vulkanContext.device, - vulkanContext.presentQueueFamilyIndex, + &vulkanContext->graphicsQueue); + if(vulkanContext->graphicsQueueFamilyIndex != vulkanContext->presentQueueFamilyIndex) + vkGetDeviceQueue(vulkanContext->device, + vulkanContext->presentQueueFamilyIndex, 0, - &vulkanContext.presentQueue); + &vulkanContext->presentQueue); else - vulkanContext.presentQueue = vulkanContext.graphicsQueue; + vulkanContext->presentQueue = vulkanContext->graphicsQueue; } static void createSemaphore(VkSemaphore *semaphore) @@ -566,7 +568,7 @@ static void createSemaphore(VkSemaphore *semaphore) VkSemaphoreCreateInfo createInfo = {0}; createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - result = vkCreateSemaphore(vulkanContext.device, &createInfo, NULL, semaphore); + result = vkCreateSemaphore(vulkanContext->device, &createInfo, NULL, semaphore); if(result != VK_SUCCESS) { *semaphore = VK_NULL_HANDLE; @@ -579,14 +581,14 @@ static void createSemaphore(VkSemaphore *semaphore) static void createSemaphores(void) { - createSemaphore(&vulkanContext.imageAvailableSemaphore); - createSemaphore(&vulkanContext.renderingFinishedSemaphore); + createSemaphore(&vulkanContext->imageAvailableSemaphore); + createSemaphore(&vulkanContext->renderingFinishedSemaphore); } static void getSurfaceCaps(void) { VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - vulkanContext.physicalDevice, vulkanContext.surface, &vulkanContext.surfaceCapabilities); + vulkanContext->physicalDevice, vulkanContext->surface, &vulkanContext->surfaceCapabilities); if(result != VK_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, @@ -596,7 +598,7 @@ static void getSurfaceCaps(void) } // check surface usage - if(!(vulkanContext.surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) + if(!(vulkanContext->surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan surface doesn't support VK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); @@ -606,38 +608,38 @@ static void getSurfaceCaps(void) static void getSurfaceFormats(void) { - VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice, - vulkanContext.surface, - &vulkanContext.surfaceFormatsCount, + VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext->physicalDevice, + vulkanContext->surface, + &vulkanContext->surfaceFormatsCount, NULL); if(result != VK_SUCCESS) { - vulkanContext.surfaceFormatsCount = 0; + vulkanContext->surfaceFormatsCount = 0; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n", getVulkanResultString(result)); quit(2); } - if(vulkanContext.surfaceFormatsCount > vulkanContext.surfaceFormatsAllocatedCount) + if(vulkanContext->surfaceFormatsCount > vulkanContext->surfaceFormatsAllocatedCount) { - vulkanContext.surfaceFormatsAllocatedCount = vulkanContext.surfaceFormatsCount; - SDL_free(vulkanContext.surfaceFormats); - vulkanContext.surfaceFormats = - SDL_malloc(sizeof(VkSurfaceFormatKHR) * vulkanContext.surfaceFormatsAllocatedCount); - if(!vulkanContext.surfaceFormats) + vulkanContext->surfaceFormatsAllocatedCount = vulkanContext->surfaceFormatsCount; + SDL_free(vulkanContext->surfaceFormats); + vulkanContext->surfaceFormats = + SDL_malloc(sizeof(VkSurfaceFormatKHR) * vulkanContext->surfaceFormatsAllocatedCount); + if(!vulkanContext->surfaceFormats) { - vulkanContext.surfaceFormatsCount = 0; + vulkanContext->surfaceFormatsCount = 0; SDL_OutOfMemory(); quit(2); } } - result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice, - vulkanContext.surface, - &vulkanContext.surfaceFormatsCount, - vulkanContext.surfaceFormats); + result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext->physicalDevice, + vulkanContext->surface, + &vulkanContext->surfaceFormatsCount, + vulkanContext->surfaceFormats); if(result != VK_SUCCESS) { - vulkanContext.surfaceFormatsCount = 0; + vulkanContext->surfaceFormatsCount = 0; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n", getVulkanResultString(result)); @@ -649,33 +651,33 @@ static void getSwapchainImages(void) { VkResult result; - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; + SDL_free(vulkanContext->swapchainImages); + vulkanContext->swapchainImages = NULL; result = vkGetSwapchainImagesKHR( - vulkanContext.device, vulkanContext.swapchain, &vulkanContext.swapchainImageCount, NULL); + vulkanContext->device, vulkanContext->swapchain, &vulkanContext->swapchainImageCount, NULL); if(result != VK_SUCCESS) { - vulkanContext.swapchainImageCount = 0; + vulkanContext->swapchainImageCount = 0; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetSwapchainImagesKHR(): %s\n", getVulkanResultString(result)); quit(2); } - vulkanContext.swapchainImages = SDL_malloc(sizeof(VkImage) * vulkanContext.swapchainImageCount); - if(!vulkanContext.swapchainImages) + vulkanContext->swapchainImages = SDL_malloc(sizeof(VkImage) * vulkanContext->swapchainImageCount); + if(!vulkanContext->swapchainImages) { SDL_OutOfMemory(); quit(2); } - result = vkGetSwapchainImagesKHR(vulkanContext.device, - vulkanContext.swapchain, - &vulkanContext.swapchainImageCount, - vulkanContext.swapchainImages); + result = vkGetSwapchainImagesKHR(vulkanContext->device, + vulkanContext->swapchain, + &vulkanContext->swapchainImageCount, + vulkanContext->swapchainImages); if(result != VK_SUCCESS) { - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; - vulkanContext.swapchainImageCount = 0; + SDL_free(vulkanContext->swapchainImages); + vulkanContext->swapchainImages = NULL; + vulkanContext->swapchainImageCount = 0; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkGetSwapchainImagesKHR(): %s\n", getVulkanResultString(result)); @@ -691,69 +693,69 @@ static SDL_bool createSwapchain(void) VkResult result; // pick an image count - vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.minImageCount + 1; - if(vulkanContext.swapchainDesiredImageCount > vulkanContext.surfaceCapabilities.maxImageCount - && vulkanContext.surfaceCapabilities.maxImageCount > 0) - vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.maxImageCount; + vulkanContext->swapchainDesiredImageCount = vulkanContext->surfaceCapabilities.minImageCount + 1; + if(vulkanContext->swapchainDesiredImageCount > vulkanContext->surfaceCapabilities.maxImageCount + && vulkanContext->surfaceCapabilities.maxImageCount > 0) + vulkanContext->swapchainDesiredImageCount = vulkanContext->surfaceCapabilities.maxImageCount; // pick a format - if(vulkanContext.surfaceFormatsCount == 1 - && vulkanContext.surfaceFormats[0].format == VK_FORMAT_UNDEFINED) + if(vulkanContext->surfaceFormatsCount == 1 + && vulkanContext->surfaceFormats[0].format == VK_FORMAT_UNDEFINED) { // aren't any preferred formats, so we pick - vulkanContext.surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - vulkanContext.surfaceFormat.format = VK_FORMAT_R8G8B8A8_UNORM; + vulkanContext->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + vulkanContext->surfaceFormat.format = VK_FORMAT_R8G8B8A8_UNORM; } else { - vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[0]; - for(i = 0; i < vulkanContext.surfaceFormatsCount; i++) + vulkanContext->surfaceFormat = vulkanContext->surfaceFormats[0]; + for(i = 0; i < vulkanContext->surfaceFormatsCount; i++) { - if(vulkanContext.surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) + if(vulkanContext->surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) { - vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[i]; + vulkanContext->surfaceFormat = vulkanContext->surfaceFormats[i]; break; } } } // get size - SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h); + SDL_Vulkan_GetDrawableSize(vulkanContext->window, &w, &h); // Clamp the size to the allowable image extent. // SDL_Vulkan_GetDrawableSize()'s result it not always in this range (bug #3287) - vulkanContext.swapchainSize.width = SDL_clamp(w, - vulkanContext.surfaceCapabilities.minImageExtent.width, - vulkanContext.surfaceCapabilities.maxImageExtent.width); + vulkanContext->swapchainSize.width = SDL_clamp(w, + vulkanContext->surfaceCapabilities.minImageExtent.width, + vulkanContext->surfaceCapabilities.maxImageExtent.width); - vulkanContext.swapchainSize.height = SDL_clamp(h, - vulkanContext.surfaceCapabilities.minImageExtent.height, - vulkanContext.surfaceCapabilities.maxImageExtent.height); + vulkanContext->swapchainSize.height = SDL_clamp(h, + vulkanContext->surfaceCapabilities.minImageExtent.height, + vulkanContext->surfaceCapabilities.maxImageExtent.height); if(w == 0 || h == 0) return SDL_FALSE; createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - createInfo.surface = vulkanContext.surface; - createInfo.minImageCount = vulkanContext.swapchainDesiredImageCount; - createInfo.imageFormat = vulkanContext.surfaceFormat.format; - createInfo.imageColorSpace = vulkanContext.surfaceFormat.colorSpace; - createInfo.imageExtent = vulkanContext.swapchainSize; + createInfo.surface = vulkanContext->surface; + createInfo.minImageCount = vulkanContext->swapchainDesiredImageCount; + createInfo.imageFormat = vulkanContext->surfaceFormat.format; + createInfo.imageColorSpace = vulkanContext->surfaceFormat.colorSpace; + createInfo.imageExtent = vulkanContext->swapchainSize; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - createInfo.preTransform = vulkanContext.surfaceCapabilities.currentTransform; + createInfo.preTransform = vulkanContext->surfaceCapabilities.currentTransform; createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; createInfo.clipped = VK_TRUE; - createInfo.oldSwapchain = vulkanContext.swapchain; + createInfo.oldSwapchain = vulkanContext->swapchain; result = - vkCreateSwapchainKHR(vulkanContext.device, &createInfo, NULL, &vulkanContext.swapchain); + vkCreateSwapchainKHR(vulkanContext->device, &createInfo, NULL, &vulkanContext->swapchain); if(createInfo.oldSwapchain) - vkDestroySwapchainKHR(vulkanContext.device, createInfo.oldSwapchain, NULL); + vkDestroySwapchainKHR(vulkanContext->device, createInfo.oldSwapchain, NULL); if(result != VK_SUCCESS) { - vulkanContext.swapchain = VK_NULL_HANDLE; + vulkanContext->swapchain = VK_NULL_HANDLE; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateSwapchainKHR(): %s\n", getVulkanResultString(result)); @@ -765,29 +767,29 @@ static SDL_bool createSwapchain(void) static void destroySwapchain(void) { - if(vulkanContext.swapchain) - vkDestroySwapchainKHR(vulkanContext.device, vulkanContext.swapchain, NULL); - vulkanContext.swapchain = VK_NULL_HANDLE; - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; + if(vulkanContext->swapchain) + vkDestroySwapchainKHR(vulkanContext->device, vulkanContext->swapchain, NULL); + vulkanContext->swapchain = VK_NULL_HANDLE; + SDL_free(vulkanContext->swapchainImages); + vulkanContext->swapchainImages = NULL; } static void destroyCommandBuffers(void) { - if(vulkanContext.commandBuffers) - vkFreeCommandBuffers(vulkanContext.device, - vulkanContext.commandPool, - vulkanContext.swapchainImageCount, - vulkanContext.commandBuffers); - SDL_free(vulkanContext.commandBuffers); - vulkanContext.commandBuffers = NULL; + if(vulkanContext->commandBuffers) + vkFreeCommandBuffers(vulkanContext->device, + vulkanContext->commandPool, + vulkanContext->swapchainImageCount, + vulkanContext->commandBuffers); + SDL_free(vulkanContext->commandBuffers); + vulkanContext->commandBuffers = NULL; } static void destroyCommandPool(void) { - if(vulkanContext.commandPool) - vkDestroyCommandPool(vulkanContext.device, vulkanContext.commandPool, NULL); - vulkanContext.commandPool = VK_NULL_HANDLE; + if(vulkanContext->commandPool) + vkDestroyCommandPool(vulkanContext->device, vulkanContext->commandPool, NULL); + vulkanContext->commandPool = VK_NULL_HANDLE; } static void createCommandPool(void) @@ -798,12 +800,12 @@ static void createCommandPool(void) createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; - createInfo.queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex; + createInfo.queueFamilyIndex = vulkanContext->graphicsQueueFamilyIndex; result = - vkCreateCommandPool(vulkanContext.device, &createInfo, NULL, &vulkanContext.commandPool); + vkCreateCommandPool(vulkanContext->device, &createInfo, NULL, &vulkanContext->commandPool); if(result != VK_SUCCESS) { - vulkanContext.commandPool = VK_NULL_HANDLE; + vulkanContext->commandPool = VK_NULL_HANDLE; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateCommandPool(): %s\n", getVulkanResultString(result)); @@ -817,17 +819,17 @@ static void createCommandBuffers(void) VkCommandBufferAllocateInfo allocateInfo = {0}; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocateInfo.commandPool = vulkanContext.commandPool; + allocateInfo.commandPool = vulkanContext->commandPool; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocateInfo.commandBufferCount = vulkanContext.swapchainImageCount; - vulkanContext.commandBuffers = - SDL_malloc(sizeof(VkCommandBuffer) * vulkanContext.swapchainImageCount); + allocateInfo.commandBufferCount = vulkanContext->swapchainImageCount; + vulkanContext->commandBuffers = + SDL_malloc(sizeof(VkCommandBuffer) * vulkanContext->swapchainImageCount); result = - vkAllocateCommandBuffers(vulkanContext.device, &allocateInfo, vulkanContext.commandBuffers); + vkAllocateCommandBuffers(vulkanContext->device, &allocateInfo, vulkanContext->commandBuffers); if(result != VK_SUCCESS) { - SDL_free(vulkanContext.commandBuffers); - vulkanContext.commandBuffers = NULL; + SDL_free(vulkanContext->commandBuffers); + vulkanContext->commandBuffers = NULL; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkAllocateCommandBuffers(): %s\n", getVulkanResultString(result)); @@ -839,13 +841,13 @@ static void createFences(void) { uint32_t i; - vulkanContext.fences = SDL_malloc(sizeof(VkFence) * vulkanContext.swapchainImageCount); - if(!vulkanContext.fences) + vulkanContext->fences = SDL_malloc(sizeof(VkFence) * vulkanContext->swapchainImageCount); + if(!vulkanContext->fences) { SDL_OutOfMemory(); quit(2); } - for(i = 0; i < vulkanContext.swapchainImageCount; i++) + for(i = 0; i < vulkanContext->swapchainImageCount; i++) { VkResult result; @@ -853,15 +855,15 @@ static void createFences(void) createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; createInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; result = - vkCreateFence(vulkanContext.device, &createInfo, NULL, &vulkanContext.fences[i]); + vkCreateFence(vulkanContext->device, &createInfo, NULL, &vulkanContext->fences[i]); if(result != VK_SUCCESS) { for(; i > 0; i--) { - vkDestroyFence(vulkanContext.device, vulkanContext.fences[i - 1], NULL); + vkDestroyFence(vulkanContext->device, vulkanContext->fences[i - 1], NULL); } - SDL_free(vulkanContext.fences); - vulkanContext.fences = NULL; + SDL_free(vulkanContext->fences); + vulkanContext->fences = NULL; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkCreateFence(): %s\n", getVulkanResultString(result)); @@ -874,14 +876,14 @@ static void destroyFences(void) { uint32_t i; - if(!vulkanContext.fences) + if(!vulkanContext->fences) return; - for(i = 0; i < vulkanContext.swapchainImageCount; i++) + for(i = 0; i < vulkanContext->swapchainImageCount; i++) { - vkDestroyFence(vulkanContext.device, vulkanContext.fences[i], NULL); + vkDestroyFence(vulkanContext->device, vulkanContext->fences[i], NULL); } - SDL_free(vulkanContext.fences); - vulkanContext.fences = NULL; + SDL_free(vulkanContext->fences); + vulkanContext->fences = NULL; } static void recordPipelineImageBarrier(VkCommandBuffer commandBuffer, @@ -919,8 +921,8 @@ static void recordPipelineImageBarrier(VkCommandBuffer commandBuffer, static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue *clearColor) { - VkCommandBuffer commandBuffer = vulkanContext.commandBuffers[frameIndex]; - VkImage image = vulkanContext.swapchainImages[frameIndex]; + VkCommandBuffer commandBuffer = vulkanContext->commandBuffers[frameIndex]; + VkImage image = vulkanContext->swapchainImages[frameIndex]; VkCommandBufferBeginInfo beginInfo = {0}; VkImageSubresourceRange clearRange = {0}; @@ -995,36 +997,57 @@ static SDL_bool createNewSwapchainAndSwapchainSpecificStuff(void) static void initVulkan(void) { + int i; + SDL_Vulkan_LoadLibrary(NULL); - SDL_memset(&vulkanContext, 0, sizeof(VulkanContext)); - loadGlobalFunctions(); - createInstance(); - loadInstanceFunctions(); - createSurface(); - findPhysicalDevice(); - createDevice(); - loadDeviceFunctions(); - getQueues(); - createSemaphores(); - createNewSwapchainAndSwapchainSpecificStuff(); + + vulkanContexts = (VulkanContext *) SDL_calloc(state->num_windows, sizeof (VulkanContext)); + if (!vulkanContexts) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); + quit(2); + } + + for (i = 0; i < state->num_windows; ++i) { + vulkanContext = &vulkanContexts[i]; + vulkanContext->window = state->windows[i]; + loadGlobalFunctions(); + createInstance(); + loadInstanceFunctions(); + createSurface(); + findPhysicalDevice(); + createDevice(); + loadDeviceFunctions(); + getQueues(); + createSemaphores(); + createNewSwapchainAndSwapchainSpecificStuff(); + } } static void shutdownVulkan(void) { - if(vulkanContext.device && vkDeviceWaitIdle) - vkDeviceWaitIdle(vulkanContext.device); - destroySwapchainAndSwapchainSpecificStuff(SDL_TRUE); - if(vulkanContext.imageAvailableSemaphore && vkDestroySemaphore) - vkDestroySemaphore(vulkanContext.device, vulkanContext.imageAvailableSemaphore, NULL); - if(vulkanContext.renderingFinishedSemaphore && vkDestroySemaphore) - vkDestroySemaphore(vulkanContext.device, vulkanContext.renderingFinishedSemaphore, NULL); - if(vulkanContext.device && vkDestroyDevice) - vkDestroyDevice(vulkanContext.device, NULL); - if(vulkanContext.surface && vkDestroySurfaceKHR) - vkDestroySurfaceKHR(vulkanContext.instance, vulkanContext.surface, NULL); - if(vulkanContext.instance && vkDestroyInstance) - vkDestroyInstance(vulkanContext.instance, NULL); - SDL_free(vulkanContext.surfaceFormats); + if (vulkanContexts) { + int i; + for (i = 0; i < state->num_windows; ++i) { + vulkanContext = &vulkanContexts[i]; + if(vulkanContext->device && vkDeviceWaitIdle) + vkDeviceWaitIdle(vulkanContext->device); + destroySwapchainAndSwapchainSpecificStuff(SDL_TRUE); + if(vulkanContext->imageAvailableSemaphore && vkDestroySemaphore) + vkDestroySemaphore(vulkanContext->device, vulkanContext->imageAvailableSemaphore, NULL); + if(vulkanContext->renderingFinishedSemaphore && vkDestroySemaphore) + vkDestroySemaphore(vulkanContext->device, vulkanContext->renderingFinishedSemaphore, NULL); + if(vulkanContext->device && vkDestroyDevice) + vkDestroyDevice(vulkanContext->device, NULL); + if(vulkanContext->surface && vkDestroySurfaceKHR) + vkDestroySurfaceKHR(vulkanContext->instance, vulkanContext->surface, NULL); + if(vulkanContext->instance && vkDestroyInstance) + vkDestroyInstance(vulkanContext->instance, NULL); + SDL_free(vulkanContext->surfaceFormats); + } + SDL_free(vulkanContexts); + vulkanContexts = NULL; + } + SDL_Vulkan_UnloadLibrary(); } @@ -1039,17 +1062,17 @@ static SDL_bool render(void) VkPresentInfoKHR presentInfo = {0}; int w, h; - if(!vulkanContext.swapchain) + if(!vulkanContext->swapchain) { SDL_bool retval = createNewSwapchainAndSwapchainSpecificStuff(); if(!retval) SDL_Delay(100); return retval; } - result = vkAcquireNextImageKHR(vulkanContext.device, - vulkanContext.swapchain, + result = vkAcquireNextImageKHR(vulkanContext->device, + vulkanContext->swapchain, UINT64_MAX, - vulkanContext.imageAvailableSemaphore, + vulkanContext->imageAvailableSemaphore, VK_NULL_HANDLE, &frameIndex); if(result == VK_ERROR_OUT_OF_DATE_KHR) @@ -1062,14 +1085,14 @@ static SDL_bool render(void) quit(2); } result = vkWaitForFences( - vulkanContext.device, 1, &vulkanContext.fences[frameIndex], VK_FALSE, UINT64_MAX); + vulkanContext->device, 1, &vulkanContext->fences[frameIndex], VK_FALSE, UINT64_MAX); if(result != VK_SUCCESS) { SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "vkWaitForFences(): %s\n", getVulkanResultString(result)); quit(2); } - result = vkResetFences(vulkanContext.device, 1, &vulkanContext.fences[frameIndex]); + result = vkResetFences(vulkanContext->device, 1, &vulkanContext->fences[frameIndex]); if(result != VK_SUCCESS) { SDL_LogError( @@ -1084,14 +1107,14 @@ static SDL_bool render(void) rerecordCommandBuffer(frameIndex, &clearColor); submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = &vulkanContext.imageAvailableSemaphore; + submitInfo.pWaitSemaphores = &vulkanContext->imageAvailableSemaphore; submitInfo.pWaitDstStageMask = &waitDestStageMask; submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &vulkanContext.commandBuffers[frameIndex]; + submitInfo.pCommandBuffers = &vulkanContext->commandBuffers[frameIndex]; submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &vulkanContext.renderingFinishedSemaphore; + submitInfo.pSignalSemaphores = &vulkanContext->renderingFinishedSemaphore; result = vkQueueSubmit( - vulkanContext.graphicsQueue, 1, &submitInfo, vulkanContext.fences[frameIndex]); + vulkanContext->graphicsQueue, 1, &submitInfo, vulkanContext->fences[frameIndex]); if(result != VK_SUCCESS) { SDL_LogError( @@ -1100,11 +1123,11 @@ static SDL_bool render(void) } presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = &vulkanContext.renderingFinishedSemaphore; + presentInfo.pWaitSemaphores = &vulkanContext->renderingFinishedSemaphore; presentInfo.swapchainCount = 1; - presentInfo.pSwapchains = &vulkanContext.swapchain; + presentInfo.pSwapchains = &vulkanContext->swapchain; presentInfo.pImageIndices = &frameIndex; - result = vkQueuePresentKHR(vulkanContext.presentQueue, &presentInfo); + result = vkQueuePresentKHR(vulkanContext->presentQueue, &presentInfo); if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { return createNewSwapchainAndSwapchainSpecificStuff(); @@ -1116,8 +1139,8 @@ static SDL_bool render(void) getVulkanResultString(result)); quit(2); } - SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h); - if(w != (int)vulkanContext.swapchainSize.width || h != (int)vulkanContext.swapchainSize.height) + SDL_Vulkan_GetDrawableSize(vulkanContext->window, &w, &h); + if(w != (int)vulkanContext->swapchainSize.width || h != (int)vulkanContext->swapchainSize.height) { return createNewSwapchainAndSwapchainSpecificStuff(); } @@ -1144,7 +1167,6 @@ int main(int argc, char *argv[]) /* Set Vulkan parameters */ state->window_flags |= SDL_WINDOW_VULKAN; - state->num_windows = 1; state->skip_renderer = 1; if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { @@ -1170,13 +1192,20 @@ int main(int argc, char *argv[]) { /* Check for events */ ++frames; - while(SDL_PollEvent(&event)) + while(SDL_PollEvent(&event)) /* !!! FIXME: fix coding conventions with braces and spaces */ { SDLTest_CommonEvent(state, &event, &done); } - if(!done) - render(); + if (!done) { + int i; + for (i = 0; i < state->num_windows; ++i) { + if (state->windows[i]) { + vulkanContext = &vulkanContexts[i]; + render(); + } + } + } } /* Print out some timing information */