/*
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "SDL_test_common.h"

#if defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)

int main(int argc, char *argv[])
{
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Vulkan support on this system\n");
    return 1;
}

#else

#define VK_NO_PROTOTYPES
#ifdef HAVE_VULKAN_H
#include <vulkan/vulkan.h>
#else
/* SDL includes a copy for building on systems without the Vulkan SDK */
#include "../src/video/khronos/vulkan/vulkan.h"
#endif
#include "SDL_vulkan.h"

#ifndef UINT64_MAX /* VS2008 */
#define UINT64_MAX 18446744073709551615
#endif

#define VULKAN_FUNCTIONS()                                              \
    VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR)                       \
    VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers)                    \
    VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer)                        \
    VULKAN_DEVICE_FUNCTION(vkCmdClearColorImage)                        \
    VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier)                        \
    VULKAN_DEVICE_FUNCTION(vkCreateCommandPool)                         \
    VULKAN_DEVICE_FUNCTION(vkCreateFence)                               \
    VULKAN_DEVICE_FUNCTION(vkCreateImageView)                           \
    VULKAN_DEVICE_FUNCTION(vkCreateSemaphore)                           \
    VULKAN_DEVICE_FUNCTION(vkCreateSwapchainKHR)                        \
    VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool)                        \
    VULKAN_DEVICE_FUNCTION(vkDestroyDevice)                             \
    VULKAN_DEVICE_FUNCTION(vkDestroyFence)                              \
    VULKAN_DEVICE_FUNCTION(vkDestroyImageView)                          \
    VULKAN_DEVICE_FUNCTION(vkDestroySemaphore)                          \
    VULKAN_DEVICE_FUNCTION(vkDestroySwapchainKHR)                       \
    VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle)                            \
    VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer)                          \
    VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers)                        \
    VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue)                            \
    VULKAN_DEVICE_FUNCTION(vkGetFenceStatus)                            \
    VULKAN_DEVICE_FUNCTION(vkGetSwapchainImagesKHR)                     \
    VULKAN_DEVICE_FUNCTION(vkQueuePresentKHR)                           \
    VULKAN_DEVICE_FUNCTION(vkQueueSubmit)                               \
    VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer)                        \
    VULKAN_DEVICE_FUNCTION(vkResetFences)                               \
    VULKAN_DEVICE_FUNCTION(vkWaitForFences)                             \
    VULKAN_GLOBAL_FUNCTION(vkCreateInstance)                            \
    VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties)      \
    VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties)          \
    VULKAN_INSTANCE_FUNCTION(vkCreateDevice)                            \
    VULKAN_INSTANCE_FUNCTION(vkDestroyInstance)                         \
    VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR)                       \
    VULKAN_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties)      \
    VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)                \
    VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr)                       \
    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures)               \
    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)             \
    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)  \
    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR)      \
    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) \
    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR)

#define VULKAN_DEVICE_FUNCTION(name) static PFN_##name name = NULL;
#define VULKAN_GLOBAL_FUNCTION(name) static PFN_##name name = NULL;
#define VULKAN_INSTANCE_FUNCTION(name) static PFN_##name name = NULL;
VULKAN_FUNCTIONS()
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
static PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;

/* Based on the headers found in
 * https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers
 */
#if VK_HEADER_VERSION < 22
enum
{
    VK_ERROR_FRAGMENTED_POOL = -12,
};
#endif
#if VK_HEADER_VERSION < 38
enum {
    VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000
};
#endif

