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

Loading…
Cancel
Save