diff options
Diffstat (limited to 'src/renderer.c')
| -rw-r--r-- | src/renderer.c | 1470 | 
1 files changed, 0 insertions, 1470 deletions
diff --git a/src/renderer.c b/src/renderer.c deleted file mode 100644 index 7022af6..0000000 --- a/src/renderer.c +++ /dev/null @@ -1,1470 +0,0 @@ -#include "log.h" -#include "renderer.h" -#include "src/platform.h" -#include "vulkan/vulkan_core.h" -#include <assert.h> - -static const char *VALIDATION_LAYERS[] = {"VK_LAYER_KHRONOS_validation"}; -static constexpr int VALIDATION_LAYER_COUNT = -    sizeof(VALIDATION_LAYERS) / sizeof(VALIDATION_LAYERS[0]); - -#ifdef VGLTF_DEBUG -static constexpr bool enable_validation_layers = true; -#else -static constexpr bool enable_validation_layers = false; -#endif - -static VKAPI_ATTR VkBool32 VKAPI_CALL -debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, -               VkDebugUtilsMessageTypeFlagBitsEXT message_type, -               const VkDebugUtilsMessengerCallbackDataEXT *callback_data, -               void *user_data) { -  (void)message_severity; -  (void)message_type; -  (void)user_data; -  VGLTF_LOG_DBG("validation layer: %s", callback_data->pMessage); -  return VK_FALSE; -} - -static constexpr int REQUIRED_INSTANCE_EXTENSIONS_ARRAY_CAPACITY = 10; -struct required_instance_extensions { -  const char *extensions[REQUIRED_INSTANCE_EXTENSIONS_ARRAY_CAPACITY]; -  uint32_t count; -}; -void required_instance_extensions_push( -    struct required_instance_extensions *required_instance_extensions, -    const char *required_instance_extension) { -  if (required_instance_extensions->count == -      REQUIRED_INSTANCE_EXTENSIONS_ARRAY_CAPACITY) { -    VGLTF_PANIC("required instance extensions array is full"); -  } -  required_instance_extensions -      ->extensions[required_instance_extensions->count++] = -      required_instance_extension; -} - -static constexpr int SUPPORTED_INSTANCE_EXTENSIONS_ARRAY_CAPACITY = 128; -struct supported_instance_extensions { -  VkExtensionProperties -      properties[SUPPORTED_INSTANCE_EXTENSIONS_ARRAY_CAPACITY]; -  uint32_t count; -}; -bool supported_instance_extensions_init( -    struct supported_instance_extensions *supported_instance_extensions) { -  if (vkEnumerateInstanceExtensionProperties( -          nullptr, &supported_instance_extensions->count, nullptr) != -      VK_SUCCESS) { -    goto err; -  } - -  if (supported_instance_extensions->count > -      SUPPORTED_INSTANCE_EXTENSIONS_ARRAY_CAPACITY) { -    VGLTF_LOG_ERR("supported instance extensions array cannot fit all the " -                  "VkExtensionProperties"); -    goto err; -  } - -  if (vkEnumerateInstanceExtensionProperties( -          nullptr, &supported_instance_extensions->count, -          supported_instance_extensions->properties) != VK_SUCCESS) { -    goto err; -  } -  return true; -err: -  return false; -} -void supported_instance_extensions_debug_print( -    const struct supported_instance_extensions *supported_instance_extensions) { -  VGLTF_LOG_DBG("Supported instance extensions:"); -  for (uint32_t i = 0; i < supported_instance_extensions->count; i++) { -    VGLTF_LOG_DBG("\t- %s", -                  supported_instance_extensions->properties[i].extensionName); -  } -} -bool supported_instance_extensions_includes( -    const struct supported_instance_extensions *supported_instance_extensions, -    const char *extension_name) { -  for (uint32_t supported_instance_extension_index = 0; -       supported_instance_extension_index < -       supported_instance_extensions->count; -       supported_instance_extension_index++) { -    const VkExtensionProperties *extension_properties = -        &supported_instance_extensions -             ->properties[supported_instance_extension_index]; -    if (strcmp(extension_properties->extensionName, extension_name) == 0) { -      return true; -    } -  } - -  return false; -} - -static constexpr uint32_t SUPPORTED_VALIDATION_LAYERS_ARRAY_CAPACITY = 64; -struct supported_validation_layers { -  VkLayerProperties properties[SUPPORTED_VALIDATION_LAYERS_ARRAY_CAPACITY]; -  uint32_t count; -}; -bool supported_validation_layers_init( -    struct supported_validation_layers *supported_validation_layers) { -  if (vkEnumerateInstanceLayerProperties(&supported_validation_layers->count, -                                         nullptr) != VK_SUCCESS) { -    goto err; -  } - -  if (supported_validation_layers->count > -      SUPPORTED_VALIDATION_LAYERS_ARRAY_CAPACITY) { -    VGLTF_LOG_ERR("supported validation layers array cannot fit all the " -                  "VkLayerProperties"); -    goto err; -  } - -  if (vkEnumerateInstanceLayerProperties( -          &supported_validation_layers->count, -          supported_validation_layers->properties) != VK_SUCCESS) { -    goto err; -  } - -  return true; -err: -  return false; -} - -static bool are_validation_layer_supported() { -  struct supported_validation_layers supported_layers = {}; -  if (!supported_validation_layers_init(&supported_layers)) { -    goto err; -  } - -  for (int requested_layer_index = 0; -       requested_layer_index < VALIDATION_LAYER_COUNT; -       requested_layer_index++) { -    const char *requested_layer_name = VALIDATION_LAYERS[requested_layer_index]; -    bool requested_layer_found = false; -    for (uint32_t supported_layer_index = 0; -         supported_layer_index < supported_layers.count; -         supported_layer_index++) { -      VkLayerProperties *supported_layer = -          &supported_layers.properties[supported_layer_index]; -      if (strcmp(requested_layer_name, supported_layer->layerName) == 0) { -        requested_layer_found = true; -        break; -      } -    } - -    if (!requested_layer_found) { -      goto err; -    } -  } - -  return true; -err: -  return false; -} - -static bool fetch_required_instance_extensions( -    struct required_instance_extensions *required_extensions, -    struct vgltf_platform *platform) { -  struct supported_instance_extensions supported_extensions = {}; -  if (!supported_instance_extensions_init(&supported_extensions)) { -    VGLTF_LOG_ERR( -        "Couldn't fetch supported instance extensions details (OOM?)"); -    goto err; -  } -  supported_instance_extensions_debug_print(&supported_extensions); - -  uint32_t platform_required_extension_count = 0; -  const char *const *platform_required_extensions = -      vgltf_platform_get_vulkan_instance_extensions( -          platform, &platform_required_extension_count); -  for (uint32_t platform_required_extension_index = 0; -       platform_required_extension_index < platform_required_extension_count; -       platform_required_extension_index++) { -    required_instance_extensions_push( -        required_extensions, -        platform_required_extensions[platform_required_extension_index]); -  } -  required_instance_extensions_push( -      required_extensions, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); - -  if (enable_validation_layers) { -    required_instance_extensions_push(required_extensions, -                                      VK_EXT_DEBUG_UTILS_EXTENSION_NAME); -  } - -  bool all_extensions_supported = true; -  for (uint32_t required_extension_index = 0; -       required_extension_index < required_extensions->count; -       required_extension_index++) { -    const char *required_extension_name = -        required_extensions->extensions[required_extension_index]; -    if (!supported_instance_extensions_includes(&supported_extensions, -                                                required_extension_name)) { -      VGLTF_LOG_ERR("Unsupported instance extension: %s", -                    required_extension_name); -      all_extensions_supported = false; -    } -  } - -  if (!all_extensions_supported) { -    VGLTF_LOG_ERR("Some required extensions are unsupported."); -    goto err; -  } - -  return true; -err: -  return false; -} - -static void populate_debug_messenger_create_info( -    VkDebugUtilsMessengerCreateInfoEXT *create_info) { -  *create_info = (VkDebugUtilsMessengerCreateInfoEXT){}; -  create_info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; -  create_info->messageSeverity = -      VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | -      VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | -      VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; -  create_info->messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | -                             VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | -                             VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; -  create_info->pfnUserCallback = debug_callback; -} - -static bool vgltf_renderer_create_instance(struct vgltf_renderer *renderer, -                                           struct vgltf_platform *platform) { -  VGLTF_LOG_INFO("Creating vulkan instance..."); -  if (enable_validation_layers && !are_validation_layer_supported()) { -    VGLTF_LOG_ERR("Requested validation layers aren't supported"); -    goto err; -  } - -  VkApplicationInfo application_info = { -      .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, -      .pApplicationName = "Visible GLTF", -      .applicationVersion = VK_MAKE_VERSION(0, 1, 0), -      .pEngineName = "No Engine", -      .engineVersion = VK_MAKE_VERSION(1, 0, 0), -      .apiVersion = VK_API_VERSION_1_2}; - -  struct required_instance_extensions required_extensions = {}; -  fetch_required_instance_extensions(&required_extensions, platform); - -  VkInstanceCreateInfo create_info = { -      .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, -      .pApplicationInfo = &application_info, -      .enabledExtensionCount = required_extensions.count, -      .ppEnabledExtensionNames = required_extensions.extensions, -      .flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR}; - -  VkDebugUtilsMessengerCreateInfoEXT debug_create_info; -  if (enable_validation_layers) { -    create_info.enabledLayerCount = VALIDATION_LAYER_COUNT; -    create_info.ppEnabledLayerNames = VALIDATION_LAYERS; -    populate_debug_messenger_create_info(&debug_create_info); -    create_info.pNext = &debug_create_info; -  } - -  if (vkCreateInstance(&create_info, nullptr, &renderer->instance) != -      VK_SUCCESS) { -    VGLTF_LOG_ERR("Failed to create VkInstance"); -    goto err; -  } - -  return true; -err: -  return false; -} - -static VkResult create_debug_utils_messenger_ext( -    VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *create_info, -    const VkAllocationCallbacks *allocator, -    VkDebugUtilsMessengerEXT *debug_messenger) { -  auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr( -      instance, "vkCreateDebugUtilsMessengerEXT"); -  if (func != nullptr) { -    return func(instance, create_info, allocator, debug_messenger); -  } - -  return VK_ERROR_EXTENSION_NOT_PRESENT; -} - -static void -destroy_debug_utils_messenger_ext(VkInstance instance, -                                  VkDebugUtilsMessengerEXT debug_messenger, -                                  const VkAllocationCallbacks *allocator) { -  auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr( -      instance, "vkDestroyDebugUtilsMessengerEXT"); -  if (func != nullptr) { -    func(instance, debug_messenger, allocator); -  } -} - -static void -vgltf_renderer_setup_debug_messenger(struct vgltf_renderer *renderer) { -  if (!enable_validation_layers) -    return; -  VkDebugUtilsMessengerCreateInfoEXT create_info; -  populate_debug_messenger_create_info(&create_info); -  create_debug_utils_messenger_ext(renderer->instance, &create_info, nullptr, -                                   &renderer->debug_messenger); -} - -static constexpr int AVAILABLE_PHYSICAL_DEVICE_ARRAY_CAPACITY = 128; -struct available_physical_devices { -  VkPhysicalDevice devices[AVAILABLE_PHYSICAL_DEVICE_ARRAY_CAPACITY]; -  uint32_t count; -}; -static bool -available_physical_devices_init(VkInstance instance, -                                struct available_physical_devices *devices) { - -  if (vkEnumeratePhysicalDevices(instance, &devices->count, nullptr) != -      VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't enumerate physical devices"); -    goto err; -  } - -  if (devices->count == 0) { -    VGLTF_LOG_ERR("Failed to find any GPU with Vulkan support"); -    goto err; -  } - -  if (devices->count > AVAILABLE_PHYSICAL_DEVICE_ARRAY_CAPACITY) { -    VGLTF_LOG_ERR("available physical devices array cannot fit all available " -                  "physical devices"); -    goto err; -  } - -  if (vkEnumeratePhysicalDevices(instance, &devices->count, devices->devices) != -      VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't enumerate physical devices"); -    goto err; -  } - -  return true; -err: -  return false; -} - -struct queue_family_indices { -  uint32_t graphics_family; -  uint32_t present_family; -  bool has_graphics_family; -  bool has_present_family; -}; -bool queue_family_indices_is_complete( -    const struct queue_family_indices *indices) { -  return indices->has_graphics_family && indices->has_present_family; -} -bool queue_family_indices_for_device(struct queue_family_indices *indices, -                                     VkPhysicalDevice device, -                                     VkSurfaceKHR surface) { -  static constexpr uint32_t QUEUE_FAMILY_PROPERTIES_ARRAY_CAPACITY = 64; -  uint32_t queue_family_count = 0; -  vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, -                                           nullptr); - -  if (queue_family_count > QUEUE_FAMILY_PROPERTIES_ARRAY_CAPACITY) { -    VGLTF_LOG_ERR( -        "Queue family properties array cannot fit all queue family properties"); -    goto err; -  } - -  VkQueueFamilyProperties -      queue_family_properties[QUEUE_FAMILY_PROPERTIES_ARRAY_CAPACITY] = {}; -  vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, -                                           queue_family_properties); - -  for (uint32_t queue_family_index = 0; queue_family_index < queue_family_count; -       queue_family_index++) { -    VkQueueFamilyProperties *queue_family = -        &queue_family_properties[queue_family_index]; - -    VkBool32 present_support; -    vkGetPhysicalDeviceSurfaceSupportKHR(device, queue_family_index, surface, -                                         &present_support); - -    if (queue_family->queueFlags & VK_QUEUE_GRAPHICS_BIT) { -      indices->graphics_family = queue_family_index; -      indices->has_graphics_family = true; -    } - -    if (present_support) { -      indices->present_family = queue_family_index; -      indices->has_present_family = true; -    } - -    if (queue_family_indices_is_complete(indices)) { -      break; -    } -  } - -  return true; -err: -  return false; -} - -static bool is_in_array(uint32_t *array, int length, uint32_t value) { -  for (int i = 0; i < length; i++) { -    if (array[i] == value) { -      return true; -    } -  } - -  return false; -} - -static constexpr uint32_t SUPPORTED_EXTENSIONS_ARRAY_CAPACITY = 128; -struct supported_extensions { -  VkExtensionProperties properties[SUPPORTED_EXTENSIONS_ARRAY_CAPACITY]; -  uint32_t count; -}; -bool supported_extensions_init( -    struct supported_extensions *supported_extensions, -    VkPhysicalDevice device) { -  if (vkEnumerateDeviceExtensionProperties(device, nullptr, -                                           &supported_extensions->count, -                                           nullptr) != VK_SUCCESS) { -    goto err; -  } - -  if (supported_extensions->count > SUPPORTED_EXTENSIONS_ARRAY_CAPACITY) { -    VGLTF_LOG_ERR( -        "supported extensions aarray cannot fit all the VkExtensionProperties"); -    goto err; -  } - -  if (vkEnumerateDeviceExtensionProperties( -          device, nullptr, &supported_extensions->count, -          supported_extensions->properties) != VK_SUCCESS) { -    goto err; -  } - -  return true; -err: -  return false; -} - -static bool supported_extensions_includes_extension( -    struct supported_extensions *supported_extensions, -    const char *extension_name) { -  for (uint32_t supported_extension_index = 0; -       supported_extension_index < supported_extensions->count; -       supported_extension_index++) { -    if (strcmp(supported_extensions->properties[supported_extension_index] -                   .extensionName, -               extension_name) == 0) { -      return true; -    } -  } -  return false; -} - -static const char *DEVICE_EXTENSIONS[] = {VK_KHR_SWAPCHAIN_EXTENSION_NAME, -                                          "VK_KHR_portability_subset"}; -static constexpr int DEVICE_EXTENSION_COUNT = -    sizeof(DEVICE_EXTENSIONS) / sizeof(DEVICE_EXTENSIONS[0]); -static bool are_device_extensions_supported(VkPhysicalDevice device) { -  struct supported_extensions supported_extensions = {}; -  if (!supported_extensions_init(&supported_extensions, device)) { -    goto err; -  } - -  for (uint32_t required_extension_index = 0; -       required_extension_index < DEVICE_EXTENSION_COUNT; -       required_extension_index++) { -    if (!supported_extensions_includes_extension( -            &supported_extensions, -            DEVICE_EXTENSIONS[required_extension_index])) { -      VGLTF_LOG_DBG("Unsupported: %s", -                    DEVICE_EXTENSIONS[required_extension_index]); -      goto err; -    } -  } - -  return true; - -err: -  return false; -} - -static constexpr int SWAPCHAIN_SUPPORT_DETAILS_MAX_SURFACE_FORMAT_COUNT = 256; -static constexpr int SWAPCHAIN_SUPPORT_DETAILS_MAX_PRESENT_MODE_COUNT = 256; -struct swapchain_support_details { -  VkSurfaceCapabilitiesKHR capabilities; -  VkSurfaceFormatKHR -      formats[SWAPCHAIN_SUPPORT_DETAILS_MAX_SURFACE_FORMAT_COUNT]; -  VkPresentModeKHR -      present_modes[SWAPCHAIN_SUPPORT_DETAILS_MAX_PRESENT_MODE_COUNT]; -  uint32_t format_count; -  uint32_t present_mode_count; -}; -bool swapchain_support_details_query_from_device( -    struct swapchain_support_details *swapchain_support_details, -    VkPhysicalDevice device, VkSurfaceKHR surface) { -  if (vkGetPhysicalDeviceSurfaceCapabilitiesKHR( -          device, surface, &swapchain_support_details->capabilities) != -      VK_SUCCESS) { -    goto err; -  } - -  if (vkGetPhysicalDeviceSurfaceFormatsKHR( -          device, surface, &swapchain_support_details->format_count, nullptr) != -      VK_SUCCESS) { -    goto err; -  } - -  if (swapchain_support_details->format_count != 0 && -      swapchain_support_details->format_count < -          SWAPCHAIN_SUPPORT_DETAILS_MAX_SURFACE_FORMAT_COUNT) { -    if (vkGetPhysicalDeviceSurfaceFormatsKHR( -            device, surface, &swapchain_support_details->format_count, -            swapchain_support_details->formats) != VK_SUCCESS) { -      goto err; -    } -  } - -  if (vkGetPhysicalDeviceSurfacePresentModesKHR( -          device, surface, &swapchain_support_details->present_mode_count, -          nullptr) != VK_SUCCESS) { -    goto err; -  } - -  if (swapchain_support_details->present_mode_count != 0 && -      swapchain_support_details->present_mode_count < -          SWAPCHAIN_SUPPORT_DETAILS_MAX_PRESENT_MODE_COUNT) { -    if (vkGetPhysicalDeviceSurfacePresentModesKHR( -            device, surface, &swapchain_support_details->present_mode_count, -            swapchain_support_details->present_modes) != VK_SUCCESS) { -      goto err; -    } -  } - -  return true; -err: -  return false; -} - -static bool is_physical_device_suitable(VkPhysicalDevice device, -                                        VkSurfaceKHR surface) { -  struct queue_family_indices indices = {}; -  queue_family_indices_for_device(&indices, device, surface); - -  VGLTF_LOG_DBG("Checking for physical device extension support"); -  bool extensions_supported = are_device_extensions_supported(device); -  VGLTF_LOG_DBG("Supported: %d", extensions_supported); - -  bool swapchain_adequate = false; -  if (extensions_supported) { - -    VGLTF_LOG_DBG("Checking for swapchain support details"); -    struct swapchain_support_details swapchain_support_details = {}; -    if (!swapchain_support_details_query_from_device(&swapchain_support_details, -                                                     device, surface)) { -      VGLTF_LOG_ERR("Couldn't query swapchain support details from device"); -      goto err; -    } - -    swapchain_adequate = swapchain_support_details.format_count > 0 && -                         swapchain_support_details.present_mode_count > 0; -  } - -  return queue_family_indices_is_complete(&indices) && extensions_supported && -         swapchain_adequate; -err: -  return false; -} - -static bool -vgltf_renderer_pick_physical_device(struct vgltf_renderer *renderer) { -  VkPhysicalDevice physical_device = VK_NULL_HANDLE; - -  struct available_physical_devices available_physical_devices = {}; -  if (!available_physical_devices_init(renderer->instance, -                                       &available_physical_devices)) { -    VGLTF_LOG_ERR("Couldn't fetch available physical devices"); -    goto err; -  } - -  for (uint32_t available_physical_device_index = 0; -       available_physical_device_index < available_physical_devices.count; -       available_physical_device_index++) { -    VkPhysicalDevice available_physical_device = -        available_physical_devices.devices[available_physical_device_index]; -    if (is_physical_device_suitable(available_physical_device, -                                    renderer->surface)) { -      physical_device = available_physical_device; -      break; -    } -  } - -  if (physical_device == VK_NULL_HANDLE) { -    VGLTF_LOG_ERR("Failed to find a suitable GPU"); -    goto err; -  } - -  renderer->physical_device = physical_device; - -  return true; -err: -  return false; -} - -static bool -vgltf_renderer_create_logical_device(struct vgltf_renderer *renderer) { -  struct queue_family_indices queue_family_indices = {}; -  queue_family_indices_for_device(&queue_family_indices, -                                  renderer->physical_device, renderer->surface); -  static constexpr int MAX_QUEUE_FAMILY_COUNT = 2; - -  uint32_t unique_queue_families[MAX_QUEUE_FAMILY_COUNT] = {}; -  int unique_queue_family_count = 0; - -  if (!is_in_array(unique_queue_families, unique_queue_family_count, -                   queue_family_indices.graphics_family)) { -    assert(unique_queue_family_count < MAX_QUEUE_FAMILY_COUNT); -    unique_queue_families[unique_queue_family_count++] = -        queue_family_indices.graphics_family; -  } -  if (!is_in_array(unique_queue_families, unique_queue_family_count, -                   queue_family_indices.present_family)) { -    assert(unique_queue_family_count < MAX_QUEUE_FAMILY_COUNT); -    unique_queue_families[unique_queue_family_count++] = -        queue_family_indices.present_family; -  } - -  float queue_priority = 1.f; -  VkDeviceQueueCreateInfo queue_create_infos[MAX_QUEUE_FAMILY_COUNT] = {}; -  int queue_create_info_count = 0; -  for (int unique_queue_family_index = 0; -       unique_queue_family_index < unique_queue_family_count; -       unique_queue_family_index++) { -    queue_create_infos[queue_create_info_count++] = (VkDeviceQueueCreateInfo){ -        .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, -        .queueFamilyIndex = unique_queue_families[unique_queue_family_index], -        .queueCount = 1, -        .pQueuePriorities = &queue_priority}; -  } - -  VkPhysicalDeviceFeatures device_features = {}; -  VkDeviceCreateInfo create_info = { -      .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, -      .pQueueCreateInfos = queue_create_infos, -      .queueCreateInfoCount = queue_create_info_count, -      .pEnabledFeatures = &device_features, -      .ppEnabledExtensionNames = DEVICE_EXTENSIONS, -      .enabledExtensionCount = DEVICE_EXTENSION_COUNT}; -  if (vkCreateDevice(renderer->physical_device, &create_info, nullptr, -                     &renderer->device) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Failed to create logical device"); -    goto err; -  } - -  vkGetDeviceQueue(renderer->device, queue_family_indices.graphics_family, 0, -                   &renderer->graphics_queue); -  vkGetDeviceQueue(renderer->device, queue_family_indices.present_family, 0, -                   &renderer->present_queue); - -  return true; -err: -  return false; -} - -static bool vgltf_renderer_create_surface(struct vgltf_renderer *renderer, -                                          struct vgltf_platform *platform) { -  if (!vgltf_platform_create_vulkan_surface(platform, renderer->instance, -                                            &renderer->surface)) { -    VGLTF_LOG_ERR("Couldn't create surface"); -    goto err; -  } - -  return true; -err: -  return false; -} - -static VkSurfaceFormatKHR -choose_swapchain_surface_format(VkSurfaceFormatKHR *available_formats, -                                uint32_t available_format_count) { -  for (uint32_t available_format_index = 0; -       available_format_index < available_format_count; -       available_format_index++) { -    VkSurfaceFormatKHR *available_format = -        &available_formats[available_format_index]; -    if (available_format->format == VK_FORMAT_B8G8R8A8_SRGB && -        available_format->colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { -      return *available_format; -    } -  } - -  return available_formats[0]; -} - -static VkPresentModeKHR -choose_swapchain_present_mode(VkPresentModeKHR *available_modes, -                              uint32_t available_mode_count) { -  for (uint32_t available_mode_index = 0; -       available_mode_index < available_mode_count; available_mode_index++) { -    VkPresentModeKHR available_mode = available_modes[available_mode_index]; -    if (available_mode == VK_PRESENT_MODE_MAILBOX_KHR) { -      return available_mode; -    } -  } - -  return VK_PRESENT_MODE_FIFO_KHR; -} - -static uint32_t clamp_uint32(uint32_t min, uint32_t max, uint32_t value) { -  return value < min ? min : value > max ? max : value; -} - -static VkExtent2D -choose_swapchain_extent(const VkSurfaceCapabilitiesKHR *capabilities, int width, -                        int height) { -  if (capabilities->currentExtent.width != UINT32_MAX) { -    return capabilities->currentExtent; -  } else { -    VkExtent2D actual_extent = {width, height}; -    actual_extent.width = -        clamp_uint32(capabilities->minImageExtent.width, -                     capabilities->maxImageExtent.width, actual_extent.width); -    actual_extent.height = -        clamp_uint32(capabilities->minImageExtent.height, -                     capabilities->maxImageExtent.height, actual_extent.height); -    return actual_extent; -  } -} - -static bool vgltf_renderer_create_swapchain(struct vgltf_renderer *renderer) { -  struct swapchain_support_details swapchain_support_details = {}; -  swapchain_support_details_query_from_device( -      &swapchain_support_details, renderer->physical_device, renderer->surface); - -  VkSurfaceFormatKHR surface_format = -      choose_swapchain_surface_format(swapchain_support_details.formats, -                                      swapchain_support_details.format_count); -  VkPresentModeKHR present_mode = choose_swapchain_present_mode( -      swapchain_support_details.present_modes, -      swapchain_support_details.present_mode_count); - -  VkExtent2D extent = choose_swapchain_extent( -      &swapchain_support_details.capabilities, renderer->window_size.width, -      renderer->window_size.height); -  uint32_t image_count = -      swapchain_support_details.capabilities.minImageCount + 1; -  if (swapchain_support_details.capabilities.maxImageCount > 0 && -      image_count > swapchain_support_details.capabilities.maxImageCount) { -    image_count = swapchain_support_details.capabilities.maxImageCount; -  } - -  VkSwapchainCreateInfoKHR create_info = { -      .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, -      .surface = renderer->surface, -      .minImageCount = image_count, -      .imageFormat = surface_format.format, -      .imageColorSpace = surface_format.colorSpace, -      .imageExtent = extent, -      .imageArrayLayers = 1, -      .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT}; -  struct queue_family_indices indices = {}; -  queue_family_indices_for_device(&indices, renderer->physical_device, -                                  renderer->surface); -  uint32_t queue_family_indices[] = {indices.graphics_family, -                                     indices.present_family}; -  if (indices.graphics_family != indices.present_family) { -    create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; -    create_info.queueFamilyIndexCount = 2; -    create_info.pQueueFamilyIndices = queue_family_indices; -  } else { -    create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; -  } - -  create_info.preTransform = -      swapchain_support_details.capabilities.currentTransform; -  create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; -  create_info.presentMode = present_mode; -  create_info.clipped = VK_TRUE; -  create_info.oldSwapchain = VK_NULL_HANDLE; - -  if (vkCreateSwapchainKHR(renderer->device, &create_info, nullptr, -                           &renderer->swapchain) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Swapchain creation failed!"); -    goto err; -  } - -  if (vkGetSwapchainImagesKHR(renderer->device, renderer->swapchain, -                              &renderer->swapchain_image_count, -                              nullptr) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't get swapchain image count"); -    goto destroy_swapchain; -  } - -  if (renderer->swapchain_image_count > -      VGLTF_RENDERER_MAX_SWAPCHAIN_IMAGE_COUNT) { -    VGLTF_LOG_ERR("Swapchain image array cannot fit all %d swapchain images", -                  renderer->swapchain_image_count); -    goto destroy_swapchain; -  } - -  if (vkGetSwapchainImagesKHR(renderer->device, renderer->swapchain, -                              &renderer->swapchain_image_count, -                              renderer->swapchain_images) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't get swapchain images"); -    goto destroy_swapchain; -  } - -  renderer->swapchain_image_format = surface_format.format; -  renderer->swapchain_extent = extent; - -  return true; -destroy_swapchain: -  vkDestroySwapchainKHR(renderer->device, renderer->swapchain, nullptr); -err: -  return false; -} - -static bool vgltf_renderer_create_image_views(struct vgltf_renderer *renderer) { -  uint32_t swapchain_image_index; -  for (swapchain_image_index = 0; -       swapchain_image_index < renderer->swapchain_image_count; -       swapchain_image_index++) { -    VkImage swapchain_image = renderer->swapchain_images[swapchain_image_index]; - -    VkImageViewCreateInfo create_info = { -        .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, -        .image = swapchain_image, -        .viewType = VK_IMAGE_VIEW_TYPE_2D, -        .format = renderer->swapchain_image_format, -        .components = {VK_COMPONENT_SWIZZLE_IDENTITY, -                       VK_COMPONENT_SWIZZLE_IDENTITY, -                       VK_COMPONENT_SWIZZLE_IDENTITY, -                       VK_COMPONENT_SWIZZLE_IDENTITY}, -        .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, -                             .levelCount = 1, -                             .layerCount = 1}}; - -    if (vkCreateImageView( -            renderer->device, &create_info, nullptr, -            &renderer->swapchain_image_views[swapchain_image_index]) != -        VK_SUCCESS) { -      goto err; -    } -  } -  return true; -err: -  for (uint32_t to_remove_index = 0; to_remove_index < swapchain_image_index; -       to_remove_index++) { -    vkDestroyImageView(renderer->device, -                       renderer->swapchain_image_views[to_remove_index], -                       nullptr); -  } -  return false; -} - -static bool create_shader_module(VkDevice device, const unsigned char *code, -                                 int size, VkShaderModule *out) { -  VkShaderModuleCreateInfo create_info = { -      .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, -      .codeSize = size, -      .pCode = (const uint32_t *)code, -  }; -  if (vkCreateShaderModule(device, &create_info, nullptr, out) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't create shader module"); -    goto err; -  } -  return true; -err: -  return false; -} - -static bool vgltf_renderer_create_render_pass(struct vgltf_renderer *renderer) { -  VkAttachmentDescription color_attachment = { -      .format = renderer->swapchain_image_format, -      .samples = VK_SAMPLE_COUNT_1_BIT, -      .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, -      .storeOp = VK_ATTACHMENT_STORE_OP_STORE, -      .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, -      .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, -      .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, -      .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR}; -  VkAttachmentReference color_attachment_ref = { -      .attachment = 0, -      .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, -  }; -  VkSubpassDescription subpass = {.pipelineBindPoint = -                                      VK_PIPELINE_BIND_POINT_GRAPHICS, -                                  .pColorAttachments = &color_attachment_ref, -                                  .colorAttachmentCount = 1}; -  VkSubpassDependency dependency = { -      .srcSubpass = VK_SUBPASS_EXTERNAL, -      .dstSubpass = 0, -      .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, -      .srcAccessMask = 0, -      .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, -      .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT}; - -  VkRenderPassCreateInfo render_pass_info = { -      .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, -      .attachmentCount = 1, -      .pAttachments = &color_attachment, -      .subpassCount = 1, -      .pSubpasses = &subpass, -      .dependencyCount = 1, -      .pDependencies = &dependency}; - -  if (vkCreateRenderPass(renderer->device, &render_pass_info, nullptr, -                         &renderer->render_pass) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Failed to create render pass"); -    goto err; -  } - -  return true; -err: -  return false; -} - -static bool -vgltf_renderer_create_graphics_pipeline(struct vgltf_renderer *renderer) { -  static constexpr unsigned char triangle_shader_vert_code[] = { -#embed "../compiled_shaders/triangle.vert.spv" -  }; -  static constexpr unsigned char triangle_shader_frag_code[] = { -#embed "../compiled_shaders/triangle.frag.spv" -  }; - -  VkShaderModule triangle_shader_vert_module; -  if (!create_shader_module(renderer->device, triangle_shader_vert_code, -                            sizeof(triangle_shader_vert_code), -                            &triangle_shader_vert_module)) { -    VGLTF_LOG_ERR("Couldn't create triangle vert shader module"); -    goto err; -  } - -  VkShaderModule triangle_shader_frag_module; -  if (!create_shader_module(renderer->device, triangle_shader_frag_code, -                            sizeof(triangle_shader_frag_code), -                            &triangle_shader_frag_module)) { -    VGLTF_LOG_ERR("Couldn't create triangle frag shader module"); -    goto destroy_vert_shader_module; -  } - -  VkPipelineShaderStageCreateInfo triangle_shader_vert_stage_create_info = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, -      .stage = VK_SHADER_STAGE_VERTEX_BIT, -      .module = triangle_shader_vert_module, -      .pName = "main"}; -  VkPipelineShaderStageCreateInfo triangle_shader_frag_stage_create_info = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, -      .stage = VK_SHADER_STAGE_FRAGMENT_BIT, -      .module = triangle_shader_frag_module, -      .pName = "main"}; -  VkPipelineShaderStageCreateInfo shader_stages[] = { -      triangle_shader_vert_stage_create_info, -      triangle_shader_frag_stage_create_info}; - -  VkDynamicState dynamic_states[] = { -      VK_DYNAMIC_STATE_VIEWPORT, -      VK_DYNAMIC_STATE_SCISSOR, -  }; - -  VkPipelineDynamicStateCreateInfo dynamic_state = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, -      .dynamicStateCount = sizeof(dynamic_states) / sizeof(dynamic_states[0]), -      .pDynamicStates = dynamic_states}; - -  VkPipelineVertexInputStateCreateInfo vertex_input_info = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, -      .vertexBindingDescriptionCount = 0, -      .vertexAttributeDescriptionCount = 0, -  }; - -  VkPipelineInputAssemblyStateCreateInfo input_assembly = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, -      .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, -      .primitiveRestartEnable = VK_FALSE, -  }; - -  VkPipelineViewportStateCreateInfo viewport_state = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, -      .viewportCount = 1, -      .scissorCount = 1}; - -  VkPipelineRasterizationStateCreateInfo rasterizer = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, -      .depthClampEnable = VK_FALSE, -      .rasterizerDiscardEnable = VK_FALSE, -      .polygonMode = VK_POLYGON_MODE_FILL, -      .lineWidth = 1.f, -      .cullMode = VK_CULL_MODE_BACK_BIT, -      .frontFace = VK_FRONT_FACE_CLOCKWISE, -      .depthBiasEnable = VK_FALSE}; - -  VkPipelineMultisampleStateCreateInfo multisampling = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, -      .sampleShadingEnable = VK_FALSE, -      .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, -  }; - -  VkPipelineColorBlendAttachmentState color_blend_attachment = { -      .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | -                        VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, -      .blendEnable = VK_FALSE, -  }; - -  VkPipelineColorBlendStateCreateInfo color_blending = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, -      .logicOpEnable = VK_FALSE, -      .attachmentCount = 1, -      .pAttachments = &color_blend_attachment}; - -  VkPipelineLayoutCreateInfo pipeline_layout_info = { -      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, -  }; - -  if (vkCreatePipelineLayout(renderer->device, &pipeline_layout_info, nullptr, -                             &renderer->pipeline_layout) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't create pipeline layout"); -    goto destroy_frag_shader_module; -  } - -  VkGraphicsPipelineCreateInfo pipeline_info = { -      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, -      .stageCount = 2, -      .pStages = shader_stages, -      .pVertexInputState = &vertex_input_info, -      .pInputAssemblyState = &input_assembly, -      .pViewportState = &viewport_state, -      .pRasterizationState = &rasterizer, -      .pMultisampleState = &multisampling, -      .pColorBlendState = &color_blending, -      .pDynamicState = &dynamic_state, -      .layout = renderer->pipeline_layout, -      .renderPass = renderer->render_pass, -      .subpass = 0, -  }; - -  if (vkCreateGraphicsPipelines(renderer->device, VK_NULL_HANDLE, 1, -                                &pipeline_info, nullptr, -                                &renderer->graphics_pipeline) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't create pipeline"); -    goto destroy_pipeline_layout; -  } - -  vkDestroyShaderModule(renderer->device, triangle_shader_frag_module, nullptr); -  vkDestroyShaderModule(renderer->device, triangle_shader_vert_module, nullptr); -  return true; -destroy_pipeline_layout: -  vkDestroyPipelineLayout(renderer->device, renderer->pipeline_layout, nullptr); -destroy_frag_shader_module: -  vkDestroyShaderModule(renderer->device, triangle_shader_frag_module, nullptr); -destroy_vert_shader_module: -  vkDestroyShaderModule(renderer->device, triangle_shader_vert_module, nullptr); -err: -  return false; -} - -static bool -vgltf_renderer_create_framebuffers(struct vgltf_renderer *renderer) { -  for (uint32_t i = 0; i < renderer->swapchain_image_count; i++) { -    VkImageView attachments[] = {renderer->swapchain_image_views[i]}; - -    VkFramebufferCreateInfo framebuffer_info = { -        .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, -        .renderPass = renderer->render_pass, -        .attachmentCount = 1, -        .pAttachments = attachments, -        .width = renderer->swapchain_extent.width, -        .height = renderer->swapchain_extent.height, -        .layers = 1}; - -    if (vkCreateFramebuffer(renderer->device, &framebuffer_info, nullptr, -                            &renderer->swapchain_framebuffers[i]) != -        VK_SUCCESS) { -      VGLTF_LOG_ERR("Failed to create framebuffer"); -      goto err; -    } -  } - -  return true; -err: -  return false; -} - -static bool -vgltf_renderer_create_command_pool(struct vgltf_renderer *renderer) { -  struct queue_family_indices queue_family_indices = {}; -  if (!queue_family_indices_for_device(&queue_family_indices, -                                       renderer->physical_device, -                                       renderer->surface)) { -    VGLTF_LOG_ERR("Couldn't fetch queue family indices"); -    goto err; -  } - -  VkCommandPoolCreateInfo pool_info = { -      .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, -      .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, -      .queueFamilyIndex = queue_family_indices.graphics_family}; - -  if (vkCreateCommandPool(renderer->device, &pool_info, nullptr, -                          &renderer->command_pool) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't create command pool"); -    goto err; -  } - -  return true; -err: -  return false; -} - -static bool -vgltf_renderer_create_command_buffer(struct vgltf_renderer *renderer) { -  VkCommandBufferAllocateInfo allocate_info = { -      .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, -      .commandPool = renderer->command_pool, -      .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, -      .commandBufferCount = VGLTF_RENDERER_MAX_FRAME_IN_FLIGHT_COUNT}; - -  if (vkAllocateCommandBuffers(renderer->device, &allocate_info, -                               renderer->command_buffer) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Couldn't allocate command buffers"); -    goto err; -  } - -  return true; -err: -  return false; -} - -static bool -vgltf_renderer_create_sync_objects(struct vgltf_renderer *renderer) { -  VkSemaphoreCreateInfo semaphore_info = { -      .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, -  }; - -  VkFenceCreateInfo fence_info = {.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, -                                  .flags = VK_FENCE_CREATE_SIGNALED_BIT}; - -  int frame_in_flight_index = 0; -  for (; frame_in_flight_index < VGLTF_RENDERER_MAX_FRAME_IN_FLIGHT_COUNT; -       frame_in_flight_index++) { -    if (vkCreateSemaphore( -            renderer->device, &semaphore_info, nullptr, -            &renderer->image_available_semaphores[frame_in_flight_index]) != -            VK_SUCCESS || -        vkCreateSemaphore( -            renderer->device, &semaphore_info, nullptr, -            &renderer->render_finished_semaphores[frame_in_flight_index]) != -            VK_SUCCESS || -        vkCreateFence(renderer->device, &fence_info, nullptr, -                      &renderer->in_flight_fences[frame_in_flight_index]) != -            VK_SUCCESS) { -      VGLTF_LOG_ERR("Couldn't create sync objects"); -      goto err; -    } -  } - -  return true; -err: -  for (int frame_in_flight_to_delete_index = 0; -       frame_in_flight_to_delete_index < frame_in_flight_index; -       frame_in_flight_to_delete_index++) { -    vkDestroyFence(renderer->device, -                   renderer->in_flight_fences[frame_in_flight_index], nullptr); -    vkDestroySemaphore( -        renderer->device, -        renderer->render_finished_semaphores[frame_in_flight_index], nullptr); -    vkDestroySemaphore( -        renderer->device, -        renderer->image_available_semaphores[frame_in_flight_index], nullptr); -  } -  return false; -} - -static void vgltf_renderer_cleanup_swapchain(struct vgltf_renderer *renderer) { -  for (uint32_t framebuffer_index = 0; -       framebuffer_index < renderer->swapchain_image_count; -       framebuffer_index++) { -    vkDestroyFramebuffer(renderer->device, -                         renderer->swapchain_framebuffers[framebuffer_index], -                         nullptr); -  } - -  for (uint32_t image_view_index = 0; -       image_view_index < renderer->swapchain_image_count; image_view_index++) { -    vkDestroyImageView(renderer->device, -                       renderer->swapchain_image_views[image_view_index], -                       nullptr); -  } - -  vkDestroySwapchainKHR(renderer->device, renderer->swapchain, nullptr); -} - -static bool vgltf_renderer_recreate_swapchain(struct vgltf_renderer *renderer) { -  vkDeviceWaitIdle(renderer->device); -  vgltf_renderer_cleanup_swapchain(renderer); - -  // TODO add error handling -  vgltf_renderer_create_swapchain(renderer); -  vgltf_renderer_create_image_views(renderer); -  vgltf_renderer_create_framebuffers(renderer); -  return true; -} - -bool vgltf_renderer_triangle_pass(struct vgltf_renderer *renderer) { -  vkWaitForFences(renderer->device, 1, -                  &renderer->in_flight_fences[renderer->current_frame], VK_TRUE, -                  UINT64_MAX); - -  uint32_t image_index; -  VkResult acquire_swapchain_image_result = vkAcquireNextImageKHR( -      renderer->device, renderer->swapchain, UINT64_MAX, -      renderer->image_available_semaphores[renderer->current_frame], -      VK_NULL_HANDLE, &image_index); -  if (acquire_swapchain_image_result == VK_ERROR_OUT_OF_DATE_KHR || -      acquire_swapchain_image_result == VK_SUBOPTIMAL_KHR || -      renderer->framebuffer_resized) { -    renderer->framebuffer_resized = false; -    vgltf_renderer_recreate_swapchain(renderer); -    return true; -  } else if (acquire_swapchain_image_result != VK_SUCCESS) { -    VGLTF_LOG_ERR("Failed to acquire a swapchain image"); -    goto err; -  } - -  vkResetFences(renderer->device, 1, -                &renderer->in_flight_fences[renderer->current_frame]); - -  vkResetCommandBuffer(renderer->command_buffer[renderer->current_frame], 0); -  VkCommandBufferBeginInfo begin_info = { -      .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, -  }; - -  if (vkBeginCommandBuffer(renderer->command_buffer[renderer->current_frame], -                           &begin_info) != VK_SUCCESS) { -    VGLTF_LOG_ERR("Failed to begin recording command buffer"); -    goto err; -  } - -  VkRenderPassBeginInfo render_pass_info = { -      .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, -      .renderPass = renderer->render_pass, -      .framebuffer = renderer->swapchain_framebuffers[image_index], -      .renderArea = {.offset = {}, .extent = renderer->swapchain_extent}, -      .clearValueCount = 1, -      .pClearValues = -          &(const VkClearValue){.color = {.float32 = {0.f, 0.f, 0.f, 1.f}}}, - -  }; - -  vkCmdBeginRenderPass(renderer->command_buffer[renderer->current_frame], -                       &render_pass_info, VK_SUBPASS_CONTENTS_INLINE); -  vkCmdBindPipeline(renderer->command_buffer[renderer->current_frame], -                    VK_PIPELINE_BIND_POINT_GRAPHICS, -                    renderer->graphics_pipeline); -  VkViewport viewport = {.x = 0.f, -                         .y = 0.f, -                         .width = (float)renderer->swapchain_extent.width, -                         .height = (float)renderer->swapchain_extent.height, -                         .minDepth = 0.f, -                         .maxDepth = 1.f}; -  vkCmdSetViewport(renderer->command_buffer[renderer->current_frame], 0, 1, -                   &viewport); -  VkRect2D scissor = {.offset = {}, .extent = renderer->swapchain_extent}; -  vkCmdSetScissor(renderer->command_buffer[renderer->current_frame], 0, 1, -                  &scissor); - -  vkCmdDraw(renderer->command_buffer[renderer->current_frame], 3, 1, 0, 0); - -  vkCmdEndRenderPass(renderer->command_buffer[renderer->current_frame]); - -  if (vkEndCommandBuffer(renderer->command_buffer[renderer->current_frame]) != -      VK_SUCCESS) { -    VGLTF_LOG_ERR("Failed to record command buffer"); -    goto err; -  } - -  VkSubmitInfo submit_info = { -      .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, -  }; - -  VkSemaphore wait_semaphores[] = { -      renderer->image_available_semaphores[renderer->current_frame]}; -  VkPipelineStageFlags wait_stages[] = { -      VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; -  submit_info.waitSemaphoreCount = 1; -  submit_info.pWaitSemaphores = wait_semaphores; -  submit_info.pWaitDstStageMask = wait_stages; -  submit_info.commandBufferCount = 1; -  submit_info.pCommandBuffers = -      &renderer->command_buffer[renderer->current_frame]; - -  VkSemaphore signal_semaphores[] = { -      renderer->render_finished_semaphores[renderer->current_frame]}; -  submit_info.signalSemaphoreCount = 1; -  submit_info.pSignalSemaphores = signal_semaphores; -  if (vkQueueSubmit(renderer->graphics_queue, 1, &submit_info, -                    renderer->in_flight_fences[renderer->current_frame]) != -      VK_SUCCESS) { -    VGLTF_LOG_ERR("Failed to submit draw command buffer"); -    goto err; -  } - -  VkPresentInfoKHR present_info = {.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, -                                   .waitSemaphoreCount = 1, -                                   .pWaitSemaphores = signal_semaphores}; - -  VkSwapchainKHR swapchains[] = {renderer->swapchain}; -  present_info.swapchainCount = 1; -  present_info.pSwapchains = swapchains; -  present_info.pImageIndices = &image_index; -  VkResult result = vkQueuePresentKHR(renderer->present_queue, &present_info); -  if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { -    vgltf_renderer_recreate_swapchain(renderer); -  } else if (acquire_swapchain_image_result != VK_SUCCESS) { -    VGLTF_LOG_ERR("Failed to acquire a swapchain image"); -    goto err; -  } -  renderer->current_frame = -      (renderer->current_frame + 1) % VGLTF_RENDERER_MAX_FRAME_IN_FLIGHT_COUNT; -  return true; -err: -  return false; -} - -bool vgltf_renderer_init(struct vgltf_renderer *renderer, -                         struct vgltf_platform *platform) { -  if (!vgltf_renderer_create_instance(renderer, platform)) { -    VGLTF_LOG_ERR("instance creation failed"); -    goto err; -  } -  vgltf_renderer_setup_debug_messenger(renderer); -  if (!vgltf_renderer_create_surface(renderer, platform)) { -    goto destroy_instance; -  } - -  if (!vgltf_renderer_pick_physical_device(renderer)) { -    VGLTF_LOG_ERR("Couldn't pick physical device"); -    goto destroy_surface; -  } -  if (!vgltf_renderer_create_logical_device(renderer)) { -    VGLTF_LOG_ERR("Couldn't create logical device"); -    goto destroy_device; -  } - -  struct vgltf_window_size window_size = {800, 600}; -  if (!vgltf_platform_get_window_size(platform, &window_size)) { -    VGLTF_LOG_ERR("Couldn't get window size"); -    goto destroy_device; -  } -  renderer->window_size = window_size; - -  if (!vgltf_renderer_create_swapchain(renderer)) { -    VGLTF_LOG_ERR("Couldn't create swapchain"); -    goto destroy_device; -  } - -  if (!vgltf_renderer_create_image_views(renderer)) { -    VGLTF_LOG_ERR("Couldn't create image views"); -    goto destroy_swapchain; -  } - -  if (!vgltf_renderer_create_render_pass(renderer)) { -    VGLTF_LOG_ERR("Couldn't create render pass"); -    goto destroy_image_views; -  } - -  if (!vgltf_renderer_create_graphics_pipeline(renderer)) { -    VGLTF_LOG_ERR("Couldn't create graphics pipeline"); -    goto destroy_render_pass; -  } - -  if (!vgltf_renderer_create_framebuffers(renderer)) { -    VGLTF_LOG_ERR("Couldn't create framebuffers"); -    goto destroy_graphics_pipeline; -  } - -  if (!vgltf_renderer_create_command_pool(renderer)) { -    VGLTF_LOG_ERR("Couldn't create command pool"); -    goto destroy_frame_buffers; -  } - -  if (!vgltf_renderer_create_command_buffer(renderer)) { -    VGLTF_LOG_ERR("Couldn't create command buffer"); -    goto destroy_command_pool; -  } - -  if (!vgltf_renderer_create_sync_objects(renderer)) { -    VGLTF_LOG_ERR("Couldn't create sync objects"); -    goto destroy_command_pool; -  } - -  return true; - -destroy_command_pool: -  vkDestroyCommandPool(renderer->device, renderer->command_pool, nullptr); -destroy_frame_buffers: -  for (uint32_t swapchain_framebuffer_index = 0; -       swapchain_framebuffer_index < renderer->swapchain_image_count; -       swapchain_framebuffer_index++) { -    vkDestroyFramebuffer( -        renderer->device, -        renderer->swapchain_framebuffers[swapchain_framebuffer_index], nullptr); -  } -destroy_graphics_pipeline: -  vkDestroyPipeline(renderer->device, renderer->graphics_pipeline, nullptr); -  vkDestroyPipelineLayout(renderer->device, renderer->pipeline_layout, nullptr); -destroy_render_pass: -  vkDestroyRenderPass(renderer->device, renderer->render_pass, nullptr); -destroy_image_views: -  for (uint32_t swapchain_image_view_index = 0; -       swapchain_image_view_index < renderer->swapchain_image_count; -       swapchain_image_view_index++) { -    vkDestroyImageView( -        renderer->device, -        renderer->swapchain_image_views[swapchain_image_view_index], nullptr); -  } -destroy_swapchain: -  vkDestroySwapchainKHR(renderer->device, renderer->swapchain, nullptr); -destroy_device: -  vkDestroyDevice(renderer->device, nullptr); -destroy_surface: -  vkDestroySurfaceKHR(renderer->instance, renderer->surface, nullptr); -destroy_instance: -  if (enable_validation_layers) { -    destroy_debug_utils_messenger_ext(renderer->instance, -                                      renderer->debug_messenger, nullptr); -  } -  vkDestroyInstance(renderer->instance, nullptr); -err: -  return false; -} -void vgltf_renderer_deinit(struct vgltf_renderer *renderer) { -  vkDeviceWaitIdle(renderer->device); -  vgltf_renderer_cleanup_swapchain(renderer); -  vkDestroyPipeline(renderer->device, renderer->graphics_pipeline, nullptr); -  vkDestroyPipelineLayout(renderer->device, renderer->pipeline_layout, nullptr); -  vkDestroyRenderPass(renderer->device, renderer->render_pass, nullptr); -  for (int i = 0; i < VGLTF_RENDERER_MAX_FRAME_IN_FLIGHT_COUNT; i++) { -    vkDestroySemaphore(renderer->device, -                       renderer->image_available_semaphores[i], nullptr); -    vkDestroySemaphore(renderer->device, -                       renderer->render_finished_semaphores[i], nullptr); -    vkDestroyFence(renderer->device, renderer->in_flight_fences[i], nullptr); -  } -  vkDestroyCommandPool(renderer->device, renderer->command_pool, nullptr); -  vkDestroyDevice(renderer->device, nullptr); -  if (enable_validation_layers) { -    destroy_debug_utils_messenger_ext(renderer->instance, -                                      renderer->debug_messenger, nullptr); -  } -  vkDestroySurfaceKHR(renderer->instance, renderer->surface, nullptr); -  vkDestroyInstance(renderer->instance, nullptr); -} -void vgltf_renderer_on_window_resized(struct vgltf_renderer *renderer, -                                      struct vgltf_window_size size) { -  if (size.width > 0 && size.height > 0 && -      size.width != renderer->window_size.width && -      size.height != renderer->window_size.height) { -    renderer->window_size = size; -    renderer->framebuffer_resized = true; -  } -}  | 
