summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-10-21 12:56:07 +0300
committerkartofen <mladenovnasko0@gmail.com>2023-10-21 12:56:07 +0300
commitff2497dc2c67d2b7df29b729c763b6e09c876d76 (patch)
treea83f5dcb96066e700da914d222732aad1ed1c5f7
parent5115eb592d1477b355770eee9d6b913481d4859f (diff)
minor changes and more error checks
-rw-r--r--src/common.h2
-rw-r--r--src/device.c247
-rw-r--r--src/window.c8
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;
}