/*
 * Copyright (c) 2015-2019 The Khronos Group Inc.
 * Copyright (c) 2015-2019 Valve Corporation
 * Copyright (c) 2015-2019 LunarG, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
 * Author: David Pinedo <david@lunarg.com>
 * Author: Mark Lobodzinski <mark@lunarg.com>
 * Author: Rene Lindsay <rene@lunarg.com>
 * Author: Jeremy Kniager <jeremyk@lunarg.com>
 * Author: Shannon McPherson <shannon@lunarg.com>
 * Author: Bob Ellison <bob@lunarg.com>
 * Author: Charles Giessen <charles@lunarg.com>
 *
 */

#include <algorithm>
#include <array>
#include <iostream>
#include <fstream>
#include <memory>
#include <ostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <utility>

#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstring>

#ifdef __GNUC__
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
#else
#define strndup(p, n) strdup(p)
#endif

#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif  // _WIN32

#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
#include <X11/Xutil.h>
#endif

#if defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)
#include "metal_view.h"
#endif

#include <vulkan/vulkan.h>

#define ERR(err) std::cerr << __FILE__ << ":" << __LINE__ << ": failed with " << VkResultString(err) << "\n";

// global configuration
bool human_readable_output = true;
bool html_output = false;
bool json_output = false;

#ifdef _WIN32

#define strdup _strdup

// Returns nonzero if the console is used only for this process. Will return
// zero if another process (such as cmd.exe) is also attached.
static int ConsoleIsExclusive(void) {
    DWORD pids[2];
    DWORD num_pids = GetConsoleProcessList(pids, ARRAYSIZE(pids));
    return num_pids <= 1;
}

#define WAIT_FOR_CONSOLE_DESTROY                                            \
    do {                                                                    \
        if (ConsoleIsExclusive() && human_readable_output) Sleep(INFINITE); \
    } while (0)
#else
#define WAIT_FOR_CONSOLE_DESTROY
#endif

#define ERR_EXIT(err)             \
    do {                          \
        ERR(err);                 \
        fflush(stdout);           \
        fflush(stderr);           \
        WAIT_FOR_CONSOLE_DESTROY; \
        exit(-1);                 \
    } while (0)

#ifdef _WIN32

#define _CALL_PFN(pfn, ...) (pfn)
#define CALL_PFN(fncName) _CALL_PFN(User32Handles::pfn##fncName)

#define _CHECK_PFN(pfn, fncName)                                              \
    do {                                                                      \
        if (pfn == nullptr) {                                                 \
            fprintf(stderr, "Failed to get %s function address!\n", fncName); \
            WAIT_FOR_CONSOLE_DESTROY;                                         \
            exit(1);                                                          \
        }                                                                     \
    } while (false)

#define _SET_PFN(dllHandle, pfnType, pfn, fncName)                           \
    do {                                                                     \
        pfn = reinterpret_cast<pfnType>(GetProcAddress(dllHandle, fncName)); \
        _CHECK_PFN(pfn, fncName);                                            \
    } while (false)

#define SET_PFN(dllHandle, fncName) _SET_PFN(User32Handles::dllHandle, PFN_##fncName, User32Handles::pfn##fncName, #fncName)

// User32 function declarations
typedef WINUSERAPI BOOL(WINAPI *PFN_AdjustWindowRect)(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL);
typedef WINUSERAPI HWND(WINAPI *PFN_CreateWindowExA)(_In_ DWORD, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ DWORD, _In_ int, _In_ int,
                                                     _In_ int, _In_ int, _In_opt_ HWND, _In_opt_ HMENU, _In_opt_ HINSTANCE,
                                                     _In_opt_ LPVOID);
typedef WINUSERAPI LRESULT(WINAPI *PFN_DefWindowProcA)(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM);
typedef WINUSERAPI BOOL(WINAPI *PFN_DestroyWindow)(_In_ HWND);
typedef WINUSERAPI HICON(WINAPI *PFN_LoadIconA)(_In_opt_ HINSTANCE, _In_ LPCSTR);
typedef WINUSERAPI ATOM(WINAPI *PFN_RegisterClassExA)(_In_ CONST WNDCLASSEXA *);

struct User32Handles {
    // User32 function pointers
    static PFN_AdjustWindowRect pfnAdjustWindowRect;
    static PFN_CreateWindowExA pfnCreateWindowExA;
    static PFN_DefWindowProcA pfnDefWindowProcA;
    static PFN_DestroyWindow pfnDestroyWindow;
    static PFN_LoadIconA pfnLoadIconA;
    static PFN_RegisterClassExA pfnRegisterClassExA;

    // User32 dll handle
    static HMODULE user32DllHandle;
};

bool LoadUser32Dll() {
    User32Handles::user32DllHandle = LoadLibraryExA("user32.dll", nullptr, 0);
    if (User32Handles::user32DllHandle != NULL) {
        SET_PFN(user32DllHandle, AdjustWindowRect);
        SET_PFN(user32DllHandle, CreateWindowExA);
        SET_PFN(user32DllHandle, DefWindowProcA);
        SET_PFN(user32DllHandle, DestroyWindow);
        SET_PFN(user32DllHandle, LoadIconA);
        SET_PFN(user32DllHandle, RegisterClassExA);
        return true;
    }
    return false;
}

void FreeUser32Dll() {
    if (User32Handles::user32DllHandle != nullptr) {
        FreeLibrary(User32Handles::user32DllHandle);
        User32Handles::user32DllHandle = nullptr;
    }
}
#endif  // _WIN32

static const char *VkResultString(VkResult err);

const char *app_short_name = "vulkaninfo";

std::vector<const char *> get_c_str_array(std::vector<std::string> const &vec) {
    std::vector<const char *> ret;
    for (auto &str : vec) ret.push_back(str.c_str());
    return ret;
}

static const char *VkDebugReportFlagsEXTString(const VkDebugReportFlagsEXT flags) {
    switch (flags) {
        case VK_DEBUG_REPORT_ERROR_BIT_EXT:
            return "ERROR";
        case VK_DEBUG_REPORT_WARNING_BIT_EXT:
            return "WARNING";
        case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT:
            return "PERF";
        case VK_DEBUG_REPORT_INFORMATION_BIT_EXT:
            return "INFO";
        case VK_DEBUG_REPORT_DEBUG_BIT_EXT:
            return "DEBUG";
        default:
            return "UNKNOWN";
    }
}
static VKAPI_ATTR VkBool32 VKAPI_CALL DbgCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType,
                                                  uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix,
                                                  const char *pMsg, void *pUserData) {
    std::cerr << VkDebugReportFlagsEXTString(msgFlags) << ": [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg << "\n";

    // True is reserved for layer developers, and MAY mean calls are not distributed down the layer chain after validation error.
    // False SHOULD always be returned by apps:
    return VK_FALSE;
}

// ----------- Instance Setup ------- //

struct VkStructureHeader {
    VkStructureType sType;
    VkStructureHeader *pNext;
};

