#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; } static void gfx_vulkan_renderer_unload_shader(struct ShaderProgram *old_prg) { } static void gfx_vulkan_renderer_load_shader(struct ShaderProgram *new_prg) { } static struct ShaderProgram *gfx_vulkan_renderer_create_and_load_new_shader(uint32_t shader_id) { return NULL; } static struct ShaderProgram *gfx_vulkan_renderer_lookup_shader(uint32_t shader_id) { return NULL; } static void gfx_vulkan_renderer_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) { *num_inputs = 0; used_textures[0] = false; used_textures[1] = false; } static uint32_t gfx_vulkan_renderer_new_texture(void) { return 0; } static void gfx_vulkan_renderer_select_texture(int tile, uint32_t texture_id) { } static void gfx_vulkan_renderer_upload_texture(const uint8_t *rgba32_buf, int width, int height) { } static void gfx_vulkan_renderer_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) { } static void gfx_vulkan_renderer_set_depth_test(bool depth_test) { } static void gfx_vulkan_renderer_set_depth_mask(bool z_upd) { } static void gfx_vulkan_renderer_set_zmode_decal(bool zmode_decal) { } static void gfx_vulkan_renderer_set_viewport(int x, int y, int width, int height) { } static void gfx_vulkan_renderer_set_scissor(int x, int y, int width, int height) { } 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) { } static void gfx_vulkan_renderer_end_frame(void) { } static void gfx_vulkan_renderer_finish_render(void) { } static const char* gfx_vulkan_get_name() { return "Vulkan"; } struct GfxRenderingAPI gfx_vulkan_api = { gfx_vulkan_renderer_z_is_from_0_to_1, gfx_vulkan_renderer_unload_shader, gfx_vulkan_renderer_load_shader, gfx_vulkan_renderer_create_and_load_new_shader, gfx_vulkan_renderer_lookup_shader, gfx_vulkan_renderer_shader_get_info, gfx_vulkan_renderer_new_texture, gfx_vulkan_renderer_select_texture, gfx_vulkan_renderer_upload_texture, gfx_vulkan_renderer_set_sampler_parameters, gfx_vulkan_renderer_set_depth_test, gfx_vulkan_renderer_set_depth_mask, gfx_vulkan_renderer_set_zmode_decal, gfx_vulkan_renderer_set_viewport, gfx_vulkan_renderer_set_scissor, gfx_vulkan_renderer_set_use_alpha, gfx_vulkan_renderer_draw_triangles, gfx_vulkan_renderer_init, gfx_vulkan_renderer_on_resize, gfx_vulkan_renderer_start_frame, gfx_vulkan_renderer_end_frame, gfx_vulkan_renderer_finish_render, gfx_vulkan_get_name, };