diff --git a/src/dyn_arr.c b/src/dyn_arr.c new file mode 100644 index 0000000..53aa893 --- /dev/null +++ b/src/dyn_arr.c @@ -0,0 +1,74 @@ +// Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c +#include "dyn_arr.h" +#include +#include +#include + +#define ARRAY_GROWTH_MULTIPLIER 1.3 + +void *dyn_arr_init(size_t item_size, size_t capacity) { + void *dyna_ptr = NULL; + size_t size = item_size * capacity + sizeof(dyna_header); + dyna_header *header = malloc(size); + + if (header) { + header->capacity = capacity; + header->length = 0; + dyna_ptr = header + 1; + } + + return dyna_ptr; +} + +void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size) { + dyna_header *header = dyna_get_header(array); + size_t minimum_capacity = header->length + item_count; + + if (header->capacity > minimum_capacity) { + return header + 1; + } + + size_t new_capacity = header->capacity * ARRAY_GROWTH_MULTIPLIER; + while (new_capacity < minimum_capacity) { + new_capacity *= ARRAY_GROWTH_MULTIPLIER; + } + + size_t new_size = sizeof(dyna_header) + new_capacity * item_size; + header = realloc(header, new_size); + header->capacity = new_capacity; + return header + 1; +} + +void dyn_arr_pop(void *array, size_t item_size) { + if (dyna_empty(array)) { + return; + } + + dyna_length(array)--; + + // Shrink if smaller than growth factor, may break if growth factor is > 2 + if (dyna_length(array) > + (2 - ARRAY_GROWTH_MULTIPLIER) * dyna_capacity(array)) { + return; + } + + size_t new_capacity = dyna_length(array) * ARRAY_GROWTH_MULTIPLIER; + dyna_capacity(array) = new_capacity; + + size_t new_size = sizeof(dyna_header) + new_capacity * item_size; + dyna_header *header = dyna_get_header(array); + header = realloc(dyna_get_header(array), new_size); +} + +void dyna_deinit(void *array) { + dyna_header *header = dyna_get_header(array); + header = NULL; + free(dyna_get_header(array)); +} + +bool dyna_empty(void *array) { + if (dyna_length(array) == 0) { + return true; + } + return false; +} diff --git a/src/dyn_arr.h b/src/dyn_arr.h new file mode 100644 index 0000000..2927251 --- /dev/null +++ b/src/dyn_arr.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +#define ARRAY_INITIAL_CAPACITY 4 + +/* TODO: + * Functions to implement to match what I want: + * - Capacity + * - shrink capacity to size + * - Modifiers + * - clear aka erase + * - insert + * - (optional) insert range + * - pop + * - (optional) swap + * - (optional) resize + * - Sanity checks + * - Check data going into array is the right size + * - see if possible to check entered data is correct type + */ + +typedef struct dyna_header { + size_t capacity; + size_t length; +} dyna_header; + +// Initialisation +#define dyna_init(T) (T *)dyn_arr_init(sizeof(T), ARRAY_INITIAL_CAPACITY) +void *dyn_arr_init(size_t item_size, size_t capacity); + +// Modification +#define dyna_append(array, value) \ + ((array) = dyna_ensure_capacity(array, 1, sizeof(value)), \ + (array)[dyna_get_header(array)->length] = (value), \ + &(array)[dyna_get_header(array)->length++]) + +void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size); + +#define dyna_pop(array) dyn_arr_pop(array, sizeof(typeof(*array))) +void dyn_arr_pop(void *array, size_t item_size); + +void dyna_deinit(void *array); + +// Get meta data +#define dyna_get_header(array) ((dyna_header *)(array)-1) +#define dyna_length(array) (dyna_get_header(array)->length) +#define dyna_capacity(array) (dyna_get_header(array)->capacity) +bool dyna_empty(void *array); diff --git a/src/main.c b/src/main.c index da40df5..09ae95d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include "dyn_arr.h" #include #include #include @@ -259,8 +260,6 @@ QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, // Early break if we've found everything if (indices.presentFamilyExists && indices.graphicsFamilyExists) { - fprintf(stderr, "yay? %d %d\n", indices.presentFamilyExists, - indices.graphicsFamilyExists); break; } } @@ -307,16 +306,29 @@ void pickPhysicalDevice(Application *app) { void createLogicalDevice(Application *app) { // Specify Queues - QueueFamilyIndices indeces = + QueueFamilyIndices indices = findQueueFamilies(app->physicalDevice, &app->surface); - //TODO: stop duplicate queue indeces occurring in this array (A set would be so handy rn) - uint32_t uniqueQueueFamilies[] = {indeces.graphicsFamily, - indeces.presentFamily}; - size_t numQueues = sizeof(uniqueQueueFamilies) / sizeof(uint32_t); - VkDeviceQueueCreateInfo queueCreateInfos[numQueues]; + uint32_t queueFamilies[] = {indices.graphicsFamily, indices.presentFamily}; + size_t numQueues = sizeof(queueFamilies) / sizeof(uint32_t); + // Make sure queue families don't have duplicates + // TODO: eventually move over to a set rather than a dynamic array + uint32_t *uniqueQueueFamilies = dyna_init(uint32_t); for (uint i = 0; i < numQueues; i++) { + bool isUnique = true; + for (uint j = 0; j < dyna_length(uniqueQueueFamilies); j++) { + if (uniqueQueueFamilies[j] == queueFamilies[i]) { + isUnique = false; + } + } + if (isUnique) { + dyna_append(uniqueQueueFamilies, queueFamilies[i]); + } + } + VkDeviceQueueCreateInfo queueCreateInfos[dyna_length(uniqueQueueFamilies)]; + + for (uint i = 0; i < dyna_length(uniqueQueueFamilies); i++) { VkDeviceQueueCreateInfo queueCreateInfo = {}; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.queueFamilyIndex = uniqueQueueFamilies[i]; @@ -334,9 +346,11 @@ void createLogicalDevice(Application *app) { VkDeviceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.pQueueCreateInfos = queueCreateInfos; - createInfo.queueCreateInfoCount = numQueues; + createInfo.queueCreateInfoCount = dyna_length(uniqueQueueFamilies); createInfo.pEnabledFeatures = &deviceFeatures; + dyna_deinit(uniqueQueueFamilies); + // Old Vulkan specify layers createInfo.enabledLayerCount = 0; createInfo.ppEnabledLayerNames = 0; @@ -352,7 +366,8 @@ void createLogicalDevice(Application *app) { } // Set graphics queue from logical device - vkGetDeviceQueue(app->device, indeces.graphicsFamily, 0, &app->graphicsQueue); + vkGetDeviceQueue(app->device, indices.graphicsFamily, 0, &app->graphicsQueue); + vkGetDeviceQueue(app->device, indices.presentFamily, 0, &app->presentQueue); } void createSurface(Application *app) {