summaryrefslogtreecommitdiff
path: root/src/renderer/backends/vulkan_helpers.h
diff options
context:
space:
mode:
authoromnisci3nce <17525998+omnisci3nce@users.noreply.github.com>2024-04-04 20:25:40 +1100
committeromnisci3nce <17525998+omnisci3nce@users.noreply.github.com>2024-04-04 20:25:40 +1100
commitbb889d2edc1cc72b939edf47a2e03b7569c1a722 (patch)
tree59b7744d44bda7768ba908224a18d6a5046b186f /src/renderer/backends/vulkan_helpers.h
parent1047d08258f6c56f5fa8067cc65694b1b5798602 (diff)
parent6a95b047998c0e0dcfdf60d17cf2cd0bd0bfee12 (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.h166
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