Browse Source

Add presentation queue support.

master
Amber 2 years ago
parent
commit
b69c6f85c8
  1. 78
      src/main.c

78
src/main.c

@ -27,11 +27,17 @@ typedef struct ApplicationState { @@ -27,11 +27,17 @@ typedef struct ApplicationState {
VkDevice device;
//the queue for draw commands
VkQueue graphics_queue;
//the window surface
VkSurfaceKHR surface;
//presentation queue
VkQueue present_queue;
} ApplicationState;
typedef struct QueueFamilyIndices {
bool graphics_present;
uint32_t graphics_queue;
bool present_present;
uint32_t present_queue;
} QueueFamilyIndices;
void create_window(ApplicationState* state) {
@ -131,7 +137,7 @@ void create_instance(ApplicationState* state) { @@ -131,7 +137,7 @@ void create_instance(ApplicationState* state) {
free(extensions);
}
QueueFamilyIndices find_queue_families(VkPhysicalDevice device) {
QueueFamilyIndices find_queue_families(ApplicationState* state, VkPhysicalDevice device) {
struct QueueFamilyIndices ret = {0};
uint32_t queue_family_count = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, NULL);
@ -143,6 +149,14 @@ QueueFamilyIndices find_queue_families(VkPhysicalDevice device) { @@ -143,6 +149,14 @@ QueueFamilyIndices find_queue_families(VkPhysicalDevice device) {
ret.graphics_present = true;
ret.graphics_queue = i;
}
VkBool32 present_support = false;
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, state->surface, &present_support);
if (present_support) {
ret.present_present = true;
ret.present_queue = i;
}
}
free(queue_fam_props);
@ -173,11 +187,11 @@ void pick_physical_device(ApplicationState* state) { @@ -173,11 +187,11 @@ void pick_physical_device(ApplicationState* state) {
VkPhysicalDeviceFeatures device_features;
vkGetPhysicalDeviceFeatures(device, &device_features);
QueueFamilyIndices families = find_queue_families(device);
QueueFamilyIndices families = find_queue_families(state, device);
//for now we only require that a graphics queue is present
if (families.graphics_present) {
printf("graphics queue at %x\n", families.graphics_queue);
if (families.graphics_present && families.present_present) {
printf("graphics queue at %x, present queue at %x\n", families.graphics_queue, families.present_queue);
break;
}
}
@ -186,17 +200,40 @@ void pick_physical_device(ApplicationState* state) { @@ -186,17 +200,40 @@ void pick_physical_device(ApplicationState* state) {
free(devices);
}
int cmp(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
void create_logical_device(ApplicationState* state) {
//we already ensured that a graphics queue exists
QueueFamilyIndices indices = find_queue_families(state->physical_device);
//we already ensured that all of the required queues exist
QueueFamilyIndices indices = find_queue_families(state, state->physical_device);
//now we need to find out the number of unique queues we need to create
//since there aren't going to be many queues in this case we don't need
//a particularly efficient algorithm
uint32_t indices_array[] = {indices.present_queue, indices.graphics_queue};
qsort(indices_array, ARRSIZE(indices_array), sizeof(uint32_t), cmp);
int unique_queues[ARRSIZE(indices_array)] = {0};
int j = 0;
for (int i = 0; i < ARRSIZE(indices_array) - 1; i++) {
if (indices_array[i] != indices_array[i + 1]) {
unique_queues[j++] = indices_array[i];
}
}
unique_queues[j++] = unique_queues[ARRSIZE(indices_array) - 1];
printf("number of queues: %x\n", j);
//multiple of these will be needed once we require other kinds of queues
VkDeviceQueueCreateInfo queue_create_info = {0};
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_info.queueFamilyIndex = indices.graphics_queue;
queue_create_info.queueCount = 1;
float prio = 1.0f;
queue_create_info.pQueuePriorities = &prio;
VkDeviceQueueCreateInfo* queue_create_infos = calloc(j, sizeof(VkDeviceCreateInfo));
for (int i = 0; i < j; i++) {
queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_infos[i].queueFamilyIndex = unique_queues[i];
queue_create_infos[i].queueCount = 1;
float prio = 1.0f;
queue_create_infos[i].pQueuePriorities = &prio;
}
//for now we won't use any features
VkPhysicalDeviceFeatures device_features = {0};
@ -204,8 +241,8 @@ void create_logical_device(ApplicationState* state) { @@ -204,8 +241,8 @@ void create_logical_device(ApplicationState* state) {
//now create a logical device knowing which features and queues we need
VkDeviceCreateInfo create_info = {0};
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
create_info.pQueueCreateInfos = &queue_create_info;
create_info.queueCreateInfoCount = 1;
create_info.pQueueCreateInfos = queue_create_infos;
create_info.queueCreateInfoCount = j;
create_info.pEnabledFeatures = &device_features;
create_info.enabledExtensionCount = 0;
@ -216,6 +253,7 @@ void create_logical_device(ApplicationState* state) { @@ -216,6 +253,7 @@ void create_logical_device(ApplicationState* state) {
create_info.enabledLayerCount = 0;;
}
printf("creating logical device\n");
if (vkCreateDevice(state->physical_device, &create_info, NULL, &state->device) != VK_SUCCESS) {
printf("Error creating logical device\n");
exit(1);
@ -223,12 +261,21 @@ void create_logical_device(ApplicationState* state) { @@ -223,12 +261,21 @@ void create_logical_device(ApplicationState* state) {
//get a handle to the queue
vkGetDeviceQueue(state->device, indices.graphics_queue, 0, &state->graphics_queue);
vkGetDeviceQueue(state->device, indices.present_queue, 0, &state->present_queue);
printf("Logical device created\n");
}
void create_surface(ApplicationState* state) {
if (glfwCreateWindowSurface(state->instance, state->window, NULL, &state->surface) != VK_SUCCESS) {
printf("Surface creation failed\n");
exit(1);
}
}
void init_vulkan(ApplicationState* state) {
create_instance(state);
create_surface(state);
pick_physical_device(state);
create_logical_device(state);
}
@ -241,6 +288,7 @@ void main_loop(ApplicationState* state) { @@ -241,6 +288,7 @@ void main_loop(ApplicationState* state) {
void terminate(ApplicationState* state) {
vkDestroyDevice(state->device, NULL);
vkDestroySurfaceKHR(state->instance, state->surface, NULL);
vkDestroyInstance(state->instance, NULL);
glfwDestroyWindow(state->window);
glfwTerminate();

Loading…
Cancel
Save