|
@@ -6,6 +6,13 @@
|
|
|
|
|
|
#include "core/internal/GLFW.h"
|
|
|
|
|
|
+typedef struct {
|
|
|
+ VkPhysicalDevice physical;
|
|
|
+ VkDevice logical;
|
|
|
+ u32 graphicsFamily;
|
|
|
+ VkQueue graphicsQueue;
|
|
|
+} Device;
|
|
|
+
|
|
|
typedef struct {
|
|
|
VkFormat format;
|
|
|
VkSwapchainKHR handle;
|
|
@@ -17,11 +24,6 @@ typedef struct {
|
|
|
VkFramebuffer* framebuffers;
|
|
|
} Swapchain;
|
|
|
|
|
|
-typedef struct {
|
|
|
- VkPhysicalDevice handle;
|
|
|
- u32 graphicsFamily;
|
|
|
-} PhysicalDevice;
|
|
|
-
|
|
|
typedef struct {
|
|
|
// basic setup
|
|
|
VkInstance instance;
|
|
@@ -31,9 +33,7 @@ typedef struct {
|
|
|
VkDebugReportCallbackEXT debugReportCallback;
|
|
|
#endif
|
|
|
// render setup
|
|
|
- PhysicalDevice physicalDevice;
|
|
|
- VkDevice device;
|
|
|
- VkQueue graphicsQueue;
|
|
|
+ Device device;
|
|
|
VkSemaphore semaphore;
|
|
|
VkSemaphore renderSemaphore;
|
|
|
Swapchain swapchain;
|
|
@@ -212,10 +212,10 @@ static u32 findQueueFamilies(VkPhysicalDevice pd, VkQueueFlags flags) {
|
|
|
return (u32)-1;
|
|
|
}
|
|
|
|
|
|
-static int getDevicePoints(PhysicalDevice pd) {
|
|
|
+static int getDevicePoints(Device* d) {
|
|
|
int points = 0;
|
|
|
VkPhysicalDeviceProperties p;
|
|
|
- vkGetPhysicalDeviceProperties(pd.handle, &p);
|
|
|
+ vkGetPhysicalDeviceProperties(d->physical, &p);
|
|
|
LOG_INFO("Checking '%s'", p.deviceName);
|
|
|
switch(p.deviceType) {
|
|
|
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: points += 100; break;
|
|
@@ -223,8 +223,8 @@ static int getDevicePoints(PhysicalDevice pd) {
|
|
|
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) {
|
|
|
+ d->graphicsFamily = findQueueFamilies(d->physical, VK_QUEUE_GRAPHICS_BIT);
|
|
|
+ if(d->graphicsFamily == (u32)-1) {
|
|
|
LOG_INFO("> ... has no graphics family");
|
|
|
points = -1;
|
|
|
}
|
|
@@ -239,11 +239,11 @@ static bool initPhysicalDevice() {
|
|
|
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);
|
|
|
+ Device d = {.physical = devices[i]};
|
|
|
+ int points = getDevicePoints(&d);
|
|
|
if(points > bestPoints) {
|
|
|
bestPoints = points;
|
|
|
- vk.physicalDevice = pd;
|
|
|
+ vk.device = d;
|
|
|
}
|
|
|
}
|
|
|
if(bestPoints == 0) {
|
|
@@ -251,32 +251,34 @@ static bool initPhysicalDevice() {
|
|
|
return true;
|
|
|
}
|
|
|
VkPhysicalDeviceProperties p;
|
|
|
- vkGetPhysicalDeviceProperties(vk.physicalDevice.handle, &p);
|
|
|
+ vkGetPhysicalDeviceProperties(vk.device.physical, &p);
|
|
|
LOG_INFO("Best Device: %s", p.deviceName);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-static bool initDevice() {
|
|
|
+static bool getDeviceQueue(Device* d, VkQueue* q) {
|
|
|
+ vkGetDeviceQueue(d->logical, d->graphicsFamily, 0, q);
|
|
|
+ return *q == VK_NULL_HANDLE;
|
|
|
+}
|
|
|
+
|
|
|
+static bool initDevice(Device* d) {
|
|
|
VkPhysicalDeviceFeatures deviceFeatures = {0};
|
|
|
- vkGetPhysicalDeviceFeatures(vk.physicalDevice.handle, &deviceFeatures);
|
|
|
- VkDeviceQueueCreateInfo dqInfo = {
|
|
|
+ vkGetPhysicalDeviceFeatures(d->physical, &deviceFeatures);
|
|
|
+ VkDeviceQueueCreateInfo deviceQueueInfo = {
|
|
|
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
|
|
- .queueFamilyIndex = vk.physicalDevice.graphicsFamily,
|
|
|
+ .queueFamilyIndex = d->graphicsFamily,
|
|
|
.queueCount = 1,
|
|
|
.pQueuePriorities = (float[]){1.0f}};
|
|
|
- VkDeviceCreateInfo deviceCreateInfo = {
|
|
|
+ VkDeviceCreateInfo info = {
|
|
|
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
|
|
.queueCreateInfoCount = 1,
|
|
|
- .pQueueCreateInfos = &dqInfo,
|
|
|
+ .pQueueCreateInfos = &deviceQueueInfo,
|
|
|
.enabledExtensionCount = 1,
|
|
|
.ppEnabledExtensionNames =
|
|
|
(const char*[]){VK_KHR_SWAPCHAIN_EXTENSION_NAME},
|
|
|
.pEnabledFeatures = &deviceFeatures};
|
|
|
- VK_ASSERT(vkCreateDevice(
|
|
|
- vk.physicalDevice.handle, &deviceCreateInfo, nullptr, &vk.device));
|
|
|
- vkGetDeviceQueue(
|
|
|
- vk.device, vk.physicalDevice.graphicsFamily, 0, &vk.graphicsQueue);
|
|
|
- if(vk.graphicsQueue == VK_NULL_HANDLE) {
|
|
|
+ VK_ASSERT(vkCreateDevice(d->physical, &info, nullptr, &d->logical));
|
|
|
+ if(getDeviceQueue(d, &d->graphicsQueue)) {
|
|
|
LOG_ERROR("Cannot get device graphics queue");
|
|
|
return true;
|
|
|
}
|
|
@@ -302,10 +304,10 @@ static u32 getSwapImageCount(const VkSurfaceCapabilitiesKHR* caps) {
|
|
|
static bool getSurfaceFormat(VkSurfaceFormatKHR* sf) {
|
|
|
u32 c = 0;
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfaceFormatsKHR(
|
|
|
- vk.physicalDevice.handle, vk.surface, &c, nullptr));
|
|
|
+ vk.device.physical, vk.surface, &c, nullptr));
|
|
|
VkSurfaceFormatKHR* formats = coreAllocate(sizeof(VkSurfaceFormatKHR) * c);
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfaceFormatsKHR(
|
|
|
- vk.physicalDevice.handle, vk.surface, &c, formats));
|
|
|
+ vk.device.physical, 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) {
|
|
@@ -322,10 +324,10 @@ static bool getSurfaceFormat(VkSurfaceFormatKHR* sf) {
|
|
|
static bool getPresentMode(VkPresentModeKHR* pm) {
|
|
|
u32 c = 0;
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfacePresentModesKHR(
|
|
|
- vk.physicalDevice.handle, vk.surface, &c, nullptr));
|
|
|
+ vk.device.physical, vk.surface, &c, nullptr));
|
|
|
VkPresentModeKHR* modes = coreAllocate(sizeof(VkPresentModeKHR) * c);
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfacePresentModesKHR(
|
|
|
- vk.physicalDevice.handle, vk.surface, &c, modes));
|
|
|
+ vk.device.physical, vk.surface, &c, modes));
|
|
|
for(u32 i = 0; i < c; i++) {
|
|
|
if(modes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
|
|
|
*pm = modes[i];
|
|
@@ -341,7 +343,7 @@ static bool getPresentMode(VkPresentModeKHR* pm) {
|
|
|
static bool initSwapchain() {
|
|
|
VkSurfaceCapabilitiesKHR caps = {0};
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
|
|
- vk.physicalDevice.handle, vk.surface, &caps));
|
|
|
+ vk.device.physical, vk.surface, &caps));
|
|
|
VkSurfaceFormatKHR sf = {0};
|
|
|
if(getSurfaceFormat(&sf)) {
|
|
|
return true;
|
|
@@ -363,14 +365,14 @@ static bool initSwapchain() {
|
|
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
|
|
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
.queueFamilyIndexCount = 1,
|
|
|
- .pQueueFamilyIndices = &vk.physicalDevice.graphicsFamily,
|
|
|
+ .pQueueFamilyIndices = &vk.device.graphicsFamily,
|
|
|
.preTransform = caps.currentTransform,
|
|
|
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
|
|
.presentMode = pm,
|
|
|
.clipped = VK_TRUE,
|
|
|
.oldSwapchain = VK_NULL_HANDLE};
|
|
|
- VK_ASSERT(
|
|
|
- vkCreateSwapchainKHR(vk.device, &ci, nullptr, &vk.swapchain.handle));
|
|
|
+ VK_ASSERT(vkCreateSwapchainKHR(
|
|
|
+ vk.device.logical, &ci, nullptr, &vk.swapchain.handle));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -386,13 +388,14 @@ static bool createImageView(VkImage image, VkImageView* view) {
|
|
|
.levelCount = 1,
|
|
|
.baseArrayLayer = 0,
|
|
|
.layerCount = 1}};
|
|
|
- VK_ASSERT(vkCreateImageView(vk.device, &info, nullptr, view));
|
|
|
+ VK_ASSERT(vkCreateImageView(vk.device.logical, &info, nullptr, view));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
static void destroySwapchainImages() {
|
|
|
for(size_t x = 0; x < vk.swapchain.amount; x++) {
|
|
|
- vkDestroyImageView(vk.device, vk.swapchain.imageViews[x], nullptr);
|
|
|
+ vkDestroyImageView(
|
|
|
+ vk.device.logical, vk.swapchain.imageViews[x], nullptr);
|
|
|
}
|
|
|
coreFree(vk.swapchain.images);
|
|
|
coreFree(vk.swapchain.imageViews);
|
|
@@ -400,14 +403,14 @@ static void destroySwapchainImages() {
|
|
|
|
|
|
static bool initSwapchainImages() {
|
|
|
u32 c = 0;
|
|
|
- VK_ASSERT(
|
|
|
- vkGetSwapchainImagesKHR(vk.device, vk.swapchain.handle, &c, nullptr));
|
|
|
+ VK_ASSERT(vkGetSwapchainImagesKHR(
|
|
|
+ vk.device.logical, vk.swapchain.handle, &c, nullptr));
|
|
|
LOG_INFO("Found %u images", c);
|
|
|
vk.swapchain.amount = c;
|
|
|
vk.swapchain.images = coreAllocate(sizeof(VkImage) * c);
|
|
|
vk.swapchain.imageViews = coreZeroAllocate(sizeof(VkImageView) * c);
|
|
|
VK_ASSERT(vkGetSwapchainImagesKHR(
|
|
|
- vk.device, vk.swapchain.handle, &c, vk.swapchain.images));
|
|
|
+ vk.device.logical, vk.swapchain.handle, &c, vk.swapchain.images));
|
|
|
for(u32 x = 0; x < c; x++) {
|
|
|
if(createImageView(
|
|
|
vk.swapchain.images[x], vk.swapchain.imageViews + x)) {
|
|
@@ -420,19 +423,18 @@ static bool initSwapchainImages() {
|
|
|
static bool initSemaphore(VkSemaphore* s) {
|
|
|
VkSemaphoreCreateInfo info = {
|
|
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
|
|
|
- VK_ASSERT(vkCreateSemaphore(vk.device, &info, nullptr, s));
|
|
|
+ VK_ASSERT(vkCreateSemaphore(vk.device.logical, &info, nullptr, s));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
static void destroySemaphore(VkSemaphore s) {
|
|
|
- vkDestroySemaphore(vk.device, s, nullptr);
|
|
|
+ vkDestroySemaphore(vk.device.logical, s, nullptr);
|
|
|
}
|
|
|
|
|
|
static bool checkPresentationSupport() {
|
|
|
VkBool32 b = false;
|
|
|
VK_ASSERT(vkGetPhysicalDeviceSurfaceSupportKHR(
|
|
|
- vk.physicalDevice.handle, vk.physicalDevice.graphicsFamily, vk.surface,
|
|
|
- &b));
|
|
|
+ vk.device.physical, vk.device.graphicsFamily, vk.surface, &b));
|
|
|
if(!b) {
|
|
|
LOG_ERROR("Presentation is not supported");
|
|
|
return true;
|
|
@@ -443,9 +445,9 @@ static bool checkPresentationSupport() {
|
|
|
static bool initCommandBuffers() {
|
|
|
VkCommandPoolCreateInfo info = {
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
|
- .queueFamilyIndex = vk.physicalDevice.graphicsFamily};
|
|
|
+ .queueFamilyIndex = vk.device.graphicsFamily};
|
|
|
VK_ASSERT(vkCreateCommandPool(
|
|
|
- vk.device, &info, nullptr, &vk.swapchain.commandPool));
|
|
|
+ vk.device.logical, &info, nullptr, &vk.swapchain.commandPool));
|
|
|
vk.swapchain.commandsBuffers =
|
|
|
coreAllocate(sizeof(VkCommandBuffer) * vk.swapchain.amount);
|
|
|
VkCommandBufferAllocateInfo a = {
|
|
@@ -453,19 +455,19 @@ static bool initCommandBuffers() {
|
|
|
.commandPool = vk.swapchain.commandPool,
|
|
|
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
|
|
.commandBufferCount = vk.swapchain.amount};
|
|
|
- VK_ASSERT(
|
|
|
- vkAllocateCommandBuffers(vk.device, &a, vk.swapchain.commandsBuffers));
|
|
|
+ VK_ASSERT(vkAllocateCommandBuffers(
|
|
|
+ vk.device.logical, &a, vk.swapchain.commandsBuffers));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
static void destroyCommandBuffers() {
|
|
|
if(vk.swapchain.commandPool != VK_NULL_HANDLE && vk.swapchain.amount > 0) {
|
|
|
vkFreeCommandBuffers(
|
|
|
- vk.device, vk.swapchain.commandPool, vk.swapchain.amount,
|
|
|
+ vk.device.logical, vk.swapchain.commandPool, vk.swapchain.amount,
|
|
|
vk.swapchain.commandsBuffers);
|
|
|
}
|
|
|
coreFree(vk.swapchain.commandsBuffers);
|
|
|
- vkDestroyCommandPool(vk.device, vk.swapchain.commandPool, nullptr);
|
|
|
+ vkDestroyCommandPool(vk.device.logical, vk.swapchain.commandPool, nullptr);
|
|
|
}
|
|
|
|
|
|
static bool initRenderPass() {
|
|
@@ -490,7 +492,8 @@ static bool initRenderPass() {
|
|
|
.pAttachments = &c,
|
|
|
.subpassCount = 1,
|
|
|
.pSubpasses = &subpass};
|
|
|
- VK_ASSERT(vkCreateRenderPass(vk.device, &info, nullptr, &vk.renderPass));
|
|
|
+ VK_ASSERT(
|
|
|
+ vkCreateRenderPass(vk.device.logical, &info, nullptr, &vk.renderPass));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -507,7 +510,7 @@ static bool initFramebuffers() {
|
|
|
.height = vk.height,
|
|
|
.layers = 1};
|
|
|
VK_ASSERT(vkCreateFramebuffer(
|
|
|
- vk.device, &info, nullptr, vk.swapchain.framebuffers + i));
|
|
|
+ vk.device.logical, &info, nullptr, vk.swapchain.framebuffers + i));
|
|
|
}
|
|
|
printf("%u\n", vk.swapchain.amount);
|
|
|
return false;
|
|
@@ -515,7 +518,8 @@ static bool initFramebuffers() {
|
|
|
|
|
|
static void destroyFramebuffers() {
|
|
|
for(u32 i = 0; i < vk.swapchain.amount; i++) {
|
|
|
- vkDestroyFramebuffer(vk.device, vk.swapchain.framebuffers[i], nullptr);
|
|
|
+ vkDestroyFramebuffer(
|
|
|
+ vk.device.logical, vk.swapchain.framebuffers[i], nullptr);
|
|
|
}
|
|
|
coreFree(vk.swapchain.framebuffers);
|
|
|
}
|
|
@@ -524,10 +528,11 @@ bool initVulkan() {
|
|
|
vk.width = 400;
|
|
|
vk.height = 300;
|
|
|
return initInstance() || initDebugging() || initSurface() ||
|
|
|
- initPhysicalDevice() || initDevice() || checkPresentationSupport() ||
|
|
|
- initSwapchain() || initSwapchainImages() ||
|
|
|
- initSemaphore(&vk.semaphore) || initSemaphore(&vk.renderSemaphore) ||
|
|
|
- initCommandBuffers() || initRenderPass() || initFramebuffers();
|
|
|
+ initPhysicalDevice() || initDevice(&vk.device) ||
|
|
|
+ checkPresentationSupport() || initSwapchain() ||
|
|
|
+ initSwapchainImages() || initSemaphore(&vk.semaphore) ||
|
|
|
+ initSemaphore(&vk.renderSemaphore) || initCommandBuffers() ||
|
|
|
+ initRenderPass() || initFramebuffers();
|
|
|
}
|
|
|
|
|
|
static bool fillCommandBuffer(u32 index) {
|
|
@@ -556,16 +561,16 @@ void renderVulkan() {
|
|
|
}
|
|
|
|
|
|
void destroyVulkan(void) {
|
|
|
- if(vk.device != VK_NULL_HANDLE) {
|
|
|
+ if(vk.device.logical != VK_NULL_HANDLE) {
|
|
|
destroyFramebuffers();
|
|
|
- vkDestroyRenderPass(vk.device, vk.renderPass, nullptr);
|
|
|
+ vkDestroyRenderPass(vk.device.logical, vk.renderPass, nullptr);
|
|
|
destroyCommandBuffers();
|
|
|
destroySemaphore(vk.semaphore);
|
|
|
destroySemaphore(vk.renderSemaphore);
|
|
|
destroySwapchainImages();
|
|
|
- vkDestroySwapchainKHR(vk.device, vk.swapchain.handle, nullptr);
|
|
|
+ vkDestroySwapchainKHR(vk.device.logical, vk.swapchain.handle, nullptr);
|
|
|
}
|
|
|
- vkDestroyDevice(vk.device, nullptr);
|
|
|
+ vkDestroyDevice(vk.device.logical, nullptr);
|
|
|
if(vk.instance != VK_NULL_HANDLE) {
|
|
|
vkDestroySurfaceKHR(vk.instance, vk.surface, nullptr);
|
|
|
destroyDebugMessenger();
|