static const char *getVulkanResultString(VkResult result)
{
    switch((int)result)
    {
    case VK_SUCCESS:
        return "VK_SUCCESS";
    case VK_NOT_READY:
        return "VK_NOT_READY";
    case VK_TIMEOUT:
        return "VK_TIMEOUT";
    case VK_EVENT_SET:
        return "VK_EVENT_SET";
    case VK_EVENT_RESET:
        return "VK_EVENT_RESET";
    case VK_INCOMPLETE:
        return "VK_INCOMPLETE";
    case VK_ERROR_OUT_OF_HOST_MEMORY:
        return "VK_ERROR_OUT_OF_HOST_MEMORY";
    case VK_ERROR_OUT_OF_DEVICE_MEMORY:
        return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
    case VK_ERROR_INITIALIZATION_FAILED:
        return "VK_ERROR_INITIALIZATION_FAILED";
    case VK_ERROR_DEVICE_LOST:
        return "VK_ERROR_DEVICE_LOST";
    case VK_ERROR_MEMORY_MAP_FAILED:
        return "VK_ERROR_MEMORY_MAP_FAILED";
    case VK_ERROR_LAYER_NOT_PRESENT:
        return "VK_ERROR_LAYER_NOT_PRESENT";
    case VK_ERROR_EXTENSION_NOT_PRESENT:
        return "VK_ERROR_EXTENSION_NOT_PRESENT";
    case VK_ERROR_FEATURE_NOT_PRESENT:
        return "VK_ERROR_FEATURE_NOT_PRESENT";
    case VK_ERROR_INCOMPATIBLE_DRIVER:
        return "VK_ERROR_INCOMPATIBLE_DRIVER";
    case VK_ERROR_TOO_MANY_OBJECTS:
        return "VK_ERROR_TOO_MANY_OBJECTS";
    case VK_ERROR_FORMAT_NOT_SUPPORTED:
        return "VK_ERROR_FORMAT_NOT_SUPPORTED";
    case VK_ERROR_FRAGMENTED_POOL:
        return "VK_ERROR_FRAGMENTED_POOL";
    case VK_ERROR_SURFACE_LOST_KHR:
        return "VK_ERROR_SURFACE_LOST_KHR";
    case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
        return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
    case VK_SUBOPTIMAL_KHR:
        return "VK_SUBOPTIMAL_KHR";
    case VK_ERROR_OUT_OF_DATE_KHR:
        return "VK_ERROR_OUT_OF_DATE_KHR";
    case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
        return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
    case VK_ERROR_VALIDATION_FAILED_EXT:
        return "VK_ERROR_VALIDATION_FAILED_EXT";
    case VK_ERROR_OUT_OF_POOL_MEMORY_KHR:
        return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR";
    case VK_ERROR_INVALID_SHADER_NV:
        return "VK_ERROR_INVALID_SHADER_NV";
    default:
        break;
    }
    if(result < 0)
        return "VK_ERROR_<Unknown>";
    return "VK_<Unknown>";
}

typedef struct VulkanContext
{
    VkInstance instance;
    VkDevice device;
    VkSurfaceKHR surface;
    VkSwapchainKHR swapchain;
    VkPhysicalDeviceProperties physicalDeviceProperties;
    VkPhysicalDeviceFeatures physicalDeviceFeatures;
    uint32_t graphicsQueueFamilyIndex;
    uint32_t presentQueueFamilyIndex;
    VkPhysicalDevice physicalDevice;
    VkQueue graphicsQueue;
    VkQueue presentQueue;
    VkSemaphore imageAvailableSemaphore;
    VkSemaphore renderingFinishedSemaphore;
    VkSurfaceCapabilitiesKHR surfaceCapabilities;
    VkSurfaceFormatKHR *surfaceFormats;
    uint32_t surfaceFormatsAllocatedCount;
    uint32_t surfaceFormatsCount;
    uint32_t swapchainDesiredImageCount;
    VkSurfaceFormatKHR surfaceFormat;
    VkExtent2D swapchainSize;
    VkCommandPool commandPool;
    uint32_t swapchainImageCount;
    VkImage *swapchainImages;
    VkCommandBuffer *commandBuffers;
    VkFence *fences;
} VulkanContext;

static SDLTest_CommonState *state;
static VulkanContext vulkanContext = {0};

static void shutdownVulkan(void);

/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
    shutdownVulkan();
    SDLTest_CommonQuit(state);
    exit(rc);
}

static void loadGlobalFunctions(void)
{
    vkGetInstanceProcAddr = SDL_Vulkan_GetVkGetInstanceProcAddr();
    if(!vkGetInstanceProcAddr)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "SDL_Vulkan_GetVkGetInstanceProcAddr(): %s\n",
                     SDL_GetError());
        quit(2);
    }

