Added in dynamic arrays and made sure logical device only gets unique family queues
This commit is contained in:
parent
7f9a0d91a2
commit
bdcc131084
3 changed files with 149 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);
|
||||||
35
src/main.c
35
src/main.c
|
|
@ -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,29 @@ 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 +346,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 +366,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) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue