|
@@ -17,6 +17,11 @@ typedef struct {
|
|
|
VkFramebuffer* framebuffers;
|
|
|
} Swapchain;
|
|
|
|
|
|
+typedef struct {
|
|
|
+ VkPhysicalDevice handle;
|
|
|
+ u32 graphicsFamily;
|
|
|
+} PhysicalDevice;
|
|
|
+
|
|
|
typedef struct {
|
|
|
// basic setup
|
|
|
VkInstance instance;
|
|
@@ -26,8 +31,7 @@ typedef struct {
|
|
|
VkDebugReportCallbackEXT debugReportCallback;
|
|
|
#endif
|
|
|
// render setup
|
|
|
- u32 graphicsFamily;
|
|
|
- VkPhysicalDevice physicalDevice;
|
|
|
+ PhysicalDevice physicalDevice;
|
|
|
VkDevice device;
|
|
|
VkQueue graphicsQueue;
|
|
|
VkSemaphore semaphore;
|
|
@@ -196,74 +200,68 @@ static void destroyDebugReportCallback() {
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-static bool choosePhysicalDevice(VkPhysicalDevice* devices, u32 amount) {
|
|
|
- VK_ASSERT(vkEnumeratePhysicalDevices(vk.instance, &amount, devices));
|
|
|
- int bestPoints = 0;
|
|
|
- LOG_INFO("Found %u devices", amount);
|
|
|
- for(u32 i = 0; i < amount; i++) {
|
|
|
- int points = 0;
|
|
|
- VkPhysicalDeviceProperties p;
|
|
|
- vkGetPhysicalDeviceProperties(devices[i], &p);
|
|
|
- if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
|
|
|
- points += 100;
|
|
|
- } else if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
|
|
|
- points += 50;
|
|
|
- } else if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
|
|
|
- points += 20;
|
|
|
- }
|
|
|
- if(points > bestPoints) {
|
|
|
- bestPoints = points;
|
|
|
- vk.physicalDevice = devices[i];
|
|
|
- LOG_INFO("Best Device: %s", p.deviceName);
|
|
|
+static u32 findQueueFamilies(VkPhysicalDevice pd, VkQueueFlags flags) {
|
|
|
+ VkQueueFamilyProperties properties[32];
|
|
|
+ u32 count = ARRAY_LENGTH(properties);
|
|
|
+ vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, properties);
|
|
|
+ for(u32 i = 0; i < count; i++) {
|
|
|
+ if((properties[i].queueFlags & flags) == flags) {
|
|
|
+ return i;
|
|
|
}
|
|
|
}
|
|
|
- return bestPoints == 0;
|
|
|
+ return (u32)-1;
|
|
|
}
|
|
|
|
|
|
-static bool initPhysicalDevice() {
|
|
|
- u32 deviceCount = 0;
|
|
|
- VK_ASSERT(vkEnumeratePhysicalDevices(vk.instance, &deviceCount, nullptr));
|
|
|
- if(deviceCount == 0) {
|
|
|
- LOG_ERROR("No physical device was found");
|
|
|
- return true;
|
|
|
+static int getDevicePoints(PhysicalDevice pd) {
|
|
|
+ int points = 0;
|
|
|
+ VkPhysicalDeviceProperties p;
|
|
|
+ vkGetPhysicalDeviceProperties(pd.handle, &p);
|
|
|
+ LOG_INFO("Checking '%s'", p.deviceName);
|
|
|
+ switch(p.deviceType) {
|
|
|
+ case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: points += 100; break;
|
|
|
+ case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: points += 50; break;
|
|
|
+ case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: points += 20; break;
|
|
|
+ default: break;
|
|
|
+ }
|
|
|
+ pd.graphicsFamily = findQueueFamilies(pd.handle, VK_QUEUE_GRAPHICS_BIT);
|
|
|
+ if(pd.graphicsFamily == (u32)-1) {
|
|
|
+ LOG_INFO("> ... has no graphics family");
|
|
|
+ points = -1;
|
|
|
}
|
|
|
- VkPhysicalDevice* devices =
|
|
|
- coreAllocate(sizeof(VkPhysicalDevice) * deviceCount);
|
|
|
- bool r = choosePhysicalDevice(devices, deviceCount);
|
|
|
- coreFree(devices);
|
|
|
- return r;
|
|
|
+ LOG_INFO("> Final points: %d", points);
|
|
|
+ return points;
|
|
|
}
|
|
|
|
|
|
-static u32 findQueueFamilies(VkPhysicalDevice pd, VkQueueFlags flags) {
|
|
|
- u32 count = 0;
|
|
|
- vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, nullptr);
|
|
|
- VkQueueFamilyProperties* properties =
|
|
|
- coreAllocate(sizeof(VkQueueFamilyProperties) * count);
|
|
|
- vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, properties);
|
|
|
- for(u32 i = 0; i < count; i++) {
|
|
|
- if(properties[i].queueCount != 0 &&
|
|
|
- (properties[i].queueFlags & flags) == flags) {
|
|
|
- coreFree(properties);
|
|
|
- return i;
|
|
|
+static bool initPhysicalDevice() {
|
|
|
+ VkPhysicalDevice devices[32];
|
|
|
+ u32 c = ARRAY_LENGTH(devices);
|
|
|
+ VK_ASSERT(vkEnumeratePhysicalDevices(vk.instance, &c, devices));
|
|
|
+ LOG_INFO("Found %u physical devices", c);
|
|
|
+ int bestPoints = 0;
|
|
|
+ for(u32 i = 0; i < c; i++) {
|
|
|
+ PhysicalDevice pd = {.handle = devices[i]};
|
|
|
+ int points = getDevicePoints(pd);
|
|
|
+ if(points > bestPoints) {
|
|
|
+ bestPoints = points;
|
|
|
+ vk.physicalDevice = pd;
|
|
|
}
|
|
|
}
|
|
|
- coreFree(properties);
|
|
|
- return (u32)-1;
|
|
|
+ if(bestPoints == 0) {
|
|
|
+ LOG_ERROR("No matching physical device was found");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ VkPhysicalDeviceProperties p;
|
|
|
+ vkGetPhysicalDeviceProperties(vk.physicalDevice.handle, &p);
|
|
|
+ LOG_INFO("Best Device: %s", p.deviceName);
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
static bool initDevice() {
|
|
|
VkPhysicalDeviceFeatures deviceFeatures = {0};
|
|
|
- vkGetPhysicalDeviceFeatures(vk.physicalDevice, &deviceFeatures);
|
|
|
-
|
|
|
- vk.graphicsFamily =
|
|
|
- findQueueFamilies(vk.physicalDevice, VK_QUEUE_GRAPHICS_BIT);
|
|
|
- if(vk.graphicsFamily == (u32)-1) {
|
|
|
- LOG_ERROR("Cannot find queue family");
|
|
|
- return true;
|
|
|
- }
|
|
|
+ vkGetPhysicalDeviceFeatures(vk.physicalDevice.handle, &deviceFeatures);
|
|
|
VkDeviceQueueCreateInfo dqInfo = {
|
|
|
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
|
|
- .queueFamilyIndex = vk.graphicsFamily,
|
|
|
+ .queueFamilyIndex = vk.physicalDevice.graphicsFamily,
|
|
|
.queueCount = 1,
|
|
|
.pQueuePriorities = (float[]){1.0f}};
|
|
|
VkDeviceCreateInfo deviceCreateInfo = {
|
|
@@ -275,8 +273,9 @@ static bool initDevice() {
|
|
|
(const char*[]){VK_KHR_SWAPCHAIN_EXTENSION_NAME},
|
|
|
.pEnabledFeatures = &deviceFeatures};
|
|
|
VK_ASSERT(vkCreateDevice(
|
|
|
- vk.physicalDevice, &deviceCreateInfo, nullptr, &vk.device));
|
|
|
- vkGetDeviceQueue(vk.device, vk.graphicsFamily, 0, &vk.graphicsQueue);
|
|
|
+ vk.physicalDevice.handle, &deviceCreateInfo, nullptr, &vk.device));
|
|
|
+ vkGetDeviceQueue(
|
|
|
+ vk.device, vk.physicalDevice.graphicsFamily, 0, &vk.graphicsQueue);
|
|
|
if(vk.graphicsQueue == VK_NULL_HANDLE) {
|
|
|
LOG_ERROR("Cannot get device graphics queue");
|
|
|
return true;
|
|
@@ -303,10 +302,10 @@ static u32 getSwapImageCount(const VkSurfaceCapabilitiesKHR* caps) {
|
|
|
static bool getSurfaceFormat(VkSurfaceFormatKHR* sf) {
|
|
|
u32 c = 0;
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfaceFormatsKHR(
|
|
|
- vk.physicalDevice, vk.surface, &c, nullptr));
|
|
|
+ vk.physicalDevice.handle, vk.surface, &c, nullptr));
|
|
|
VkSurfaceFormatKHR* formats = coreAllocate(sizeof(VkSurfaceFormatKHR) * c);
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfaceFormatsKHR(
|
|
|
- vk.physicalDevice, vk.surface, &c, formats));
|
|
|
+ vk.physicalDevice.handle, vk.surface, &c, formats));
|
|
|
for(u32 i = 0; i < c; i++) {
|
|
|
if(formats[i].format == VK_FORMAT_B8G8R8A8_UNORM &&
|
|
|
formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
|
|
@@ -323,10 +322,10 @@ static bool getSurfaceFormat(VkSurfaceFormatKHR* sf) {
|
|
|
static bool getPresentMode(VkPresentModeKHR* pm) {
|
|
|
u32 c = 0;
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfacePresentModesKHR(
|
|
|
- vk.physicalDevice, vk.surface, &c, nullptr));
|
|
|
+ vk.physicalDevice.handle, vk.surface, &c, nullptr));
|
|
|
VkPresentModeKHR* modes = coreAllocate(sizeof(VkPresentModeKHR) * c);
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfacePresentModesKHR(
|
|
|
- vk.physicalDevice, vk.surface, &c, modes));
|
|
|
+ vk.physicalDevice.handle, vk.surface, &c, modes));
|
|
|
for(u32 i = 0; i < c; i++) {
|
|
|
if(modes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
|
|
|
*pm = modes[i];
|
|
@@ -342,7 +341,7 @@ static bool getPresentMode(VkPresentModeKHR* pm) {
|
|
|
static bool initSwapchain() {
|
|
|
VkSurfaceCapabilitiesKHR caps = {0};
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
|
|
- vk.physicalDevice, vk.surface, &caps));
|
|
|
+ vk.physicalDevice.handle, vk.surface, &caps));
|
|
|
VkSurfaceFormatKHR sf = {0};
|
|
|
if(getSurfaceFormat(&sf)) {
|
|
|
return true;
|
|
@@ -364,7 +363,7 @@ static bool initSwapchain() {
|
|
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
|
|
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
.queueFamilyIndexCount = 1,
|
|
|
- .pQueueFamilyIndices = &vk.graphicsFamily,
|
|
|
+ .pQueueFamilyIndices = &vk.physicalDevice.graphicsFamily,
|
|
|
.preTransform = caps.currentTransform,
|
|
|
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
|
|
.presentMode = pm,
|
|
@@ -432,7 +431,8 @@ static void destroySemaphore(VkSemaphore s) {
|
|
|
static bool checkPresentationSupport() {
|
|
|
VkBool32 b = false;
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfaceSupportKHR(
|
|
|
- vk.physicalDevice, vk.graphicsFamily, vk.surface, &b));
|
|
|
+ vk.physicalDevice.handle, vk.physicalDevice.graphicsFamily, vk.surface,
|
|
|
+ &b));
|
|
|
if(!b) {
|
|
|
LOG_ERROR("Presentation is not supported");
|
|
|
return true;
|
|
@@ -443,7 +443,7 @@ static bool checkPresentationSupport() {
|
|
|
static bool initCommandBuffers() {
|
|
|
VkCommandPoolCreateInfo info = {
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
|
- .queueFamilyIndex = vk.graphicsFamily};
|
|
|
+ .queueFamilyIndex = vk.physicalDevice.graphicsFamily};
|
|
|
VK_ASSERT(vkCreateCommandPool(
|
|
|
vk.device, &info, nullptr, &vk.swapchain.commandPool));
|
|
|
vk.swapchain.commandsBuffers =
|