#define VULKAN_DEVICE_FUNCTION(name)
#define VULKAN_GLOBAL_FUNCTION(name)                                                   \
    name = (PFN_##name)vkGetInstanceProcAddr(VK_NULL_HANDLE, #name);                   \
    if(!name)                                                                          \
    {                                                                                  \
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,                                     \
                     "vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \
        quit(2);                                                                       \
    }
#define VULKAN_INSTANCE_FUNCTION(name)
    VULKAN_FUNCTIONS()
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
}

static void createInstance(void)
{
    VkApplicationInfo appInfo = {0};
    VkInstanceCreateInfo instanceCreateInfo = {0};
    const char **extensions = NULL;
    unsigned extensionCount = 0;
	VkResult result;


	appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.apiVersion = VK_API_VERSION_1_0;
    instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instanceCreateInfo.pApplicationInfo = &appInfo;
    if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, NULL))
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "SDL_Vulkan_GetInstanceExtensions(): %s\n",
                     SDL_GetError());
        quit(2);
    }
    extensions = SDL_malloc(sizeof(const char *) * extensionCount);
    if(!extensions)
    {
        SDL_OutOfMemory();
        quit(2);
    }
    if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, extensions))
    {
        SDL_free((void*)extensions);
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "SDL_Vulkan_GetInstanceExtensions(): %s\n",
                     SDL_GetError());
        quit(2);
    }
    instanceCreateInfo.enabledExtensionCount = extensionCount;
    instanceCreateInfo.ppEnabledExtensionNames = extensions;
    result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext.instance);
    SDL_free((void*)extensions);
    if(result != VK_SUCCESS)
    {
        vulkanContext.instance = VK_NULL_HANDLE;
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkCreateInstance(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
}

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);     \
    if(!name)                                                                    \
    {                                                                            \
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,                               \
                     "vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \
        quit(2);                                                                 \
    }
    VULKAN_FUNCTIONS()
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
}

static void createSurface(void)
{
    if(!SDL_Vulkan_CreateSurface(state->windows[0],
                                 vulkanContext.instance,
                                 &vulkanContext.surface))
    {
        vulkanContext.surface = VK_NULL_HANDLE;
        SDL_LogError(
            SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError());
        quit(2);
    }
}