struct pNextChainBuildingBlockInfo {
    VkStructureType sType;
    uint32_t mem_size;
};

void buildpNextChain(VkStructureHeader *first, const std::vector<pNextChainBuildingBlockInfo> &chain_info) {
    VkStructureHeader *place = first;

    for (uint32_t i = 0; i < chain_info.size(); i++) {
        place->pNext = static_cast<VkStructureHeader *>(malloc(chain_info[i].mem_size));
        if (!place->pNext) {
            ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
        }
        std::memset(place->pNext, 0, chain_info[i].mem_size);
        place = place->pNext;
        place->sType = chain_info[i].sType;
    }

    place->pNext = nullptr;
}

void freepNextChain(VkStructureHeader *first) {
    VkStructureHeader *place = first;
    VkStructureHeader *next = nullptr;

    while (place) {
        next = place->pNext;
        free(place);
        place = next;
    }
}

struct LayerExtensionList {
    VkLayerProperties layer_properties{};
    std::vector<VkExtensionProperties> extension_properties;
};

struct AppInstance;

struct SurfaceExtension {
    std::string name;
    void (*create_window)(AppInstance &) = nullptr;
    VkSurfaceKHR (*create_surface)(AppInstance &) = nullptr;
    void (*destroy_window)(AppInstance &) = nullptr;
    VkSurfaceKHR surface = VK_NULL_HANDLE;
    VkBool32 supports_present = 0;

    bool operator==(const SurfaceExtension &other) {
        return name == other.name && surface == other.surface && supports_present == other.supports_present;
    }
};

struct VulkanVersion {
    uint32_t major;
    uint32_t minor;
    uint32_t patch;
};

struct AppInstance {
    VkInstance instance;
    uint32_t instance_version;
    VulkanVersion vk_version;

    std::vector<LayerExtensionList> global_layers;

    std::vector<VkExtensionProperties> global_extensions;  // Instance Extensions

    std::vector<std::string> inst_extensions;

    // Functions from vkGetInstanceProcAddress
    PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
    PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
    PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
    PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR;
    PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
    PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
    PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR;
    PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR;
    PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
    PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR;
    PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR;
    PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT;

    std::vector<SurfaceExtension> surface_extensions;

    int width = 256, height = 256;

    VkSurfaceCapabilitiesKHR surface_capabilities;

#ifdef VK_USE_PLATFORM_WIN32_KHR
    HINSTANCE h_instance;  // Windows Instance
    HWND h_wnd;            // window handle
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
    xcb_connection_t *xcb_connection;
    xcb_screen_t *xcb_screen;
    xcb_window_t xcb_window;
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
    Display *xlib_display;
    Window xlib_window;
#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
    void *macos_window;
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
    void *metal_window;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
    wl_display *wayland_display;
    wl_surface *wayland_surface;
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR  // TODO
    ANativeWindow *window;
#endif
    AppInstance() {
        PFN_vkEnumerateInstanceVersion enumerate_instance_version =
            reinterpret_cast<PFN_vkEnumerateInstanceVersion>(vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"));

        if (!enumerate_instance_version) {
            instance_version = VK_API_VERSION_1_0;
        } else {
            const VkResult err = enumerate_instance_version(&instance_version);
            if (err) ERR_EXIT(err);
        }

        vk_version = {VK_VERSION_MAJOR(instance_version), VK_VERSION_MINOR(instance_version), VK_VERSION_PATCH(VK_HEADER_VERSION)};

        AppGetInstanceExtensions();

        const VkDebugReportCallbackCreateInfoEXT dbg_info = {VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, nullptr,
                                                             VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT,
                                                             DbgCallback};

        const VkApplicationInfo app_info = {
            VK_STRUCTURE_TYPE_APPLICATION_INFO, nullptr, app_short_name, 1, nullptr, 0, VK_API_VERSION_1_0};

        AppCompileInstanceExtensionsToEnable();

        std::vector<const char *> inst_exts;
        for (auto &ext : inst_extensions) inst_exts.push_back(ext.c_str());

        const VkInstanceCreateInfo inst_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,  &dbg_info,       0, &app_info, 0, nullptr,
                                                static_cast<uint32_t>(inst_exts.size()), inst_exts.data()};

        VkResult err = vkCreateInstance(&inst_info, nullptr, &instance);
        if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
            std::cerr << "Cannot create Vulkan instance.\n";
            std::cerr << "This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU "
                         "that does not support Vulkan.\n";
            ERR_EXIT(err);
        } else if (err) {
            ERR_EXIT(err);
        }

        AppLoadInstanceCommands();
    }

    ~AppInstance() { vkDestroyInstance(instance, nullptr); }

    AppInstance(const AppInstance &) = delete;
    const AppInstance &operator=(const AppInstance &) = delete;

    bool CheckExtensionEnabled(std::string extension_to_check) {
        for (auto &extension : inst_extensions) {
            if (extension_to_check == extension) {
                return true;
            }
        }
        return false;
    }

    /* Gets a list of layer and instance extensions */
    void AppGetInstanceExtensions() {
        /* Scan layers */
        std::vector<VkLayerProperties> global_layer_properties;

        VkResult err;
        uint32_t count = 0;
        do {
            err = vkEnumerateInstanceLayerProperties(&count, nullptr);
            if (err) ERR_EXIT(err);

            global_layer_properties.resize(count);

            err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties.data());
        } while (err == VK_INCOMPLETE);
        if (err) ERR_EXIT(err);

        global_layers.resize(count);
        assert(global_layer_properties.size() == global_layers.size());

        for (size_t i = 0; i < global_layer_properties.size(); i++) {
            global_layers[i].layer_properties = global_layer_properties[i];

            global_layers[i].extension_properties = AppGetGlobalLayerExtensions(global_layer_properties[i].layerName);
        }

        // Collect global extensions
        // Gets instance extensions, if no layer was specified in the first paramteter
        global_extensions = AppGetGlobalLayerExtensions(nullptr);
    }
    void AppCompileInstanceExtensionsToEnable() {
        // Get all supported Instance extensions (excl. layer-provided ones)
        for (auto &ext : global_extensions) {
            inst_extensions.push_back(ext.extensionName);
        }
    }
    void AppLoadInstanceCommands() {
#define LOAD_INSTANCE_VK_CMD(cmd) cmd = reinterpret_cast<PFN_##cmd>(vkGetInstanceProcAddr(instance, #cmd))

        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceSupportKHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormatsKHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormats2KHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfacePresentModesKHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceProperties2KHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFormatProperties2KHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceQueueFamilyProperties2KHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFeatures2KHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceMemoryProperties2KHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2KHR);
        LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2EXT);

#undef LOAD_INSTANCE_VK_CMD
    }

    void AddSurfaceExtension(SurfaceExtension ext) { surface_extensions.push_back(ext); }

    static std::vector<VkExtensionProperties> AppGetGlobalLayerExtensions(char *layer_name) {
        std::vector<VkExtensionProperties> ext_props;
        VkResult err;
        uint32_t ext_count = 0;
        do {
            // gets the extension count if the last parameter is nullptr
            err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, nullptr);
            if (err) ERR_EXIT(err);

            ext_props.resize(ext_count);
            // gets the extension properties if the last parameter is not nullptr
            err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_props.data());
        } while (err == VK_INCOMPLETE);
        if (err) ERR_EXIT(err);
        return ext_props;
    }

    std::vector<VkPhysicalDevice> FindPhysicalDevices() {
        std::vector<VkPhysicalDevice> phys_devices;

        VkResult err;
        uint32_t gpu_count = 0;

        /* repeat get until VK_INCOMPLETE goes away */
        do {
            err = vkEnumeratePhysicalDevices(instance, &gpu_count, nullptr);
            if (err) ERR_EXIT(err);

            phys_devices.resize(gpu_count);
            err = vkEnumeratePhysicalDevices(instance, &gpu_count, phys_devices.data());
            if (err) ERR_EXIT(err);
            phys_devices.resize(gpu_count);
        } while (err == VK_INCOMPLETE);

        return phys_devices;
    }
};

// --------- Platform Specific Presentation Calls --------- //

//---------------------------Win32---------------------------
#ifdef VK_USE_PLATFORM_WIN32_KHR

// MS-Windows event handling function:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    return (CALL_PFN(DefWindowProcA)(hWnd, uMsg, wParam, lParam));
}

static void AppCreateWin32Window(AppInstance &inst) {
    inst.h_instance = GetModuleHandle(nullptr);

    WNDCLASSEX win_class;

    // Initialize the window class structure:
    win_class.cbSize = sizeof(WNDCLASSEX);
    win_class.style = CS_HREDRAW | CS_VREDRAW;
    win_class.lpfnWndProc = WndProc;
    win_class.cbClsExtra = 0;
    win_class.cbWndExtra = 0;
    win_class.hInstance = inst.h_instance;
    win_class.hIcon = CALL_PFN(LoadIconA)(nullptr, IDI_APPLICATION);
    win_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
    win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    win_class.lpszMenuName = nullptr;
    win_class.lpszClassName = app_short_name;
    win_class.hInstance = inst.h_instance;
    win_class.hIconSm = CALL_PFN(LoadIconA)(nullptr, IDI_WINLOGO);
    // Register window class:
    if (!CALL_PFN(RegisterClassExA)(&win_class)) {
        // It didn't work, so try to give a useful error:
        fprintf(stderr, "Failed to register the window class!\n");
        exit(1);
    }
    // Create window with the registered class:
    RECT wr = {0, 0, inst.width, inst.height};
    CALL_PFN(AdjustWindowRect)(&wr, WS_OVERLAPPEDWINDOW, FALSE);
    inst.h_wnd = CALL_PFN(CreateWindowExA)(0,
                                           app_short_name,  // class name
                                           app_short_name,  // app name
                                           // WS_VISIBLE | WS_SYSMENU |
                                           WS_OVERLAPPEDWINDOW,  // window style
                                           100, 100,             // x/y coords
                                           wr.right - wr.left,   // width
                                           wr.bottom - wr.top,   // height
                                           nullptr,              // handle to parent
                                           nullptr,              // handle to menu
                                           inst.h_instance,      // hInstance
                                           nullptr);             // no extra parameters
    if (!inst.h_wnd) {
        // It didn't work, so try to give a useful error:
        fprintf(stderr, "Failed to create a window!\n");
        exit(1);
    }
}

static VkSurfaceKHR AppCreateWin32Surface(AppInstance &inst) {
    VkWin32SurfaceCreateInfoKHR createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.hinstance = inst.h_instance;
    createInfo.hwnd = inst.h_wnd;

    VkSurfaceKHR surface;
    VkResult err = vkCreateWin32SurfaceKHR(inst.instance, &createInfo, nullptr, &surface);
    if (err) ERR_EXIT(err);
    return surface;
}

static void AppDestroyWin32Window(AppInstance &inst) { CALL_PFN(DestroyWindow)(inst.h_wnd); }
#endif  // VK_USE_PLATFORM_WIN32_KHR
//-----------------------------------------------------------

#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) ||      \
    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
    defined(VK_USE_PLATFORM_ANDROID_KHR)
static void AppDestroySurface(AppInstance &inst, VkSurfaceKHR surface) {  // same for all platforms
    vkDestroySurfaceKHR(inst.instance, surface, nullptr);
}
#endif

//----------------------------XCB----------------------------

#ifdef VK_USE_PLATFORM_XCB_KHR
static void AppCreateXcbWindow(AppInstance &inst) {
    //--Init Connection--
    const xcb_setup_t *setup;
    xcb_screen_iterator_t iter;
    int scr;

    // API guarantees non-null xcb_connection
    inst.xcb_connection = xcb_connect(nullptr, &scr);
    int conn_error = xcb_connection_has_error(inst.xcb_connection);
    if (conn_error) {
        fprintf(stderr, "XCB failed to connect to the X server due to error:%d.\n", conn_error);
        fflush(stderr);
        xcb_disconnect(inst.xcb_connection);
        inst.xcb_connection = nullptr;
        return;
    }

    setup = xcb_get_setup(inst.xcb_connection);
    iter = xcb_setup_roots_iterator(setup);
    while (scr-- > 0) {
        xcb_screen_next(&iter);
    }

    inst.xcb_screen = iter.data;
    //-------------------

    inst.xcb_window = xcb_generate_id(inst.xcb_connection);
    xcb_create_window(inst.xcb_connection, XCB_COPY_FROM_PARENT, inst.xcb_window, inst.xcb_screen->root, 0, 0, inst.width,
                      inst.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, inst.xcb_screen->root_visual, 0, nullptr);

    xcb_intern_atom_cookie_t cookie = xcb_intern_atom(inst.xcb_connection, 1, 12, "WM_PROTOCOLS");
    xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(inst.xcb_connection, cookie, 0);
    free(reply);
}

static VkSurfaceKHR AppCreateXcbSurface(AppInstance &inst) {
    if (!inst.xcb_connection) {
        ERR_EXIT(VK_ERROR_INITIALIZATION_FAILED);
    }

    VkXcbSurfaceCreateInfoKHR xcb_createInfo;
    xcb_createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
    xcb_createInfo.pNext = nullptr;
    xcb_createInfo.flags = 0;
    xcb_createInfo.connection = inst.xcb_connection;
    xcb_createInfo.window = inst.xcb_window;

    VkSurfaceKHR surface;
    VkResult err = vkCreateXcbSurfaceKHR(inst.instance, &xcb_createInfo, nullptr, &surface);
    if (err) ERR_EXIT(err);
    return surface;
}

static void AppDestroyXcbWindow(AppInstance &inst) {
    if (!inst.xcb_connection) {
        return;  // Nothing to destroy
    }

    xcb_destroy_window(inst.xcb_connection, inst.xcb_window);
    xcb_disconnect(inst.xcb_connection);
}
#endif  // VK_USE_PLATFORM_XCB_KHR
//-----------------------------------------------------------

