diff options
author | omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> | 2024-04-04 20:25:40 +1100 |
---|---|---|
committer | omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> | 2024-04-04 20:25:40 +1100 |
commit | bb889d2edc1cc72b939edf47a2e03b7569c1a722 (patch) | |
tree | 59b7744d44bda7768ba908224a18d6a5046b186f /src/renderer/backends/vulkan_helpers.h | |
parent | 1047d08258f6c56f5fa8067cc65694b1b5798602 (diff) | |
parent | 6a95b047998c0e0dcfdf60d17cf2cd0bd0bfee12 (diff) |
Merge branch 'cel-60-scaffold-vulkan' into cel-67-load-animation-data-from-gltf
Diffstat (limited to 'src/renderer/backends/vulkan_helpers.h')
-rw-r--r-- | src/renderer/backends/vulkan_helpers.h | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/renderer/backends/vulkan_helpers.h b/src/renderer/backends/vulkan_helpers.h new file mode 100644 index 0000000..3465aed --- /dev/null +++ b/src/renderer/backends/vulkan_helpers.h @@ -0,0 +1,166 @@ +#pragma once + +#include <assert.h> +#include <vulkan/vulkan.h> +#include <vulkan/vulkan_core.h> + +#include "darray.h" +#include "defines.h" +#include "log.h" +#include "str.h" + +#define VULKAN_PHYS_DEVICE_MAX_EXTENSION_NAMES 36 + +DECL_TYPED_ARRAY(const char*, cstr) + +static void plat_get_required_extension_names(cstr_darray* extensions) { +#ifdef CEL_PLATFORM_LINUX + cstr_darray_push(extensions, "VK_KHR_xcb_surface"); +#endif +} + +// TODO(omni): port to using internal assert functions +#define VK_CHECK(vulkan_expr) \ + { assert(vulkan_expr == VK_SUCCESS); } + +// TODO: typedef struct vk_debugger {} vk_debugger; + +typedef struct vulkan_physical_device_requirements { + bool graphics; + bool present; + bool compute; + bool transfer; + str8 device_ext_names[VULKAN_PHYS_DEVICE_MAX_EXTENSION_NAMES]; + size_t device_ext_name_count; + bool sampler_anistropy; + bool discrete_gpu; +} vulkan_physical_device_requirements; + +typedef struct vulkan_physical_device_queue_family_info { + u32 graphics_family_index; + u32 present_family_index; + u32 compute_family_index; + u32 transfer_family_index; +} vulkan_physical_device_queue_family_info; + +#define VULKAN_MAX_DEFAULT 32 + +typedef struct vulkan_swapchain_support_info { + VkSurfaceCapabilitiesKHR capabilities; + VkSurfaceFormatKHR formats[VULKAN_MAX_DEFAULT]; + u32 format_count; + VkPresentModeKHR present_modes[VULKAN_MAX_DEFAULT]; + u32 mode_count; +} vulkan_swapchain_support_info; + +VKAPI_ATTR VkBool32 VKAPI_CALL vk_debug_callback( + VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT flags, + const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data); + +void vulkan_device_query_swapchain_support(VkPhysicalDevice device, VkSurfaceKHR surface, + vulkan_swapchain_support_info* out_support_info) { + // TODO: add VK_CHECK to these calls! + + // Surface capabilities + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &out_support_info->capabilities); + + // Surface formats + vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &out_support_info->format_count, + 0); // Get number of formats + if (out_support_info->format_count > 0) { + vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &out_support_info->format_count, + out_support_info->formats); + } + + // Present Modes + vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &out_support_info->mode_count, + 0); // Get number of formats + if (out_support_info->mode_count > 0) { + vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &out_support_info->mode_count, + out_support_info->present_modes); + } +} + +static bool physical_device_meets_requirements( + VkPhysicalDevice device, VkSurfaceKHR surface, const VkPhysicalDeviceProperties* properties, + const VkPhysicalDeviceFeatures* features, + const vulkan_physical_device_requirements* requirements, + vulkan_physical_device_queue_family_info* out_queue_info, + vulkan_swapchain_support_info* out_swapchain_support) { + // TODO: pass in an arena + + out_queue_info->graphics_family_index = -1; + out_queue_info->present_family_index = -1; + out_queue_info->compute_family_index = -1; + out_queue_info->transfer_family_index = -1; + + if (requirements->discrete_gpu) { + if (properties->deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { + TRACE("Device is not a physical GPU. Skipping."); + return false; + } + } + + u32 queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, 0); + VkQueueFamilyProperties queue_families[queue_family_count]; + vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families); + + INFO("Graphics | Present | Compute | Transfer | Name"); + u8 min_transfer_score = 255; + for (u32 i = 0; i < queue_family_count; i++) { + u8 current_transfer_score = 0; + + // Graphics queue + if (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { + out_queue_info->graphics_family_index = i; + current_transfer_score++; + } + + // Compute queue + if (queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) { + out_queue_info->compute_family_index = i; + current_transfer_score++; + } + + // Transfer queue + if (queue_families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) { + // always take the lowest score transfer index + if (current_transfer_score <= min_transfer_score) { + min_transfer_score = current_transfer_score; + out_queue_info->transfer_family_index = i; + } + } + + // Present Queue + VkBool32 supports_present = VK_FALSE; + vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &supports_present); + if (supports_present) { + out_queue_info->present_family_index = i; + } + } + + INFO(" %d | %d | %d | %d | %s", + out_queue_info->graphics_family_index != -1, out_queue_info->present_family_index != -1, + out_queue_info->compute_family_index != -1, out_queue_info->transfer_family_index != -1, + properties->deviceName); + TRACE("Graphics Family queue index: %d", out_queue_info->graphics_family_index); + TRACE("Present Family queue index: %d", out_queue_info->present_family_index); + TRACE("Compute Family queue index: %d", out_queue_info->compute_family_index); + TRACE("Transfer Family queue index: %d", out_queue_info->transfer_family_index); + + if ((!requirements->graphics || + (requirements->graphics && out_queue_info->graphics_family_index != -1))) { + INFO("Physical device meets our requirements! Proceed."); + + vulkan_device_query_swapchain_support( + device, surface, out_swapchain_support + + // TODO: error handling i.e. format count = 0 or present mode = 0 + + ); + return true; + } + + return false; +}
\ No newline at end of file |