123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #define IMPORT_CORE
- #include "core/VulkanWrapper.h"
- #define GLFW_INCLUDE_VULKAN
- #include <GLFW/glfw3.h>
- #include <core/Logger.h>
- #include <core/Utility.h>
- #include <limits.h>
- #include <stdio.h>
- #include <uchar.h>
- typedef struct {
- VkInstance instance;
- VkPhysicalDevice physicalDevice;
- VkDevice device;
- } VulkanData;
- static VulkanData vk = {0};
- #define VK_ERROR_CASE(error) \
- case error: return #error
- static const char* getVulkanErrorString(VkResult r) {
- switch(r) {
- VK_ERROR_CASE(VK_ERROR_OUT_OF_HOST_MEMORY);
- VK_ERROR_CASE(VK_ERROR_OUT_OF_DEVICE_MEMORY);
- VK_ERROR_CASE(VK_ERROR_INITIALIZATION_FAILED);
- VK_ERROR_CASE(VK_ERROR_LAYER_NOT_PRESENT);
- VK_ERROR_CASE(VK_ERROR_EXTENSION_NOT_PRESENT);
- VK_ERROR_CASE(VK_ERROR_INCOMPATIBLE_DRIVER);
- default: return "unknown";
- }
- }
- #define VK_ASSERT(a) \
- do { \
- VkResult vkResult = (a); \
- if(vkResult != VK_SUCCESS) { \
- printf("Vulkan error at [%s:%d]: %s\n", \
- getShortFileName(__FILE__), __LINE__, \
- getVulkanErrorString(vkResult)); \
- return true; \
- } \
- } while(false)
- static bool initInstance() {
- VkApplicationInfo i = {.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
- .pApplicationName = "Vulkan",
- .applicationVersion = VK_MAKE_VERSION(1, 0, 0),
- .pEngineName = "Kajetan",
- .engineVersion = VK_MAKE_VERSION(0, 0, 1),
- .apiVersion = VK_API_VERSION_1_1};
- VkInstanceCreateInfo ci = {
- .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
- .pApplicationInfo = &i,
- .enabledLayerCount = 1,
- .ppEnabledLayerNames = (const char*[]){"VK_LAYER_KHRONOS_validation"},
- .enabledExtensionCount = 4,
- .ppEnabledExtensionNames =
- (const char*[]){"VK_KHR_surface", "VK_KHR_xcb_surface",
- VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
- VK_EXT_DEBUG_REPORT_EXTENSION_NAME}};
- VK_ASSERT(vkCreateInstance(&ci, nullptr, &vk.instance));
- return false;
- }
- static bool choosePhysicalDevice(VkPhysicalDevice* devices, u32 amount) {
- VK_ASSERT(vkEnumeratePhysicalDevices(vk.instance, &amount, devices));
- int bestPoints = 0;
- LOG_INFO("Found %u devices", amount);
- for(u32 i = 0; i < amount; i++) {
- int points = 0;
- VkPhysicalDeviceProperties p;
- vkGetPhysicalDeviceProperties(devices[i], &p);
- if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
- points += 100;
- } else if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
- points += 50;
- } else if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
- points += 20;
- }
- if(points > bestPoints) {
- bestPoints = points;
- vk.physicalDevice = devices[i];
- LOG_INFO("Best Device: %s", p.deviceName);
- }
- }
- return bestPoints == 0;
- }
- static bool initPhysicalDevice() {
- u32 deviceCount = 0;
- VK_ASSERT(vkEnumeratePhysicalDevices(vk.instance, &deviceCount, nullptr));
- if(deviceCount == 0) {
- LOG_ERROR("No physical device was found");
- return true;
- }
- VkPhysicalDevice* devices =
- cAllocate(sizeof(VkPhysicalDevice) * deviceCount);
- bool r = choosePhysicalDevice(devices, deviceCount);
- cFree(devices);
- return r;
- }
- static u32 findQueueFamilies(VkPhysicalDevice pd, VkQueueFlags flags) {
- u32 count = 0;
- vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, nullptr);
- VkQueueFamilyProperties* properties =
- cAllocate(sizeof(VkQueueFamilyProperties) * count);
- vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, properties);
- for(u32 i = 0; i < count; i++) {
- if(properties[i].queueCount != 0 &&
- (properties[i].queueFlags & flags) == flags) {
- cFree(properties);
- return i;
- }
- }
- cFree(properties);
- return (u32)-1;
- }
- static bool initDevice() {
- VkPhysicalDeviceFeatures deviceFeatures = {0};
- vkGetPhysicalDeviceFeatures(vk.physicalDevice, &deviceFeatures);
- u32 graphicsFamily =
- findQueueFamilies(vk.physicalDevice, VK_QUEUE_GRAPHICS_BIT);
- if(graphicsFamily == (u32)-1) {
- LOG_ERROR("Cannot find queue family");
- return true;
- }
- VkDeviceQueueCreateInfo dqInfo = {
- .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
- .queueFamilyIndex = graphicsFamily,
- .queueCount = 1,
- .pQueuePriorities = (float[]){1.0f}};
- VkDeviceCreateInfo deviceCreateInfo = {
- .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- .queueCreateInfoCount = 1,
- .pQueueCreateInfos = &dqInfo,
- .enabledExtensionCount = 1,
- .ppEnabledExtensionNames =
- (const char*[]){VK_KHR_SWAPCHAIN_EXTENSION_NAME},
- .pEnabledFeatures = &deviceFeatures};
- VK_ASSERT(vkCreateDevice(vk.physicalDevice, &deviceCreateInfo, nullptr,
- &vk.device));
- return false;
- }
- bool coreInitVulkan() {
- return initInstance() || initPhysicalDevice() || initDevice();
- }
- void coreDestroyVulkan(void) {
- vkDestroyDevice(vk.device, nullptr);
- vkDestroyInstance(vk.instance, nullptr);
- }
|