Added in dynamic arrays and made sure logical device only gets unique family queues
This commit is contained in:
parent
7f9a0d91a2
commit
9f50fdbe7f
3 changed files with 150 additions and 10 deletions
74
src/dyn_arr.c
Normal file
74
src/dyn_arr.c
Normal 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
50
src/dyn_arr.h
Normal 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);
|
||||
36
src/main.c
36
src/main.c
|
|
@ -1,3 +1,4 @@
|
|||
#include "dyn_arr.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -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,30 @@ 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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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 +347,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 +367,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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue