diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..aa6ce99 --- /dev/null +++ b/src/main.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "list.h" +#include "debug.h" + +#define APPNAME "VulkanApp" +const char* appName = APPNAME; +const VkApplicationInfo appInfo = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pApplicationName = APPNAME, + .applicationVersion = VK_MAKE_VERSION(0, 0, 1), + .pEngineName = "No Engine", + .engineVersion = VK_MAKE_VERSION(0, 0, 1), + .apiVersion = VK_API_VERSION_1_0, + + .pNext = NULL +}; + +typedef struct VkContext { + SDL_Window* window; + VkInstance instance; + VkPhysicalDevice device; + uint32_t queueFamilyIndexes; + uint32_t queueFamilyCount; +} AppContext; + +void quit(AppContext* context) { + vkDestroyInstance(context->instance, NULL); + SDL_DestroyWindow(context->window); + SDL_Quit(); + exit(0); +} + +void loop(AppContext* context) { + SDL_Event event; + while(1) { + SDL_PollEvent(&event); + if(event.type == SDL_QUIT) + quit(context); + } +} + +void get_extensions(AppContext* context, List* out) { + unsigned extCount = 10; + const char* vkExtensions[10]; + if(!SDL_Vulkan_GetInstanceExtensions(context->window, &extCount, vkExtensions)) { + LOG_WARNING("Failed to fetch vulkan instance extensions '%s'", SDL_GetError()); + } + LOG_INFO("Fetched %u vulkan extensions", extCount); + for(unsigned i = 0; i < extCount; ++i) + list_add(out, vkExtensions + i); +} + +void create_instance(AppContext* context) { + List extensions = list_from_type(char*); + get_extensions(context, &extensions); + VkInstanceCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pNext = NULL, + .flags = 0, + .pApplicationInfo = &appInfo, + .enabledLayerCount = 0, + .ppEnabledLayerNames = NULL, + .enabledExtensionCount = extensions.len, + .ppEnabledExtensionNames = extensions.data, + }; + if(vkCreateInstance(&createInfo, NULL, &context->instance) != VK_SUCCESS) { + abort(); + } + list_empty(&extensions); +} + +void create_window(AppContext* context) { + context->window = SDL_CreateWindow( + appName, + SDL_WINDOWPOS_CENTERED_DISPLAY(0), + SDL_WINDOWPOS_CENTERED_DISPLAY(0), + 1920, 1080, + SDL_WINDOW_VULKAN | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_SHOWN + ); + if(!context->window) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", SDL_GetError()); + abort(); + } +} + +int gpu_usable(VkPhysicalDevice device) { + VkPhysicalDeviceProperties devProps; + vkGetPhysicalDeviceProperties(device, &devProps); + VkPhysicalDeviceFeatures devFeats; + vkGetPhysicalDeviceFeatures(device, &devFeats); + return (devProps.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU || VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) + && (devFeats.geometryShader); +} + +void select_physical_device(AppContext* context) { + uint32_t numDevices = 0; + vkEnumeratePhysicalDevices(context->instance, &numDevices, NULL); + ASSERT_RETURN(numDevices != 0,, "Could not find any vulkan graphics devices"); + List devices = list_from_type(numDevices); + list_reserve(&devices, numDevices); + devices.len = numDevices; + vkEnumeratePhysicalDevices(context->instance, &numDevices, devices.data); + list_foreach(VkPhysicalDevice*, device, &devices) { + if(gpu_usable(*device)) { + context->device = *device; + break; + } + } + list_empty(&devices); + ASSERT_RETURN(context->device != VK_NULL_HANDLE,, "Could not find suitable graphics device"); +} + +void find_queue_families(AppContext* context) { + +} + +int main(int argc, char* argv[]) { + if(SDL_Init(SDL_INIT_VIDEO) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", SDL_GetError()); + abort(); + } + AppContext context = { + .window = NULL, + .instance = VK_NULL_HANDLE, + .device = VK_NULL_HANDLE, + }; + create_window(&context); + create_instance(&context); + select_physical_device(&context); + find_queue_families(&context); + loop(&context); + return -1; +}