static void findPhysicalDevice(void)
{
    uint32_t physicalDeviceCount = 0;
	VkPhysicalDevice *physicalDevices;
	VkQueueFamilyProperties *queueFamiliesProperties = NULL;
    uint32_t queueFamiliesPropertiesAllocatedSize = 0;
    VkExtensionProperties *deviceExtensions = NULL;
    uint32_t deviceExtensionsAllocatedSize = 0;
	uint32_t physicalDeviceIndex;

    VkResult result =
        vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, NULL);
    if(result != VK_SUCCESS)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkEnumeratePhysicalDevices(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
    if(physicalDeviceCount == 0)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkEnumeratePhysicalDevices(): no physical devices\n");
        quit(2);
    }
    physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount);
    if(!physicalDevices)
    {
        SDL_OutOfMemory();
        quit(2);
    }
    result =
        vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, physicalDevices);
    if(result != VK_SUCCESS)
    {
        SDL_free(physicalDevices);
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkEnumeratePhysicalDevices(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
    vulkanContext.physicalDevice = NULL;
    for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount;
        physicalDeviceIndex++)
    {
        uint32_t queueFamiliesCount = 0;
		uint32_t queueFamilyIndex;
        uint32_t deviceExtensionCount = 0;
		SDL_bool hasSwapchainExtension = SDL_FALSE;
		uint32_t i;


		VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex];
        vkGetPhysicalDeviceProperties(physicalDevice, &vulkanContext.physicalDeviceProperties);
        if(VK_VERSION_MAJOR(vulkanContext.physicalDeviceProperties.apiVersion) < 1)
            continue;
        vkGetPhysicalDeviceFeatures(physicalDevice, &vulkanContext.physicalDeviceFeatures);
        vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, NULL);
        if(queueFamiliesCount == 0)
            continue;
        if(queueFamiliesPropertiesAllocatedSize < queueFamiliesCount)
        {
            SDL_free(queueFamiliesProperties);
            queueFamiliesPropertiesAllocatedSize = queueFamiliesCount;
            queueFamiliesProperties =
                SDL_malloc(sizeof(VkQueueFamilyProperties) * queueFamiliesPropertiesAllocatedSize);
            if(!queueFamiliesProperties)
            {
                SDL_free(physicalDevices);
                SDL_free(deviceExtensions);
                SDL_OutOfMemory();
                quit(2);
            }
        }
        vkGetPhysicalDeviceQueueFamilyProperties(
            physicalDevice, &queueFamiliesCount, queueFamiliesProperties);
        vulkanContext.graphicsQueueFamilyIndex = queueFamiliesCount;
        vulkanContext.presentQueueFamilyIndex = queueFamiliesCount;
        for(queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount;
            queueFamilyIndex++)
        {
            VkBool32 supported = 0;

			if(queueFamiliesProperties[queueFamilyIndex].queueCount == 0)
                continue;
            if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT)
                vulkanContext.graphicsQueueFamilyIndex = queueFamilyIndex;
            result = vkGetPhysicalDeviceSurfaceSupportKHR(
                physicalDevice, queueFamilyIndex, vulkanContext.surface, &supported);
            if(result != VK_SUCCESS)
            {
                SDL_free(physicalDevices);
                SDL_free(queueFamiliesProperties);
                SDL_free(deviceExtensions);
                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                             "vkGetPhysicalDeviceSurfaceSupportKHR(): %s\n",
                             getVulkanResultString(result));
                quit(2);
            }
            if(supported)
            {
                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
            continue;
        if(vulkanContext.presentQueueFamilyIndex == queueFamiliesCount) // no good queues found
            continue;
        result =
            vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL);
        if(result != VK_SUCCESS)
        {
            SDL_free(physicalDevices);
            SDL_free(queueFamiliesProperties);
            SDL_free(deviceExtensions);
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                         "vkEnumerateDeviceExtensionProperties(): %s\n",
                         getVulkanResultString(result));
            quit(2);
        }
        if(deviceExtensionCount == 0)
            continue;
        if(deviceExtensionsAllocatedSize < deviceExtensionCount)
        {
            SDL_free(deviceExtensions);
            deviceExtensionsAllocatedSize = deviceExtensionCount;
            deviceExtensions =
                SDL_malloc(sizeof(VkExtensionProperties) * deviceExtensionsAllocatedSize);
            if(!deviceExtensions)
            {
                SDL_free(physicalDevices);
                SDL_free(queueFamiliesProperties);
                SDL_OutOfMemory();
                quit(2);
            }
        }
        result = vkEnumerateDeviceExtensionProperties(
            physicalDevice, NULL, &deviceExtensionCount, deviceExtensions);
        if(result != VK_SUCCESS)
        {
            SDL_free(physicalDevices);
            SDL_free(queueFamiliesProperties);
            SDL_free(deviceExtensions);
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                         "vkEnumerateDeviceExtensionProperties(): %s\n",
                         getVulkanResultString(result));
            quit(2);
        }
        for(i = 0; i < deviceExtensionCount; i++)
        {
            if(0 == SDL_strcmp(deviceExtensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME))
            {
                hasSwapchainExtension = SDL_TRUE;
                break;
            }
        }
        if(!hasSwapchainExtension)
            continue;
        vulkanContext.physicalDevice = physicalDevice;
        break;
    }
    SDL_free(physicalDevices);
    SDL_free(queueFamiliesProperties);
    SDL_free(deviceExtensions);
    if(!vulkanContext.physicalDevice)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan: no viable physical devices found");
        quit(2);
    }
}