//----------------------------XLib---------------------------
#ifdef VK_USE_PLATFORM_XLIB_KHR
static void AppCreateXlibWindow(AppInstance &inst) {
    long visualMask = VisualScreenMask;
    int numberOfVisuals;

    inst.xlib_display = XOpenDisplay(nullptr);
    if (inst.xlib_display == nullptr) {
        fprintf(stderr, "XLib failed to connect to the X server.\nExiting ...\n");
        exit(1);
    }

    XVisualInfo vInfoTemplate = {};
    vInfoTemplate.screen = DefaultScreen(inst.xlib_display);
    XVisualInfo *visualInfo = XGetVisualInfo(inst.xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals);
    inst.xlib_window = XCreateWindow(inst.xlib_display, RootWindow(inst.xlib_display, vInfoTemplate.screen), 0, 0, inst.width,
                                     inst.height, 0, visualInfo->depth, InputOutput, visualInfo->visual, 0, nullptr);

    XSync(inst.xlib_display, false);
    XFree(visualInfo);
}

static VkSurfaceKHR AppCreateXlibSurface(AppInstance &inst) {
    VkXlibSurfaceCreateInfoKHR createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.dpy = inst.xlib_display;
    createInfo.window = inst.xlib_window;

    VkSurfaceKHR surface;
    VkResult err = vkCreateXlibSurfaceKHR(inst.instance, &createInfo, nullptr, &surface);
    if (err) ERR_EXIT(err);
    return surface;
}

static void AppDestroyXlibWindow(AppInstance &inst) {
    XDestroyWindow(inst.xlib_display, inst.xlib_window);
    XCloseDisplay(inst.xlib_display);
}
#endif  // VK_USE_PLATFORM_XLIB_KHR
//-----------------------------------------------------------

//------------------------MACOS_MVK--------------------------
#ifdef VK_USE_PLATFORM_MACOS_MVK
static void AppCreateMacOSWindow(AppInstance &inst) {
    inst.macos_window = CreateMetalView(inst.width, inst.height);
    if (inst.macos_window == nullptr) {
        fprintf(stderr, "Could not create a native Metal view.\nExiting...\n");
        exit(1);
    }
}

static VkSurfaceKHR AppCreateMacOSSurface(AppInstance &inst) {
    VkMacOSSurfaceCreateInfoMVK createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.pView = inst.macos_window;

    VkSurfaceKHR surface;
    VkResult err = vkCreateMacOSSurfaceMVK(inst.instance, &createInfo, nullptr, &surface);
    if (err) ERR_EXIT(err);
    return surface;
}

static void AppDestroyMacOSWindow(AppInstance &inst) { DestroyMetalView(inst.macos_window); }
#endif  // VK_USE_PLATFORM_MACOS_MVK
//-----------------------------------------------------------

//------------------------METAL_EXT--------------------------
#ifdef VK_USE_PLATFORM_METAL_EXT
static void AppCreateMetalWindow(AppInstance &inst) {
    inst.metal_window = CreateMetalView(inst.width, inst.height);
    if (inst.metal_window == nullptr) {
        fprintf(stderr, "Could not create a native Metal view.\nExiting...\n");
        exit(1);
    }
}

static VkSurfaceKHR AppCreateMetalSurface(AppInstance &inst) {
    VkMetalSurfaceCreateInfoEXT createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.pLayer = static_cast<CAMetalLayer *>(GetCAMetalLayerFromMetalView(inst.metal_window));

    VkSurfaceKHR surface;
    VkResult err = vkCreateMetalSurfaceEXT(inst.instance, &createInfo, nullptr, &surface);
    if (err) ERR_EXIT(err);
    return surface;
}

static void AppDestroyMetalWindow(AppInstance &inst) { DestroyMetalView(inst.metal_window); }
#endif  // VK_USE_PLATFORM_METAL_EXT
//-----------------------------------------------------------

//-------------------------WAYLAND---------------------------
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
static void wayland_registry_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface,
                                    uint32_t version) {
    AppInstance &inst = *static_cast<AppInstance *>(data);
    if (strcmp(interface, "wl_compositor") == 0) {
        struct wl_compositor *compositor = (struct wl_compositor *)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
        inst.wayland_surface = wl_compositor_create_surface(compositor);
    }
}
static void wayland_registry_global_remove(void *data, struct wl_registry *registry, uint32_t id) {}
static const struct wl_registry_listener wayland_registry_listener = {wayland_registry_global, wayland_registry_global_remove};

static void AppCreateWaylandWindow(AppInstance &inst) {
    inst.wayland_display = wl_display_connect(nullptr);
    struct wl_registry *registry = wl_display_get_registry(inst.wayland_display);
    wl_registry_add_listener(wl_display_get_registry(inst.wayland_display), &wayland_registry_listener, static_cast<void *>(&inst));
    wl_display_roundtrip(inst.wayland_display);
    wl_registry_destroy(registry);
}

static VkSurfaceKHR AppCreateWaylandSurface(AppInstance &inst) {
    VkWaylandSurfaceCreateInfoKHR createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.display = inst.wayland_display;
    createInfo.surface = inst.wayland_surface;

    VkSurfaceKHR surface;
    VkResult err = vkCreateWaylandSurfaceKHR(inst.instance, &createInfo, nullptr, &surface);
    if (err) ERR_EXIT(err);
    return surface;
}

static void AppDestroyWaylandWindow(AppInstance &inst) { wl_display_disconnect(inst.wayland_display); }
#endif  // VK_USE_PLATFORM_WAYLAND_KHR
//-----------------------------------------------------------

//-------------------------ANDROID---------------------------
#ifdef VK_USE_PLATFORM_ANDROID_KHR
static void AppCreateAndroidWindow(AppInstance &inst) {}
static VkSurfaceKHR AppCreateAndroidSurface(AppInstance &inst) {
    VkAndroidSurfaceCreateInfoKHR createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
    createInfo.pNext = NULL;
    createInfo.flags = 0;
    createInfo.window = (struct ANativeWindow *)(inst.window);

    err = vkCreateAndroidSurfaceKHR(inst.inst, &createInfo, NULL, &inst.surface);
    EXIT_ERR(err);
}
static VkSurfaceKHR AppDestroyAndroidSurface(AppInstance &inst) {}
#endif
//-----------------------------------------------------------

// ------------ Setup Windows ------------- //

