Added in dynamic arrays and made sure logical device only gets unique family queues

This commit is contained in:
Warwick New 2024-12-16 22:10:58 +00:00
parent 7f9a0d91a2
commit 9f50fdbe7f
3 changed files with 150 additions and 10 deletions

74
src/dyn_arr.c Normal file
View file

@ -0,0 +1,74 @@
// Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c
#include "dyn_arr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

50
src/dyn_arr.h Normal file
View file

@ -0,0 +1,50 @@
#pragma once
#include <stdbool.h>
#include <stdlib.h>
#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);

View file

@ -1,3 +1,4 @@
#include "dyn_arr.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
@ -259,8 +260,6 @@ QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device,
// Early break if we've found everything // Early break if we've found everything
if (indices.presentFamilyExists && indices.graphicsFamilyExists) { if (indices.presentFamilyExists && indices.graphicsFamilyExists) {
fprintf(stderr, "yay? %d %d\n", indices.presentFamilyExists,
indices.graphicsFamilyExists);
break; break;
} }
} }
@ -307,16 +306,30 @@ void pickPhysicalDevice(Application *app) {
void createLogicalDevice(Application *app) { void createLogicalDevice(Application *app) {
// Specify Queues // Specify Queues
QueueFamilyIndices indeces = QueueFamilyIndices indices =
findQueueFamilies(app->physicalDevice, &app->surface); findQueueFamilies(app->physicalDevice, &app->surface);
//TODO: stop duplicate queue indeces occurring in this array (A set would be so handy rn) uint32_t queueFamilies[] = {indices.graphicsFamily, indices.presentFamily};
uint32_t uniqueQueueFamilies[] = {indeces.graphicsFamily, size_t numQueues = sizeof(queueFamilies) / sizeof(uint32_t);
indeces.presentFamily};
size_t numQueues = sizeof(uniqueQueueFamilies) / sizeof(uint32_t);
VkDeviceQueueCreateInfo queueCreateInfos[numQueues];
// 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++) { 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;
break;
}
}
if (isUnique) {
dyna_append(uniqueQueueFamilies, queueFamilies[i]);
}
}
VkDeviceQueueCreateInfo queueCreateInfos[dyna_length(uniqueQueueFamilies)];
for (uint i = 0; i < dyna_length(uniqueQueueFamilies); i++) {
VkDeviceQueueCreateInfo queueCreateInfo = {}; VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = uniqueQueueFamilies[i]; queueCreateInfo.queueFamilyIndex = uniqueQueueFamilies[i];
@ -334,9 +347,11 @@ void createLogicalDevice(Application *app) {
VkDeviceCreateInfo createInfo = {}; VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pQueueCreateInfos = queueCreateInfos; createInfo.pQueueCreateInfos = queueCreateInfos;
createInfo.queueCreateInfoCount = numQueues; createInfo.queueCreateInfoCount = dyna_length(uniqueQueueFamilies);
createInfo.pEnabledFeatures = &deviceFeatures; createInfo.pEnabledFeatures = &deviceFeatures;
dyna_deinit(uniqueQueueFamilies);
// Old Vulkan specify layers // Old Vulkan specify layers
createInfo.enabledLayerCount = 0; createInfo.enabledLayerCount = 0;
createInfo.ppEnabledLayerNames = 0; createInfo.ppEnabledLayerNames = 0;
@ -352,7 +367,8 @@ void createLogicalDevice(Application *app) {
} }
// Set graphics queue from logical device // 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) { void createSurface(Application *app) {