static void createDevice(void)
{
    VkDeviceQueueCreateInfo deviceQueueCreateInfo[1] = {0};
    static const float queuePriority[] = {1.0f};
    VkDeviceCreateInfo deviceCreateInfo = {0};
    static const char *const deviceExtensionNames[] = {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
    };
	VkResult result;

	deviceQueueCreateInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    deviceQueueCreateInfo->queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex;
    deviceQueueCreateInfo->queueCount = 1;
    deviceQueueCreateInfo->pQueuePriorities = &queuePriority[0];

    deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    deviceCreateInfo.queueCreateInfoCount = 1;
    deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfo;
    deviceCreateInfo.pEnabledFeatures = NULL;
    deviceCreateInfo.enabledExtensionCount = SDL_arraysize(deviceExtensionNames);
    deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;
    result = vkCreateDevice(
        vulkanContext.physicalDevice, &deviceCreateInfo, NULL, &vulkanContext.device);
    if(result != VK_SUCCESS)
    {
        vulkanContext.device = VK_NULL_HANDLE;
        SDL_LogError(
            SDL_LOG_CATEGORY_APPLICATION, "vkCreateDevice(): %s\n", getVulkanResultString(result));
        quit(2);
    }
}

static void loadDeviceFunctions(void)
{
#define VULKAN_DEVICE_FUNCTION(name)                                         \
    name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext.device, #name);     \
    if(!name)                                                                \
    {                                                                        \
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,                           \
                     "vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \
        quit(2);                                                             \
    }
#define VULKAN_GLOBAL_FUNCTION(name)
#define VULKAN_INSTANCE_FUNCTION(name)
    VULKAN_FUNCTIONS()
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
}

#undef VULKAN_FUNCTIONS

static void getQueues(void)
{
    vkGetDeviceQueue(vulkanContext.device,
                     vulkanContext.graphicsQueueFamilyIndex,
                     0,
                     &vulkanContext.graphicsQueue);
    if(vulkanContext.graphicsQueueFamilyIndex != vulkanContext.presentQueueFamilyIndex)
        vkGetDeviceQueue(vulkanContext.device,
                         vulkanContext.presentQueueFamilyIndex,
                         0,
                         &vulkanContext.presentQueue);
    else
        vulkanContext.presentQueue = vulkanContext.graphicsQueue;
}

static void createSemaphore(VkSemaphore *semaphore)
{
	VkResult result;

    VkSemaphoreCreateInfo createInfo = {0};
    createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
    result = vkCreateSemaphore(vulkanContext.device, &createInfo, NULL, semaphore);
    if(result != VK_SUCCESS)
    {
        *semaphore = VK_NULL_HANDLE;
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkCreateSemaphore(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
}

static void createSemaphores(void)
{
    createSemaphore(&vulkanContext.imageAvailableSemaphore);
    createSemaphore(&vulkanContext.renderingFinishedSemaphore);
}

static void getSurfaceCaps(void)
{
    VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
        vulkanContext.physicalDevice, vulkanContext.surface, &vulkanContext.surfaceCapabilities);
    if(result != VK_SUCCESS)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }

    // check surface usage
    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");
        quit(2);
    }
}

static void getSurfaceFormats(void)
{
    VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice,
                                                           vulkanContext.surface,
                                                           &vulkanContext.surfaceFormatsCount,
                                                           NULL);
    if(result != VK_SUCCESS)
    {
        vulkanContext.surfaceFormatsCount = 0;
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
    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.surfaceFormatsCount = 0;
            SDL_OutOfMemory();
            quit(2);
        }
    }
    result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice,
                                                  vulkanContext.surface,
                                                  &vulkanContext.surfaceFormatsCount,
                                                  vulkanContext.surfaceFormats);
    if(result != VK_SUCCESS)
    {
        vulkanContext.surfaceFormatsCount = 0;
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
}