void SetupWindowExtensions(AppInstance &inst) {
#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR)
    bool has_display = true;
    const char *display_var = getenv("DISPLAY");
    if (display_var == nullptr || strlen(display_var) == 0) {
        fprintf(stderr, "'DISPLAY' environment variable not set... skipping surface info\n");
        fflush(stderr);
        has_display = false;
    }
#endif

#ifdef VK_USE_PLATFORM_WAYLAND_KHR
    wl_display *wayland_display = wl_display_connect(nullptr);
    bool has_wayland_display = false;
    if (wayland_display != nullptr) {
        wl_display_disconnect(wayland_display);
        has_wayland_display = true;
    }
#endif

//--WIN32--
#ifdef VK_USE_PLATFORM_WIN32_KHR
    SurfaceExtension surface_ext_win32;
    if (inst.CheckExtensionEnabled(VK_KHR_WIN32_SURFACE_EXTENSION_NAME)) {
        surface_ext_win32.name = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
        surface_ext_win32.create_window = AppCreateWin32Window;
        surface_ext_win32.create_surface = AppCreateWin32Surface;
        surface_ext_win32.destroy_window = AppDestroyWin32Window;

        inst.AddSurfaceExtension(surface_ext_win32);
    }
#endif
//--XCB--
#ifdef VK_USE_PLATFORM_XCB_KHR
    SurfaceExtension surface_ext_xcb;
    if (inst.CheckExtensionEnabled(VK_KHR_XCB_SURFACE_EXTENSION_NAME)) {
        surface_ext_xcb.name = VK_KHR_XCB_SURFACE_EXTENSION_NAME;
        surface_ext_xcb.create_window = AppCreateXcbWindow;
        surface_ext_xcb.create_surface = AppCreateXcbSurface;
        surface_ext_xcb.destroy_window = AppDestroyXcbWindow;
        if (has_display) {
            inst.AddSurfaceExtension(surface_ext_xcb);
        }
    }
#endif
//--XLIB--
#ifdef VK_USE_PLATFORM_XLIB_KHR
    SurfaceExtension surface_ext_xlib;
    if (inst.CheckExtensionEnabled(VK_KHR_XLIB_SURFACE_EXTENSION_NAME)) {
        surface_ext_xlib.name = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
        surface_ext_xlib.create_window = AppCreateXlibWindow;
        surface_ext_xlib.create_surface = AppCreateXlibSurface;
        surface_ext_xlib.destroy_window = AppDestroyXlibWindow;
        if (has_display) {
            inst.AddSurfaceExtension(surface_ext_xlib);
        }
    }
#endif
//--MACOS--
#ifdef VK_USE_PLATFORM_MACOS_MVK
    SurfaceExtension surface_ext_macos;
    if (inst.CheckExtensionEnabled(VK_MVK_MACOS_SURFACE_EXTENSION_NAME)) {
        surface_ext_macos.name = VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
        surface_ext_macos.create_window = AppCreateMacOSWindow;
        surface_ext_macos.create_surface = AppCreateMacOSSurface;
        surface_ext_macos.destroy_window = AppDestroyMacOSWindow;

        inst.AddSurfaceExtension(surface_ext_macos);
    }
#endif

#ifdef VK_USE_PLATFORM_METAL_EXT
    SurfaceExtension surface_ext_metal;
    if (inst.CheckExtensionEnabled(VK_EXT_METAL_SURFACE_EXTENSION_NAME)) {
        surface_ext_metal.name = VK_EXT_METAL_SURFACE_EXTENSION_NAME;
        surface_ext_metal.create_window = AppCreateMetalWindow;
        surface_ext_metal.create_surface = AppCreateMetalSurface;
        surface_ext_metal.destroy_window = AppDestroyMetalWindow;

        inst.AddSurfaceExtension(surface_ext_metal);
    }
#endif
//--WAYLAND--
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
    SurfaceExtension surface_ext_wayland;
    if (inst.CheckExtensionEnabled(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) {
        surface_ext_wayland.name = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
        surface_ext_wayland.create_window = AppCreateWaylandWindow;
        surface_ext_wayland.create_surface = AppCreateWaylandSurface;
        surface_ext_wayland.destroy_window = AppDestroyWaylandWindow;
        if (has_wayland_display) {
            inst.AddSurfaceExtension(surface_ext_wayland);
        }
    }
#endif
//--ANDROID--
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    SurfaceExtension surface_ext_android;
    if (inst.CheckExtensionEnabled(VK_ANDROID_SURFACE_EXTENSION_NAME)) {
        surface_ext_android.name = VK_ANDROID_SURFACE_EXTENSION_NAME;
        surface_ext_android.create_window = AppCreateAndroidWindow;
        surface_ext_android.create_surface = AppCreateAndroidSurface;
        surface_ext_android.destroy_window = AppDestroyAndroidWindow;

        inst.AddSurfaceExtension(surface_ext_android);
    }
#endif
}

// ---------- Surfaces -------------- //

class AppSurface {
   public:
    AppInstance &inst;
    SurfaceExtension surface_extension;

    std::vector<VkPresentModeKHR> surf_present_modes;

    std::vector<VkSurfaceFormatKHR> surf_formats;
    std::vector<VkSurfaceFormat2KHR> surf_formats2;

    VkSurfaceCapabilitiesKHR surface_capabilities;
    VkSurfaceCapabilities2KHR surface_capabilities2_khr;
    VkSurfaceCapabilities2EXT surface_capabilities2_ext;

    AppSurface(AppInstance &inst, VkPhysicalDevice phys_device, SurfaceExtension surface_extension,
               std::vector<pNextChainBuildingBlockInfo> &sur_extension_pNextChain)
        : inst(inst), surface_extension(surface_extension) {
        uint32_t present_mode_count = 0;
        VkResult error =
            inst.vkGetPhysicalDeviceSurfacePresentModesKHR(phys_device, surface_extension.surface, &present_mode_count, nullptr);
        if (error) ERR_EXIT(error);

        surf_present_modes.resize(present_mode_count);
        error = inst.vkGetPhysicalDeviceSurfacePresentModesKHR(phys_device, surface_extension.surface, &present_mode_count,
                                                               surf_present_modes.data());
        if (error) ERR_EXIT(error);

        const VkPhysicalDeviceSurfaceInfo2KHR surface_info2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr,
                                                               surface_extension.surface};

        uint32_t format_count = 0;
        if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) {
            VkResult err = inst.vkGetPhysicalDeviceSurfaceFormats2KHR(phys_device, &surface_info2, &format_count, nullptr);
            if (err) ERR_EXIT(err);
            surf_formats2.resize(format_count);
            for (uint32_t i = 0; i < format_count; ++i) {
                surf_formats2[i].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
                surf_formats2[i].pNext = nullptr;
            }
            err = inst.vkGetPhysicalDeviceSurfaceFormats2KHR(phys_device, &surface_info2, &format_count, surf_formats2.data());
            if (err) ERR_EXIT(err);
        } else {
            VkResult err =
                inst.vkGetPhysicalDeviceSurfaceFormatsKHR(phys_device, surface_extension.surface, &format_count, nullptr);
            if (err) ERR_EXIT(err);
            surf_formats.resize(format_count);
            err = inst.vkGetPhysicalDeviceSurfaceFormatsKHR(phys_device, surface_extension.surface, &format_count,
                                                            surf_formats.data());
            if (err) ERR_EXIT(err);
        }

        if (inst.CheckExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME)) {
            VkResult err =
                inst.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_device, surface_extension.surface, &surface_capabilities);
            if (err) ERR_EXIT(err);
        }

        if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) {
            surface_capabilities2_khr.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
            buildpNextChain((VkStructureHeader *)&surface_capabilities2_khr, sur_extension_pNextChain);

            VkPhysicalDeviceSurfaceInfo2KHR surface_info;
            surface_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
            surface_info.pNext = nullptr;
            surface_info.surface = surface_extension.surface;

            VkResult err = inst.vkGetPhysicalDeviceSurfaceCapabilities2KHR(phys_device, &surface_info, &surface_capabilities2_khr);
            if (err) ERR_EXIT(err);
        }

        if (inst.CheckExtensionEnabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
            surface_capabilities2_ext.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT;
            surface_capabilities2_ext.pNext = nullptr;
            VkResult err =
                inst.vkGetPhysicalDeviceSurfaceCapabilities2EXT(phys_device, surface_extension.surface, &surface_capabilities2_ext);
            if (err) ERR_EXIT(err);
        }
    }

    ~AppSurface() {
        if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) {
            freepNextChain(static_cast<VkStructureHeader *>(surface_capabilities2_khr.pNext));
        }
    }

    AppSurface(const AppSurface &) = delete;
    const AppSurface &operator=(const AppSurface &) = delete;
};

