diff options
author | kartofen <mladenovnasko0@gmail.com> | 2023-10-21 12:56:07 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2023-10-21 12:56:07 +0300 |
commit | ff2497dc2c67d2b7df29b729c763b6e09c876d76 (patch) | |
tree | a83f5dcb96066e700da914d222732aad1ed1c5f7 | |
parent | 5115eb592d1477b355770eee9d6b913481d4859f (diff) |
minor changes and more error checks
-rw-r--r-- | src/common.h | 2 | ||||
-rw-r--r-- | src/device.c | 247 | ||||
-rw-r--r-- | src/window.c | 8 |
3 files changed, 144 insertions, 113 deletions
diff --git a/src/common.h b/src/common.h index 27d8404..eaa0743 100644 --- a/src/common.h +++ b/src/common.h @@ -51,7 +51,7 @@ void *xrealloc(void *ptr, size_t size); fseek(fp, 0, SEEK_SET); \ fread(buf, sizeof(u32), *size/sizeof(u32), fp); \ \ - return 0; \ + ret = 0; \ exit: \ fclose(fp); \ return ret; \ diff --git a/src/device.c b/src/device.c index a200e5e..f85b1a6 100644 --- a/src/device.c +++ b/src/device.c @@ -10,11 +10,21 @@ // TODO: add log output // TODO: check for memory leaks +#define SWAP_CHAIN_IMAGES 3 + #define CLAMP(val, min, max) (((val) < (min)) ? (min) : ((val) > (max) ? (max) : (val))) #define ECHECK(f, ...) if(f(__VA_ARGS__) != 0) { err(#f ": failed"); goto exit; } #define FCHECK(f, ...) if(f(__VA_ARGS__) != 0) { err(#f ": failed"); goto fail; } +#define VCHECK(f, ...) \ + do { \ + VkResult res; \ + if((res = f(__VA_ARGS__)) != VK_SUCCESS) { \ + err(#f ": %s", str_VkResult(res)); \ + goto exit; } \ + } while(0) + #ifdef DEBUG char *validation_layers[] = { "VK_LAYER_KHRONOS_validation" @@ -52,13 +62,14 @@ static int create_surface(device_t device, struct device_info *info); static int create_physical_device(device_t device, struct device_info *info); static int create_logical_device(device_t device, struct device_info *info); static int create_swap_chain(device_t device, struct device_info *info); -static int create_render_pass(device_t device, struct device_info *info); static int create_pipeline(device_t device, struct device_info *info); static void destroy_swap_chain(device_t device); static void destroy_pipeline(device_t device); // --- Helper Function --- +static char *str_VkResult(VkResult result); + static bool device_is_suitable(VkPhysicalDevice phy_device, VkSurfaceKHR surface); static bool device_has_extension_support(VkPhysicalDevice phy_device); static int device_queue_families(VkPhysicalDevice phy_device, VkSurfaceKHR surface, struct queue_family_idx *queue_family); @@ -107,12 +118,13 @@ device_t device_create(struct device_info *info) device_t device = xmalloc(sizeof(struct device)); device->instance = VK_NULL_HANDLE; device->logical_device = VK_NULL_HANDLE; - - PPLN.pipeline = VK_NULL_HANDLE; - PPLN.layout = VK_NULL_HANDLE; SWCH.swap_chain = VK_NULL_HANDLE; SWCH.nimages = 0; + + PPLN.pipeline = VK_NULL_HANDLE; + PPLN.layout = VK_NULL_HANDLE; + PPLN.render_pass = VK_NULL_HANDLE; CCHECK(create_instance); CCHECK(create_surface); @@ -122,7 +134,6 @@ device_t device_create(struct device_info *info) CCHECK(create_physical_device); CCHECK(create_logical_device); CCHECK(create_swap_chain); - CCHECK(create_render_pass); CCHECK(create_pipeline); return device; @@ -166,11 +177,14 @@ static int create_instance(device_t device, struct device_info *info) VkInstanceCreateInfo create_info = {0}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.pApplicationInfo = &app_info; + + + create_info.enabledLayerCount = 0; #ifdef DEBUG // add debug utils extensions for debug callback - char **extensions = xcalloc(info->ext_count+1, sizeof(char *)); + char **extensions = xcalloc(info->ext_count+1, sizeof(*extensions)); extensions[info->ext_count] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; for(u32 i = 0; i < info->ext_count; i++) { @@ -196,18 +210,17 @@ static int create_instance(device_t device, struct device_info *info) debug_messenger_populate_info(&msg_info); create_info.pNext = &msg_info; -#endif - - if(vkCreateInstance(&create_info, NULL, &device->instance) != VK_SUCCESS) { - err("vkCreateInstance: failed"); - goto exit; - } +#else + create_info.enabledExtensionCount = info->ext_count; + create_info.ppEnabledExtensionNames = (const char * const *)info->extensions; + create_info.enabledLayerCount = 0; +#endif + VCHECK(vkCreateInstance, &create_info, NULL, &device->instance); ret = 0; exit: - #ifdef DEBUG free(extensions); #endif @@ -239,7 +252,7 @@ static int create_physical_device(device_t device, struct device_info *info) goto exit; } - VkPhysicalDevice *devices = xcalloc(dev_count, sizeof(VkPhysicalDevice)); + VkPhysicalDevice *devices = xcalloc(dev_count, sizeof(*devices)); vkEnumeratePhysicalDevices(device->instance, &dev_count, devices); for(u32 i = 0; i < dev_count; i++) { @@ -270,20 +283,17 @@ static int create_logical_device(device_t device, struct device_info *info) struct queue_family_idx indices = {0}; device_queue_families(device->physical_device, device->surface, &indices); - // queue infos - #define QUEUE_FAMILY_COUNT 2 - - VkDeviceQueueCreateInfo queue_infos[QUEUE_FAMILY_COUNT] = {0}; - u32 queue_indices[QUEUE_FAMILY_COUNT] = { + // queue infos + u32 unique_queue_family_count = 0; + u32 queue_indices[] = { indices.graphics_family, indices.present_family, }; - - u32 unique_queue_family_count = 0; + + VkDeviceQueueCreateInfo queue_infos[ARR_SIZE(queue_indices)] = {0}; float queue_priority = 1.0f; - - // basically get add only the unique queue families - for(size_t i = 0; i < QUEUE_FAMILY_COUNT; i++) + // basically get only the unique queue families + for(size_t i = 0; i < ARR_SIZE(queue_indices); i++) { bool unique = true; for(size_t j = 0; j < i; j++) { @@ -323,10 +333,7 @@ static int create_logical_device(device_t device, struct device_info *info) // so i wont bother adding them create_info.enabledLayerCount = 0; - if(vkCreateDevice(device->physical_device, &create_info, NULL, &device->logical_device) != VK_SUCCESS) { - err("vkCreateDevice: failed"); - goto exit; - } + VCHECK(vkCreateDevice, device->physical_device, &create_info, NULL, &device->logical_device); vkGetDeviceQueue(device->logical_device, indices.graphics_family, 0, &device->graphics_queue); vkGetDeviceQueue(device->logical_device, indices.present_family, 0, &device->present_queue); @@ -338,17 +345,16 @@ exit: static int create_swap_chain(device_t device, struct device_info *info) { - (void)info; int ret = 1; - struct swap_chain_support_details details; + struct swap_chain_support_details details = {0}; swap_chain_support(device->physical_device, device->surface, &details); VkSurfaceFormatKHR surface_format; VkPresentModeKHR present_mode; VkExtent2D extent; - u32 image_count = 3; + u32 image_count = SWAP_CHAIN_IMAGES; swap_chain_choose_format(details.formats, details.nformats, &surface_format); swap_chain_choose_present_mode(details.present_modes, details.npresent_modes, &present_mode); @@ -370,15 +376,15 @@ static int create_swap_chain(device_t device, struct device_info *info) create_info.imageArrayLayers = 1; create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - struct queue_family_idx indices; + struct queue_family_idx indices = {0}; device_queue_families(device->physical_device, device->surface, &indices); - u32 queue_indices[2] = { indices.graphics_family, indices.present_family }; + u32 queue_indices[] = { indices.graphics_family, indices.present_family }; // set the sharing mode of the images if(indices.graphics_family != indices.present_family) { create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; - create_info.queueFamilyIndexCount = 2; + create_info.queueFamilyIndexCount = ARR_SIZE(queue_indices); create_info.pQueueFamilyIndices = queue_indices; } else { create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; @@ -394,11 +400,9 @@ static int create_swap_chain(device_t device, struct device_info *info) create_info.oldSwapchain = NULL; - if (vkCreateSwapchainKHR(device->logical_device, &create_info, NULL, &SWCH.swap_chain) != VK_SUCCESS) { - err("Couldn't create a Swapchain"); - goto exit; - } + VCHECK(vkCreateSwapchainKHR, device->logical_device, &create_info, NULL, &SWCH.swap_chain); + // Get the Images SWCH.image_format = surface_format.format; SWCH.extent = extent; @@ -429,10 +433,7 @@ static int create_swap_chain(device_t device, struct device_info *info) create_info.subresourceRange.baseArrayLayer = 0; create_info.subresourceRange.layerCount = 1; - if(vkCreateImageView(device->logical_device, &create_info, NULL, &SWCH.image_views[i]) != VK_SUCCESS) { - err("Couldn't create image view"); - goto exit; - } + VCHECK(vkCreateImageView, device->logical_device, &create_info, NULL, &SWCH.image_views[i]); } ret = 0; @@ -446,6 +447,7 @@ static void destroy_swap_chain(device_t device) for(u32 i = 0; i < SWCH.nimages; i++) { vkDestroyImageView(device->logical_device, SWCH.image_views[i], NULL); } + if(SWCH.nimages != 0) { free(SWCH.images); free(SWCH.image_views); @@ -454,52 +456,12 @@ static void destroy_swap_chain(device_t device) vkDestroySwapchainKHR(device->logical_device, SWCH.swap_chain, NULL); } -static int create_render_pass(device_t device, struct device_info *info) -{ - (void)info; - int ret = 1; - - VkAttachmentDescription color_attachment = {0}; - color_attachment.format = SWCH.image_format; - color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; - color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - VkAttachmentReference color_attachment_ref = {0}; - color_attachment_ref.attachment = 0; - color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {0}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &color_attachment_ref; - - VkRenderPassCreateInfo render_pass_info = {0}; - render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - render_pass_info.attachmentCount = 1; - render_pass_info.pAttachments = &color_attachment; - render_pass_info.subpassCount = 1; - render_pass_info.pSubpasses = &subpass; - - if (vkCreateRenderPass(device->logical_device, &render_pass_info, NULL, &PPLN.render_pass) != VK_SUCCESS) { - err("Couldnt create a render pass"); - goto exit; - } - - ret = 0; -exit: - return ret; -} - static int create_pipeline(device_t device, struct device_info *info) { (void)info; int ret = 1; + // Shader Things VkShaderModule vert_shader = VK_NULL_HANDLE; VkShaderModule frag_shader = VK_NULL_HANDLE; @@ -518,10 +480,11 @@ static int create_pipeline(device_t device, struct device_info *info) frag_stage.module = frag_shader; frag_stage.pName = "main"; - VkPipelineShaderStageCreateInfo shader_stages[2] = { vert_stage, frag_stage }; + VkPipelineShaderStageCreateInfo shader_stages[] = { vert_stage, frag_stage }; - VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; - + VkDynamicState dynamic_states[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + + // A Bunch of other things for the pipeline VkPipelineDynamicStateCreateInfo dynamic_state = {0}; dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamic_state.dynamicStateCount = ARR_SIZE(dynamic_states); @@ -601,6 +564,7 @@ static int create_pipeline(device_t device, struct device_info *info) color_blend.blendConstants[2] = 0.0f; // Optional color_blend.blendConstants[3] = 0.0f; // Optional + // Create Pipeline Layout VkPipelineLayoutCreateInfo pipeline_layout_info = {0}; pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeline_layout_info.setLayoutCount = 0; // Optional @@ -608,10 +572,38 @@ static int create_pipeline(device_t device, struct device_info *info) pipeline_layout_info.pushConstantRangeCount = 0; // Optional pipeline_layout_info.pPushConstantRanges = NULL; // Optional - if(vkCreatePipelineLayout(device->logical_device, &pipeline_layout_info, NULL, &PPLN.layout) != VK_SUCCESS) { - goto exit; - } + VCHECK(vkCreatePipelineLayout, device->logical_device, &pipeline_layout_info, NULL, &PPLN.layout); + + // Create Render Pass + VkAttachmentDescription color_attachment = {0}; + color_attachment.format = SWCH.image_format; + color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; + color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + VkAttachmentReference color_attachment_ref = {0}; + color_attachment_ref.attachment = 0; + color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass = {0}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &color_attachment_ref; + + VkRenderPassCreateInfo render_pass_info = {0}; + render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_info.attachmentCount = 1; + render_pass_info.pAttachments = &color_attachment; + render_pass_info.subpassCount = 1; + render_pass_info.pSubpasses = &subpass; + + VCHECK(vkCreateRenderPass, device->logical_device, &render_pass_info, NULL, &PPLN.render_pass); + + // Finally Create the Pipeline VkGraphicsPipelineCreateInfo pipeline_info = {0}; pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipeline_info.stageCount = 2; @@ -633,17 +625,12 @@ static int create_pipeline(device_t device, struct device_info *info) pipeline_info.basePipelineHandle = VK_NULL_HANDLE; // Optional pipeline_info.basePipelineIndex = -1; // Optional - if(vkCreateGraphicsPipelines(device->logical_device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &PPLN.pipeline) != VK_SUCCESS) { - err("Couldnt create a graphics pipeline"); - goto exit; - } + VCHECK(vkCreateGraphicsPipelines, device->logical_device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &PPLN.pipeline); ret = 0; exit: - if(frag_shader != VK_NULL_HANDLE) - vkDestroyShaderModule(device->logical_device, frag_shader, NULL); - if(vert_shader != VK_NULL_HANDLE) - vkDestroyShaderModule(device->logical_device, vert_shader, NULL); + vkDestroyShaderModule(device->logical_device, frag_shader, NULL); + vkDestroyShaderModule(device->logical_device, vert_shader, NULL); return ret; } @@ -659,7 +646,7 @@ static int device_queue_families(VkPhysicalDevice phy_device, VkSurfaceKHR surfa u32 count = 0; vkGetPhysicalDeviceQueueFamilyProperties(phy_device, &count, NULL); - VkQueueFamilyProperties *properties = xcalloc(count, sizeof(VkQueueFamilyProperties)); + VkQueueFamilyProperties *properties = xcalloc(count, sizeof(*properties)); vkGetPhysicalDeviceQueueFamilyProperties(phy_device, &count, properties); for(u32 i = 0; i < count; i++) { @@ -699,10 +686,12 @@ static bool device_is_suitable(VkPhysicalDevice phy_device, VkSurfaceKHR surface static bool device_has_extension_support(VkPhysicalDevice phy_device) { + bool ret = false; + u32 count = 0; vkEnumerateDeviceExtensionProperties(phy_device, NULL, &count, NULL); - VkExtensionProperties *properties = xcalloc(count, sizeof(VkExtensionProperties)); + VkExtensionProperties *properties = xcalloc(count, sizeof(*properties)); vkEnumerateDeviceExtensionProperties(phy_device, NULL, &count, properties); for(size_t i = 0; i < ARR_SIZE(device_extensions); i++) @@ -711,16 +700,18 @@ static bool device_has_extension_support(VkPhysicalDevice phy_device) for(u32 j = 0; j < count; j++) if(strncmp(device_extensions[i], properties[j].extensionName, 256) == 0) { present = true; + break; } if(!present) { - free(properties); - return false; + goto exit; } } + ret = true; +exit: free(properties); - return true; + return ret; } static int swap_chain_support(VkPhysicalDevice phy_device, VkSurfaceKHR surface, struct swap_chain_support_details *details) @@ -801,10 +792,7 @@ static int pipeline_load_shader_module(VkDevice device, char *path, VkShaderModu create_info.codeSize = size; create_info.pCode = buf; - if (vkCreateShaderModule(device, &create_info, NULL, module) != VK_SUCCESS) { - err("Couldnt create shader module"); - goto exit; - } + VCHECK(vkCreateShaderModule, device, &create_info, NULL, module); ret = 0; exit: @@ -812,6 +800,43 @@ exit: return ret; } +#define X_VK_RESULT_TABLE(X) \ + X(VK_SUCCESS) \ + X(VK_NOT_READY) \ + X(VK_TIMEOUT) \ + X(VK_EVENT_SET) \ + X(VK_EVENT_RESET) \ + X(VK_INCOMPLETE) \ + X(VK_ERROR_OUT_OF_HOST_MEMORY) \ + X(VK_ERROR_OUT_OF_DEVICE_MEMORY) \ + X(VK_ERROR_INITIALIZATION_FAILED) \ + X(VK_ERROR_DEVICE_LOST) \ + X(VK_ERROR_MEMORY_MAP_FAILED) \ + X(VK_ERROR_LAYER_NOT_PRESENT) \ + X(VK_ERROR_EXTENSION_NOT_PRESENT) \ + X(VK_ERROR_FEATURE_NOT_PRESENT) \ + X(VK_ERROR_INCOMPATIBLE_DRIVER) \ + X(VK_ERROR_TOO_MANY_OBJECTS) \ + X(VK_ERROR_FORMAT_NOT_SUPPORTED) \ + X(VK_ERROR_FRAGMENTED_POOL) \ + X(VK_ERROR_UNKNOWN) \ + X(VK_ERROR_OUT_OF_POOL_MEMORY) \ + X(VK_ERROR_INVALID_EXTERNAL_HANDLE) \ + X(VK_ERROR_FRAGMENTATION) \ + X(VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS) \ + +#define X_VK_RESULT_CASE(error) \ + case error: return #error; + +static char *str_VkResult(VkResult result) +{ + switch(result) { + X_VK_RESULT_TABLE(X_VK_RESULT_CASE) + default: + return "VK_ERROR_OTHER"; + } +} + #ifdef DEBUG static bool instance_has_validation_layers(const char * const *layers, u32 nlayers) @@ -830,16 +855,16 @@ static bool instance_has_validation_layers(const char * const *layers, u32 nlaye static int create_debug_messenger(device_t device, struct device_info *info) { (void)info; + int ret = 1; VkDebugUtilsMessengerCreateInfoEXT cinfo = {0}; debug_messenger_populate_info(&cinfo); - if(CreateDebugUtilsMessengerEXT(device->instance, &cinfo, NULL, &device->debug_messenger) != VK_SUCCESS) { - info("CreateDebugUtilMessengerEXT: failed"); - return 1; - } + VCHECK(CreateDebugUtilsMessengerEXT, device->instance, &cinfo, NULL, &device->debug_messenger); - return 0; + ret = 0; +exit: + return ret; } static void debug_messenger_populate_info(VkDebugUtilsMessengerCreateInfoEXT *info) diff --git a/src/window.c b/src/window.c index 4a498e6..9810a42 100644 --- a/src/window.c +++ b/src/window.c @@ -3,11 +3,15 @@ window_t window_create(struct window_info *info) { - info->flags |= SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN; + info->flags |= SDL_WINDOW_VULKAN; SDL_Vulkan_LoadLibrary(NULL); window_t window = SDL_CreateWindow(info->title, info->x, info->y, info->w, info->h, info->flags); + if(window == NULL) { + err("SDL_CreateWindow: failed"); + } + return window; } @@ -20,6 +24,7 @@ void window_destroy(window_t window) int window_extension_info(window_t window, unsigned int *ext_count, const char **extensions) { if(SDL_Vulkan_GetInstanceExtensions((SDL_Window *)window, ext_count, extensions) == SDL_FALSE) { + err("SDL_Vulkan_GetInstanceExtensions: failed"); return 1; } @@ -29,6 +34,7 @@ int window_extension_info(window_t window, unsigned int *ext_count, const char * int window_create_surface(window_t window, VkInstance instance, VkSurfaceKHR *surface) { if(SDL_Vulkan_CreateSurface((SDL_Window *)window, instance, surface) == SDL_FALSE) { + err("SDL_Vulkan_CreateSurface: failed"); return 1; } |