static void getSwapchainImages(void)
{
	VkResult result;

    SDL_free(vulkanContext.swapchainImages);
    vulkanContext.swapchainImages = NULL;
    result = vkGetSwapchainImagesKHR(
        vulkanContext.device, vulkanContext.swapchain, &vulkanContext.swapchainImageCount, NULL);
    if(result != VK_SUCCESS)
    {
        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)
    {
        SDL_OutOfMemory();
        quit(2);
    }
    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_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkGetSwapchainImagesKHR(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
}

static SDL_bool createSwapchain(void)
{
	uint32_t i;
	int w, h;
	VkSwapchainCreateInfoKHR createInfo = {0};
	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;

    // pick a format
    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;
    }
    else
    {
        vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[0];
        for(i = 0; i < vulkanContext.surfaceFormatsCount; i++)
        {
            if(vulkanContext.surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM)
            {
                vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[i];
                break;
            }
        }
    }

    // get size
    SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h);
    vulkanContext.swapchainSize.width = w;
    vulkanContext.swapchainSize.height = h;
    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.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.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
    createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    createInfo.clipped = VK_TRUE;
    createInfo.oldSwapchain = vulkanContext.swapchain;
    result =
        vkCreateSwapchainKHR(vulkanContext.device, &createInfo, NULL, &vulkanContext.swapchain);
    if(createInfo.oldSwapchain)
        vkDestroySwapchainKHR(vulkanContext.device, createInfo.oldSwapchain, NULL);
    if(result != VK_SUCCESS)
    {
        vulkanContext.swapchain = VK_NULL_HANDLE;
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkCreateSwapchainKHR(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
    getSwapchainImages();
    return SDL_TRUE;
}

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;
}

static void destroyCommandBuffers(void)
{
    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;
}