// -------------------- Device Groups ------------------------//

std::vector<VkPhysicalDeviceGroupProperties> GetGroups(AppInstance &inst) {
    if (inst.CheckExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
        PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR =
            reinterpret_cast<PFN_vkEnumeratePhysicalDeviceGroupsKHR>(
                vkGetInstanceProcAddr(inst.instance, "vkEnumeratePhysicalDeviceGroupsKHR"));

        std::vector<VkPhysicalDeviceGroupProperties> groups;
        uint32_t group_count;
        VkResult err;
        do {
            err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, NULL);
            if (err != VK_SUCCESS && err != VK_INCOMPLETE) ERR_EXIT(err);
            groups.resize(group_count);

            err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, groups.data());
            if (err != VK_SUCCESS && err != VK_INCOMPLETE) ERR_EXIT(err);
        } while (err == VK_INCOMPLETE);
        return groups;
    }
    return {};
}

std::vector<VkPhysicalDeviceProperties> GetGroupProps(VkPhysicalDeviceGroupProperties group) {
    std::vector<VkPhysicalDeviceProperties> props(group.physicalDeviceCount);

    for (uint32_t i = 0; i < group.physicalDeviceCount; ++i) {
        vkGetPhysicalDeviceProperties(group.physicalDevices[i], &props[i]);
    }

    return props;
}

// The bool of the pair returns true if the extension VK_KHR_device_group is present
std::pair<bool, VkDeviceGroupPresentCapabilitiesKHR> GetGroupCapabilities(AppInstance &inst,
                                                                          VkPhysicalDeviceGroupProperties group) {
    // Build create info for logical device made from all physical devices in this group.
    std::vector<std::string> extensions_list = {VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_EXTENSION_NAME};
    VkDeviceGroupDeviceCreateInfoKHR dg_ci = {VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR, nullptr,
                                              group.physicalDeviceCount, group.physicalDevices};

    float queue_priority = 1.0f;

    auto ext_list = get_c_str_array(extensions_list);

    VkDeviceQueueCreateInfo q_ci = {VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, nullptr, 0, 0, 1, &queue_priority};
    VkDeviceCreateInfo device_ci = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   &dg_ci,         0, 1, &q_ci, 0, nullptr,
                                    static_cast<uint32_t>(ext_list.size()), ext_list.data()};

    VkDevice logical_device = VK_NULL_HANDLE;

    VkResult err = vkCreateDevice(group.physicalDevices[0], &device_ci, nullptr, &logical_device);
    if (err != VK_SUCCESS && err != VK_ERROR_EXTENSION_NOT_PRESENT) ERR_EXIT(err);

    if (err == VK_ERROR_EXTENSION_NOT_PRESENT) {
        VkDeviceGroupPresentCapabilitiesKHR group_capabilities = {VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR, nullptr};
        vkDestroyDevice(logical_device, nullptr);
        return std::pair<bool, VkDeviceGroupPresentCapabilitiesKHR>(false, group_capabilities);
    }

    VkDeviceGroupPresentCapabilitiesKHR group_capabilities = {VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR, nullptr};

    // If the KHR_device_group extension is present, write the capabilities of the logical device into a struct for later
    // output to user.
    PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR =
        reinterpret_cast<PFN_vkGetDeviceGroupPresentCapabilitiesKHR>(
            vkGetInstanceProcAddr(inst.instance, "vkGetDeviceGroupPresentCapabilitiesKHR"));
    err = vkGetDeviceGroupPresentCapabilitiesKHR(logical_device, &group_capabilities);
    if (err) ERR_EXIT(err);

    vkDestroyDevice(logical_device, nullptr);

    return std::pair<bool, VkDeviceGroupPresentCapabilitiesKHR>(true, group_capabilities);
}

// -------------------- Device Setup ------------------- //

struct MemImageSupport {
    bool regular_supported, sparse_supported, transient_supported;
    VkFormat format;
    uint32_t regular_memtypes, sparse_memtypes, transient_memtypes;
};

struct MemResSupport {
    std::array<std::array<MemImageSupport, 8>, 2> image;
    // TODO: buffers
};

struct pNextChainInfos {
    std::vector<pNextChainBuildingBlockInfo> phys_device_props2;
    std::vector<pNextChainBuildingBlockInfo> phys_device_mem_props2;
    std::vector<pNextChainBuildingBlockInfo> phys_device_features2;
    std::vector<pNextChainBuildingBlockInfo> surface_capabilities2;
    std::vector<pNextChainBuildingBlockInfo> format_properties2;
};

struct FormatRange {
    // the Vulkan standard version that supports this format range, or 0 if non-standard
    uint32_t minimum_instance_version;

    // The name of the extension that supports this format range, or NULL if the range
    // is only part of the standard
    const char *extension_name;

    // The first and last supported formats within this range.
    VkFormat first_format;
    VkFormat last_format;
};

struct AppGpu {
    AppInstance &inst;
    uint32_t id;
    VkPhysicalDevice phys_device;

    VkPhysicalDeviceProperties props;
    VkPhysicalDeviceProperties2KHR props2;

    uint32_t queue_count;
    std::vector<VkQueueFamilyProperties> queue_props;
    std::vector<VkQueueFamilyProperties2KHR> queue_props2;

    VkPhysicalDeviceMemoryProperties memory_props;
    VkPhysicalDeviceMemoryProperties2KHR memory_props2;

    MemResSupport mem_type_res_support;

    VkPhysicalDeviceFeatures features;
    VkPhysicalDeviceFeatures2KHR features2;
    VkPhysicalDevice limits;

