From 56f641863c817af137f247a0ca4427a9d44c36e6 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Tue, 4 Oct 2022 09:34:57 -0400 Subject: [PATCH] Add basic Vulkan renderer init --- Makefile | 2 +- src/pc/gfx/gfx_vulkan.cpp | 179 +++++++++++++++++++++++++++++++++++++- src/pc/pc_main.c | 2 +- 3 files changed, 178 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 8e80b58..da1a55e 100644 --- a/Makefile +++ b/Makefile @@ -499,7 +499,7 @@ ifeq ($(ENABLE_OPENGL),1) endif ifeq ($(TARGET_LINUX),1) GFX_CFLAGS += $(shell sdl2-config --cflags) - GFX_LDFLAGS += -lGL $(shell sdl2-config --libs) -lX11 -lXrandr + GFX_LDFLAGS += -lGL $(shell sdl2-config --libs) -lX11 -lXrandr -lvulkan endif ifeq ($(TARGET_WEB),1) GFX_CFLAGS += -s USE_SDL=2 diff --git a/src/pc/gfx/gfx_vulkan.cpp b/src/pc/gfx/gfx_vulkan.cpp index b44b8f8..38c2804 100644 --- a/src/pc/gfx/gfx_vulkan.cpp +++ b/src/pc/gfx/gfx_vulkan.cpp @@ -1,10 +1,30 @@ -#ifdef ENABLE_VULKAN - #include #include +#include +#include +#include +#include #include "gfx_rendering_api.h" +static VkInstance instance; +static VkPhysicalDevice physical_device; +static VkDevice device; +static VkQueue graphics_queue; +static VkQueue present_queue; +static VkCommandPool command_pool; + +VKAPI_ATTR VkBool32 VKAPI_CALL +gfx_vulkan_debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData) { + + printf("%s\n", pCallbackData->pMessage); + + return VK_FALSE; +} + static bool gfx_vulkan_renderer_z_is_from_0_to_1(void) { return false; } @@ -63,10 +83,164 @@ static void gfx_vulkan_renderer_set_use_alpha(bool use_alpha) { static void gfx_vulkan_renderer_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) { } +static void gfx_vulkan_create_instance() { + std::vector instance_extensions = {"VK_EXT_debug_utils"}; + + uint32_t extension_count = 0; + vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr); + + std::vector extensions(extension_count); + vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()); + + for(auto& extension : extensions) { + if (strstr(extension.extensionName, "surface") != nullptr) { + instance_extensions.push_back(extension.extensionName); + } + + if (strstr(extension.extensionName, "VK_KHR_get_physical_device_properties2") != nullptr) { + instance_extensions.push_back(extension.extensionName); + } + } + + VkDebugUtilsMessengerCreateInfoEXT debug_create_info = {}; + debug_create_info.sType = + VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + debug_create_info.messageSeverity = + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + debug_create_info.messageType = + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; + debug_create_info.pfnUserCallback = gfx_vulkan_debug_callback; + + VkInstanceCreateInfo create_info = {}; + create_info.pNext = &debug_create_info; + create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + create_info.ppEnabledExtensionNames = instance_extensions.data(); + create_info.enabledExtensionCount = instance_extensions.size(); + + vkCreateInstance(&create_info, nullptr, &instance); + + printf("Created vulkan instance!\n"); +} + +static void gfx_vulkan_create_command_pool(const int graphics_family_index) { + VkCommandPoolCreateInfo pool_create_info = {}; + pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + pool_create_info.queueFamilyIndex = graphics_family_index; + pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + + vkCreateCommandPool(device, &pool_create_info, nullptr, &command_pool); +} + +static void gfx_vulkan_create_device() { + // pick physical device + uint32_t device_count = 0; + vkEnumeratePhysicalDevices(instance, &device_count, nullptr); + + std::vector devices(device_count); + vkEnumeratePhysicalDevices(instance, &device_count, devices.data()); + + for (auto device : devices) { + VkPhysicalDeviceProperties device_properties; + vkGetPhysicalDeviceProperties(device, &device_properties); + + printf("GPU Found: %s\n", device_properties.deviceName); + } + + physical_device = devices[0]; + + uint32_t extension_count = 0; + vkEnumerateDeviceExtensionProperties(physical_device, nullptr, + &extension_count, nullptr); + + std::vector extension_properties(extension_count); + vkEnumerateDeviceExtensionProperties( + physical_device, nullptr, &extension_count, + extension_properties.data()); + + uint32_t graphics_family_index = 0, present_family_index = 0; + + // create logical device + uint32_t queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, + nullptr); + + std::vector queueFamilies(queue_family_count); + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, + queueFamilies.data()); + + int i = 0; + for (const auto&queue_family : queueFamilies) { + if (queue_family.queueCount > 0 && queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) { + graphics_family_index = i; + } + + i++; + } + + std::vector queue_create_infos; + + if (graphics_family_index == present_family_index) { + VkDeviceQueueCreateInfo queue_create_info = {}; + queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info.queueFamilyIndex = graphics_family_index; + queue_create_info.queueCount = 1; + + float queuePriority = 1.0f; + queue_create_info.pQueuePriorities = &queuePriority; + + queue_create_infos.push_back(queue_create_info); + } else { + // graphics + { + VkDeviceQueueCreateInfo queue_create_info = {}; + queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info.queueFamilyIndex = graphics_family_index; + queue_create_info.queueCount = 1; + + float queuePriority = 1.0f; + queue_create_info.pQueuePriorities = &queuePriority; + + queue_create_infos.push_back(queue_create_info); + } + + // present + { + VkDeviceQueueCreateInfo queue_create_info = {}; + queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info.queueFamilyIndex = present_family_index; + queue_create_info.queueCount = 1; + + float queuePriority = 1.0f; + queue_create_info.pQueuePriorities = &queuePriority; + + queue_create_infos.push_back(queue_create_info); + } + } + + VkDeviceCreateInfo device_create_info = {}; + device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + device_create_info.pQueueCreateInfos = queue_create_infos.data(); + device_create_info.queueCreateInfoCount = + static_cast(queue_create_infos.size()); + + vkCreateDevice(physical_device, &device_create_info, nullptr, &device); + + printf("Created vulkan device!\n"); + + vkGetDeviceQueue(device, graphics_family_index, 0, &graphics_queue); + vkGetDeviceQueue(device, present_family_index, 0, &present_queue); + + gfx_vulkan_create_command_pool(graphics_family_index); +} + static void gfx_vulkan_renderer_init(void) { + gfx_vulkan_create_instance(); + gfx_vulkan_create_device(); } static void gfx_vulkan_renderer_on_resize(void) { + // doesn't seem to be called? } static void gfx_vulkan_renderer_start_frame(void) { @@ -107,4 +281,3 @@ struct GfxRenderingAPI gfx_vulkan_api = { gfx_vulkan_renderer_finish_render, gfx_vulkan_get_name, }; -#endif diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index 44a2310..0c53f17 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -166,7 +166,7 @@ void main_func(void) { rendering_api = &gfx_direct3d11_api; wm_api = &gfx_dxgi_api; #elif defined(ENABLE_OPENGL) - rendering_api = &gfx_opengl_api; + rendering_api = &gfx_vulkan_api; wm_api = &gfx_sdl; #elif defined(ENABLE_GFX_DUMMY) rendering_api = &gfx_dummy_renderer_api;