static void createCommandPool(void)
{
	VkResult result;

    VkCommandPoolCreateInfo createInfo = {0};
    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;
    result =
        vkCreateCommandPool(vulkanContext.device, &createInfo, NULL, &vulkanContext.commandPool);
    if(result != VK_SUCCESS)
    {
        vulkanContext.commandPool = VK_NULL_HANDLE;
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkCreateCommandPool(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
}

static void createCommandBuffers(void)
{
	VkResult result;

    VkCommandBufferAllocateInfo allocateInfo = {0};
    allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
    allocateInfo.commandPool = vulkanContext.commandPool;
    allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
    allocateInfo.commandBufferCount = vulkanContext.swapchainImageCount;
    vulkanContext.commandBuffers =
        SDL_malloc(sizeof(VkCommandBuffer) * vulkanContext.swapchainImageCount);
    result =
        vkAllocateCommandBuffers(vulkanContext.device, &allocateInfo, vulkanContext.commandBuffers);
    if(result != VK_SUCCESS)
    {
        SDL_free(vulkanContext.commandBuffers);
        vulkanContext.commandBuffers = NULL;
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkAllocateCommandBuffers(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
}

static void createFences(void)
{
	uint32_t i;

    vulkanContext.fences = SDL_malloc(sizeof(VkFence) * vulkanContext.swapchainImageCount);
    if(!vulkanContext.fences)
    {
        SDL_OutOfMemory();
        quit(2);
    }
    for(i = 0; i < vulkanContext.swapchainImageCount; i++)
    {
		VkResult result;

        VkFenceCreateInfo createInfo = {0};
        createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
        createInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
        result =
            vkCreateFence(vulkanContext.device, &createInfo, NULL, &vulkanContext.fences[i]);
        if(result != VK_SUCCESS)
        {
            for(; i > 0; i--)
            {
                vkDestroyFence(vulkanContext.device, vulkanContext.fences[i - 1], NULL);
            }
            SDL_free(vulkanContext.fences);
            vulkanContext.fences = NULL;
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                         "vkCreateFence(): %s\n",
                         getVulkanResultString(result));
            quit(2);
        }
    }
}

static void destroyFences(void)
{
	uint32_t i;

    if(!vulkanContext.fences)
        return;
    for(i = 0; i < vulkanContext.swapchainImageCount; i++)
    {
        vkDestroyFence(vulkanContext.device, vulkanContext.fences[i], NULL);
    }
    SDL_free(vulkanContext.fences);
    vulkanContext.fences = NULL;
}

static void recordPipelineImageBarrier(VkCommandBuffer commandBuffer,
                                       VkAccessFlags sourceAccessMask,
                                       VkAccessFlags destAccessMask,
                                       VkImageLayout sourceLayout,
                                       VkImageLayout destLayout,
                                       VkImage image)
{
    VkImageMemoryBarrier barrier = {0};
    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    barrier.srcAccessMask = sourceAccessMask;
    barrier.dstAccessMask = destAccessMask;
    barrier.oldLayout = sourceLayout;
    barrier.newLayout = destLayout;
    barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
    barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
    barrier.image = image;
    barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    barrier.subresourceRange.baseMipLevel = 0;
    barrier.subresourceRange.levelCount = 1;
    barrier.subresourceRange.baseArrayLayer = 0;
    barrier.subresourceRange.layerCount = 1;
    vkCmdPipelineBarrier(commandBuffer,
                         VK_PIPELINE_STAGE_TRANSFER_BIT,
                         VK_PIPELINE_STAGE_TRANSFER_BIT,
                         0,
                         0,
                         NULL,
                         0,
                         NULL,
                         1,
                         &barrier);
}

static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue *clearColor)
{
    VkCommandBuffer commandBuffer = vulkanContext.commandBuffers[frameIndex];
    VkImage image = vulkanContext.swapchainImages[frameIndex];
	VkCommandBufferBeginInfo beginInfo = {0};
    VkImageSubresourceRange clearRange = {0};

    VkResult result = vkResetCommandBuffer(commandBuffer, 0);
    if(result != VK_SUCCESS)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkResetCommandBuffer(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
    beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
    result = vkBeginCommandBuffer(commandBuffer, &beginInfo);
    if(result != VK_SUCCESS)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkBeginCommandBuffer(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
    recordPipelineImageBarrier(commandBuffer,
                               0,
                               VK_ACCESS_TRANSFER_WRITE_BIT,
                               VK_IMAGE_LAYOUT_UNDEFINED,
                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                               image);
    clearRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    clearRange.baseMipLevel = 0;
    clearRange.levelCount = 1;
    clearRange.baseArrayLayer = 0;
    clearRange.layerCount = 1;
    vkCmdClearColorImage(
        commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearColor, 1, &clearRange);
    recordPipelineImageBarrier(commandBuffer,
                               VK_ACCESS_TRANSFER_WRITE_BIT,
                               VK_ACCESS_MEMORY_READ_BIT,
                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                               VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
                               image);
    result = vkEndCommandBuffer(commandBuffer);
    if(result != VK_SUCCESS)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkEndCommandBuffer(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
}

static void destroySwapchainAndSwapchainSpecificStuff(SDL_bool doDestroySwapchain)
{
    destroyFences();
    destroyCommandBuffers();
    destroyCommandPool();
    if(doDestroySwapchain)
        destroySwapchain();
}

static SDL_bool createNewSwapchainAndSwapchainSpecificStuff(void)
{
    destroySwapchainAndSwapchainSpecificStuff(SDL_FALSE);
    getSurfaceCaps();
    getSurfaceFormats();
    if(!createSwapchain())
        return SDL_FALSE;
    createCommandPool();
    createCommandBuffers();
    createFences();
    return SDL_TRUE;
}

static void initVulkan(void)
{
    SDL_Vulkan_LoadLibrary(NULL);
    SDL_memset(&vulkanContext, 0, sizeof(VulkanContext));
    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);
    SDL_Vulkan_UnloadLibrary();
}

static SDL_bool render(void)
{
    uint32_t frameIndex;
    VkResult result;
    double currentTime;
    VkClearColorValue clearColor = {0};
    VkPipelineStageFlags waitDestStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
    VkSubmitInfo submitInfo = {0};
    VkPresentInfoKHR presentInfo = {0};
    int w, h;

    if(!vulkanContext.swapchain)
    {
        SDL_bool retval = createNewSwapchainAndSwapchainSpecificStuff();
        if(!retval)
            SDL_Delay(100);
        return retval;
    }
    result = vkAcquireNextImageKHR(vulkanContext.device,
                                            vulkanContext.swapchain,
                                            UINT64_MAX,
                                            vulkanContext.imageAvailableSemaphore,
                                            VK_NULL_HANDLE,
                                            &frameIndex);
    if(result == VK_ERROR_OUT_OF_DATE_KHR)
        return createNewSwapchainAndSwapchainSpecificStuff();
    if(result != VK_SUBOPTIMAL_KHR && result != VK_SUCCESS)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkAcquireNextImageKHR(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
    result = vkWaitForFences(
        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]);
    if(result != VK_SUCCESS)
    {
        SDL_LogError(
            SDL_LOG_CATEGORY_APPLICATION, "vkResetFences(): %s\n", getVulkanResultString(result));
        quit(2);
    }
    currentTime = (double)SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency();
    clearColor.float32[0] = (float)(0.5 + 0.5 * SDL_sin(currentTime));
    clearColor.float32[1] = (float)(0.5 + 0.5 * SDL_sin(currentTime + M_PI * 2 / 3));
    clearColor.float32[2] = (float)(0.5 + 0.5 * SDL_sin(currentTime + M_PI * 4 / 3));
    clearColor.float32[3] = 1;
    rerecordCommandBuffer(frameIndex, &clearColor);
    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    submitInfo.waitSemaphoreCount = 1;
    submitInfo.pWaitSemaphores = &vulkanContext.imageAvailableSemaphore;
    submitInfo.pWaitDstStageMask = &waitDestStageMask;
    submitInfo.commandBufferCount = 1;
    submitInfo.pCommandBuffers = &vulkanContext.commandBuffers[frameIndex];
    submitInfo.signalSemaphoreCount = 1;
    submitInfo.pSignalSemaphores = &vulkanContext.renderingFinishedSemaphore;
    result = vkQueueSubmit(
        vulkanContext.graphicsQueue, 1, &submitInfo, vulkanContext.fences[frameIndex]);
    if(result != VK_SUCCESS)
    {
        SDL_LogError(
            SDL_LOG_CATEGORY_APPLICATION, "vkQueueSubmit(): %s\n", getVulkanResultString(result));
        quit(2);
    }
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.waitSemaphoreCount = 1;
    presentInfo.pWaitSemaphores = &vulkanContext.renderingFinishedSemaphore;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = &vulkanContext.swapchain;
    presentInfo.pImageIndices = &frameIndex;
    result = vkQueuePresentKHR(vulkanContext.presentQueue, &presentInfo);
    if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
    {
        return createNewSwapchainAndSwapchainSpecificStuff();
    }
    if(result != VK_SUCCESS)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "vkQueuePresentKHR(): %s\n",
                     getVulkanResultString(result));
        quit(2);
    }
    SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h);
    if(w != (int)vulkanContext.swapchainSize.width || h != (int)vulkanContext.swapchainSize.height)
    {
        return createNewSwapchainAndSwapchainSpecificStuff();
    }
    return SDL_TRUE;
}

int main(int argc, char *argv[])
{
    int fsaa, accel;
    int done;
    SDL_DisplayMode mode;
    SDL_Event event;
    Uint32 then, now, frames;
    int dw, dh;

    /* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* Initialize parameters */
    fsaa = 0;
    accel = -1;

    /* Initialize test framework */
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
    if(!state)
    {
        return 1;
    }

    /* 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)) {
        SDLTest_CommonQuit(state);
        return 1;
    }

    SDL_GetCurrentDisplayMode(0, &mode);
    SDL_Log("Screen BPP    : %d\n", SDL_BITSPERPIXEL(mode.format));
    SDL_GetWindowSize(state->windows[0], &dw, &dh);
    SDL_Log("Window Size   : %d,%d\n", dw, dh);
    SDL_Vulkan_GetDrawableSize(state->windows[0], &dw, &dh);
    SDL_Log("Draw Size     : %d,%d\n", dw, dh);
    SDL_Log("\n");

    initVulkan();

    /* Main render loop */
    frames = 0;
    then = SDL_GetTicks();
    done = 0;
    while(!done)
    {
        /* Check for events */
        ++frames;
        while(SDL_PollEvent(&event))
        {
            SDLTest_CommonEvent(state, &event, &done);
        }

        if(!done)
            render();
    }

    /* Print out some timing information */
    now = SDL_GetTicks();
    if(now > then)
    {
        SDL_Log("%2.2f frames per second\n", ((double)frames * 1000) / (now - then));
    }
    quit(0);
    return 0;
}

#endif