    std::vector<VkExtensionProperties> device_extensions;

    VkDevice dev;
    VkPhysicalDeviceFeatures enabled_features;

    std::array<VkDeviceSize, VK_MAX_MEMORY_HEAPS> heapBudget;
    std::array<VkDeviceSize, VK_MAX_MEMORY_HEAPS> heapUsage;

    std::vector<FormatRange> supported_format_ranges;

    AppGpu(AppInstance &inst, uint32_t id, VkPhysicalDevice phys_device, pNextChainInfos chainInfos)
        : inst(inst), id(id), phys_device(phys_device) {
        vkGetPhysicalDeviceProperties(phys_device, &props);

        if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
            props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
            buildpNextChain((VkStructureHeader *)&props2, chainInfos.phys_device_props2);

            inst.vkGetPhysicalDeviceProperties2KHR(phys_device, &props2);
        }

        /* get queue count */
        vkGetPhysicalDeviceQueueFamilyProperties(phys_device, &queue_count, nullptr);

        queue_props.resize(queue_count);

        vkGetPhysicalDeviceQueueFamilyProperties(phys_device, &queue_count, queue_props.data());

        if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
            queue_props2.resize(queue_count);

            for (size_t i = 0; i < queue_count; ++i) {
                queue_props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR;
                queue_props2[i].pNext = nullptr;
            }

            inst.vkGetPhysicalDeviceQueueFamilyProperties2KHR(phys_device, &queue_count, queue_props2.data());
        }

        vkGetPhysicalDeviceMemoryProperties(phys_device, &memory_props);

        vkGetPhysicalDeviceFeatures(phys_device, &features);

        if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
            memory_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR;
            buildpNextChain((VkStructureHeader *)&memory_props2, chainInfos.phys_device_mem_props2);

            inst.vkGetPhysicalDeviceMemoryProperties2KHR(phys_device, &memory_props2);

            features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
            buildpNextChain((VkStructureHeader *)&features2, chainInfos.phys_device_features2);

            inst.vkGetPhysicalDeviceFeatures2KHR(phys_device, &features2);
        }

        device_extensions = AppGetPhysicalDeviceLayerExtensions(nullptr);

        const float queue_priority = 1.0f;
        const VkDeviceQueueCreateInfo q_ci = {VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
                                              nullptr,
                                              0,
                                              0,  // just pick the first one and hope for the best
                                              1,
                                              &queue_priority};
        enabled_features = VkPhysicalDeviceFeatures{0};
        const VkDeviceCreateInfo device_ci = {
            VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, nullptr, 0, 1, &q_ci, 0, nullptr, 0, nullptr, &enabled_features};

        VkResult err = vkCreateDevice(phys_device, &device_ci, nullptr, &dev);
        if (err) ERR_EXIT(err);

        const VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
        const std::vector<VkFormat> formats = {
            color_format,      VK_FORMAT_D16_UNORM,         VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT,
            VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT,   VK_FORMAT_D32_SFLOAT_S8_UINT};
        assert(mem_type_res_support.image[0].size() == formats.size());
        const std::array<VkImageUsageFlags, 2> usages = {0, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT};
        const std::array<VkImageCreateFlags, 2> flagss = {0, VK_IMAGE_CREATE_SPARSE_BINDING_BIT};

        for (size_t fmt_i = 0; fmt_i < formats.size(); ++fmt_i) {
            // only iterate over VK_IMAGE_TILING_OPTIMAL and VK_IMAGE_TILING_LINEAR (0 and 1)
            for (size_t tiling = VK_IMAGE_TILING_OPTIMAL; tiling <= VK_IMAGE_TILING_LINEAR; ++tiling) {
                mem_type_res_support.image[tiling][fmt_i].format = formats[fmt_i];
                mem_type_res_support.image[tiling][fmt_i].regular_supported = true;
                mem_type_res_support.image[tiling][fmt_i].sparse_supported = true;
                mem_type_res_support.image[tiling][fmt_i].transient_supported = true;

                VkFormatProperties fmt_props;
                vkGetPhysicalDeviceFormatProperties(phys_device, formats[fmt_i], &fmt_props);
                if ((tiling == VK_IMAGE_TILING_OPTIMAL && fmt_props.optimalTilingFeatures == 0) ||
                    (tiling == VK_IMAGE_TILING_LINEAR && fmt_props.linearTilingFeatures == 0)) {
                    mem_type_res_support.image[tiling][fmt_i].regular_supported = false;
                    mem_type_res_support.image[tiling][fmt_i].sparse_supported = false;
                    mem_type_res_support.image[tiling][fmt_i].transient_supported = false;
                    continue;
                }

                for (size_t u_i = 0; u_i < usages.size(); ++u_i) {
                    for (size_t flg_i = 0; flg_i < flagss.size(); ++flg_i) {
                        VkImageCreateInfo image_ci = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
                                                      nullptr,
                                                      flagss[flg_i],
                                                      VK_IMAGE_TYPE_2D,
                                                      formats[fmt_i],
                                                      {8, 8, 1},
                                                      1,
                                                      1,
                                                      VK_SAMPLE_COUNT_1_BIT,
                                                      static_cast<VkImageTiling>(tiling),
                                                      usages[u_i],
                                                      VK_SHARING_MODE_EXCLUSIVE,
                                                      0,
                                                      nullptr,
                                                      VK_IMAGE_LAYOUT_UNDEFINED};

                        if ((image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) &&
                            (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) {
                            continue;
                        }

                        if (image_ci.usage == 0 || (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) {
                            if (image_ci.format == color_format)
                                image_ci.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
                            else
                                image_ci.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
                        }

                        if (!enabled_features.sparseBinding && (image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
                            mem_type_res_support.image[tiling][fmt_i].sparse_supported = false;
                            continue;
                        }

                        VkImageFormatProperties img_props;
                        err = vkGetPhysicalDeviceImageFormatProperties(phys_device, image_ci.format, image_ci.imageType,
                                                                       image_ci.tiling, image_ci.usage, image_ci.flags, &img_props);

                        uint32_t *memtypes;
                        bool *support;

                        if (image_ci.flags == 0 && !(image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) {
                            memtypes = &mem_type_res_support.image[tiling][fmt_i].regular_memtypes;
                            support = &mem_type_res_support.image[tiling][fmt_i].regular_supported;
                        } else if ((image_ci.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) &&
                                   !(image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) {
                            memtypes = &mem_type_res_support.image[tiling][fmt_i].sparse_memtypes;
                            support = &mem_type_res_support.image[tiling][fmt_i].sparse_supported;
                        } else if (image_ci.flags == 0 && (image_ci.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) {
                            memtypes = &mem_type_res_support.image[tiling][fmt_i].transient_memtypes;
                            support = &mem_type_res_support.image[tiling][fmt_i].transient_supported;
                        } else {
                            assert(false);
                            return;
                        }

                        if (err == VK_ERROR_FORMAT_NOT_SUPPORTED) {
                            *support = false;
                        } else {
                            if (err) ERR_EXIT(err);

                            VkImage dummy_img;
                            err = vkCreateImage(dev, &image_ci, nullptr, &dummy_img);
                            if (err) ERR_EXIT(err);

                            VkMemoryRequirements mem_req;
                            vkGetImageMemoryRequirements(dev, dummy_img, &mem_req);
                            *memtypes = mem_req.memoryTypeBits;

                            vkDestroyImage(dev, dummy_img, nullptr);
                        }
                    }
                }
            }
        }

        // Memory //

        struct VkStructureHeader *structure = NULL;
        if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
            structure = (struct VkStructureHeader *)memory_props2.pNext;

            while (structure) {
                if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT &&
                    CheckPhysicalDeviceExtensionIncluded(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) {
                    VkPhysicalDeviceMemoryBudgetPropertiesEXT *mem_budget_props =
                        (VkPhysicalDeviceMemoryBudgetPropertiesEXT *)structure;
                    for (uint32_t i = 0; i < VK_MAX_MEMORY_HEAPS; i++) {
                        heapBudget[i] = mem_budget_props->heapBudget[i];
                        heapUsage[i] = mem_budget_props->heapUsage[i];
                    }
                }

                structure = (struct VkStructureHeader *)structure->pNext;
            }
        }
        // TODO buffer - memory type compatibility

        supported_format_ranges = {
            {
                // Standard formats in Vulkan 1.0
                VK_MAKE_VERSION(1, 0, 0),
                NULL,
                VK_FORMAT_BEGIN_RANGE,
                VK_FORMAT_END_RANGE,
            },
            {
                // YCBCR extension, standard in Vulkan 1.1
                VK_MAKE_VERSION(1, 1, 0),
                VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
                VK_FORMAT_G8B8G8R8_422_UNORM,
                VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
            },
            {
                // PVRTC extension, not standardized
                0,
                VK_IMG_FORMAT_PVRTC_EXTENSION_NAME,
                VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,
                VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG,
            },
        };
    }
    ~AppGpu() {
        vkDestroyDevice(dev, nullptr);

        if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
            freepNextChain(static_cast<VkStructureHeader *>(features2.pNext));
            freepNextChain(static_cast<VkStructureHeader *>(props2.pNext));
            freepNextChain(static_cast<VkStructureHeader *>(memory_props2.pNext));
        }
    }

    AppGpu(const AppGpu &) = delete;
    const AppGpu &operator=(const AppGpu &) = delete;

    bool CheckPhysicalDeviceExtensionIncluded(std::string extension_to_check) {
        for (auto &extension : device_extensions) {
            if (extension_to_check == std::string(extension.extensionName)) {
                return true;
            }
        }
        return false;
    }

    std::vector<VkExtensionProperties> AppGetPhysicalDeviceLayerExtensions(char *layer_name) {
        std::vector<VkExtensionProperties> extension_properties;

        VkResult err;
        uint32_t ext_count = 0;

        /* repeat get until VK_INCOMPLETE goes away */
        do {
            err = vkEnumerateDeviceExtensionProperties(phys_device, layer_name, &ext_count, nullptr);
            if (err) ERR_EXIT(err);

            extension_properties.resize(ext_count);
            err = vkEnumerateDeviceExtensionProperties(phys_device, layer_name, &ext_count, extension_properties.data());
            if (err) ERR_EXIT(err);
            extension_properties.resize(ext_count);
        } while (err == VK_INCOMPLETE);

        return extension_properties;
    }

    // Helper function to determine whether a format range is currently supported.
    bool FormatRangeSupported(FormatRange &format_range) {
        // True if standard and supported by both this instance and this GPU
        if (format_range.minimum_instance_version > 0 && inst.instance_version >= format_range.minimum_instance_version &&
            props.apiVersion >= format_range.minimum_instance_version) {
            return true;
        }

        // True if this extension is present
        if (format_range.extension_name != nullptr) {
            return inst.CheckExtensionEnabled(format_range.extension_name);
        }

        // Otherwise, not supported.
        return false;
    }

    VkPhysicalDeviceProperties GetDeviceProperties() {
        if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
            return props2.properties;
        } else {
            return props;
        }
    }
};
struct AppQueueFamilyProperties {
    VkQueueFamilyProperties props;
    uint32_t queue_index;
    bool is_present_platform_agnostic = true;
    VkBool32 platforms_support_present = VK_FALSE;

