topaz/rendering/vk/physical_device.c

100 lines
3.2 KiB
C

/* SPDX-License-Identifier:BSD-3-Clause */
#include "physical_device.h"
#include "../../core/log.h"
#include <stdio.h>
#include <string.h>
void vk_physical_device_pick(struct renderer_context *context)
{
u32 device_count = 0;
vkEnumeratePhysicalDevices(context->instance, &device_count, NULL);
VkPhysicalDevice *devices = malloc(sizeof(VkPhysicalDevice) * device_count);
if (vkEnumeratePhysicalDevices(context->instance, &device_count, devices) != VK_SUCCESS || device_count == 0) {
fatal("Can't get physical devices.\n");
}
log_info("Available devices:\n");
for (usize i = 0; i < device_count; i++) {
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(devices[i], &properties);
printf("%s\n", properties.deviceName);
}
context->physical_device = devices[0];
free(devices);
}
struct vector *vk_physical_device_get_extensions(struct renderer_context *context)
{
u32 property_count = 0;
VkExtensionProperties *properties = NULL;
vkEnumerateDeviceExtensionProperties(context->physical_device, NULL, &property_count, NULL);
struct vector *extensions = vector_init(property_count, sizeof(char *));
properties = (VkExtensionProperties *) malloc(sizeof(VkExtensionProperties) * property_count);
if (vkEnumerateDeviceExtensionProperties(context->physical_device, NULL, &property_count, properties) != VK_SUCCESS) {
free(properties);
fatal("Can't get physical device extension properties.\n");
}
for (usize i = 0; i < property_count; i++) {
char *name = malloc(strlen(properties[i].extensionName) + 1);
strcpy(name, properties[i].extensionName);
vector_push(extensions, char *, name);
}
free(properties);
return extensions;
}
void vk_physical_device_select_family_indices(struct renderer_context *context)
{
u32 property_count = 0;
VkQueueFamilyProperties *properties = NULL;
vkGetPhysicalDeviceQueueFamilyProperties(context->physical_device, &property_count, NULL);
properties = (VkQueueFamilyProperties *) malloc(sizeof(VkExtensionProperties) * property_count);
vkGetPhysicalDeviceQueueFamilyProperties(context->physical_device, &property_count, properties);
/*
* Use 0xaa as a known value to specify that these
* indices have not been found yet.
*/
context->queue_indices.graphics = 0xaa;
context->queue_indices.present = 0xaa;
/*
* This loop iterates over all the family properties
* provided by the physical device and searches for
* queue family indices for presentation and graphics.
* They may be the same queue family on many GPUs.
*/
for (u32 i = 0; i < property_count; i++) {
if (context->queue_indices.graphics != 0xaa && context->queue_indices.present != 0xaa) break;
VkQueueFamilyProperties prop = properties[i];
if ((prop.queueFlags & VK_QUEUE_GRAPHICS_BIT) && context->queue_indices.graphics == 0xaa) {
context->queue_indices.graphics = i;
}
VkBool32 present_support = VK_FALSE;
if (vkGetPhysicalDeviceSurfaceSupportKHR(context->physical_device, i, context->surface, &present_support) != VK_SUCCESS) {
free(properties);
fatal("Can't check for surface support.\n");
}
if (present_support == VK_TRUE && context->queue_indices.present == 0xaa) {
context->queue_indices.present = i;
}
}
free(properties);
}