    AppQueueFamilyProperties(AppGpu &gpu, uint32_t queue_index) : queue_index(queue_index) {
        if (gpu.inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
            props = gpu.queue_props2[queue_index].queueFamilyProperties;
        } else {
            props = gpu.queue_props[queue_index];
        }

        for (auto &surface_ext : gpu.inst.surface_extensions) {
            VkResult err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu.phys_device, queue_index, surface_ext.surface,
                                                                &surface_ext.supports_present);
            if (err) ERR_EXIT(err);

            const bool first = (surface_ext == gpu.inst.surface_extensions.at(0));
            if (!first && platforms_support_present != surface_ext.supports_present) {
                is_present_platform_agnostic = false;

                platforms_support_present = surface_ext.supports_present;
            }
        }
    }
};

// --------- Format Properties ----------//

struct PropFlags {
    uint32_t linear;
    uint32_t optimal;
    uint32_t buffer;

    bool operator==(const PropFlags &other) const {
        return (linear == other.linear && optimal == other.optimal && buffer == other.buffer);
    }
};

namespace std {
template <>
struct hash<PropFlags> {
    std::size_t operator()(const PropFlags &k) const {
        return ((std::hash<uint32_t>()(k.linear) ^ (std::hash<uint32_t>()(k.optimal) << 1)) >> 1) ^
               (std::hash<uint32_t>()(k.buffer) << 1);
    }
};
}  // namespace std

// Used to sort the formats into buckets by their properties.
std::unordered_map<PropFlags, std::vector<VkFormat>> FormatPropMap(AppGpu &gpu) {
    std::unordered_map<PropFlags, std::vector<VkFormat>> map;
    for (auto fmtRange : gpu.supported_format_ranges) {
        for (int32_t fmt = fmtRange.first_format; fmt <= fmtRange.last_format; ++fmt) {
            VkFormatProperties props;
            vkGetPhysicalDeviceFormatProperties(gpu.phys_device, static_cast<VkFormat>(fmt), &props);

            PropFlags pf = {props.linearTilingFeatures, props.optimalTilingFeatures, props.bufferFeatures};

            map[pf].push_back(static_cast<VkFormat>(fmt));
        }
    }
    return map;
}

VkFormatProperties2 GetFormatProperties2(AppGpu &gpu, VkFormat format, pNextChainInfos &chainInfos) {
    VkFormatProperties2 props;
    props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
    buildpNextChain((VkStructureHeader *)&props, chainInfos.format_properties2);

    gpu.inst.vkGetPhysicalDeviceFormatProperties2KHR(gpu.phys_device, format, &props);
    return props;
}
