From eaf3bcb290159ee37e692f3cbe45ed8328cd8f88 Mon Sep 17 00:00:00 2001 From: Gregory Wells Date: Mon, 25 May 2026 18:14:40 -0400 Subject: [PATCH] create vulkan swapchain --- Gryphn/GryphnLoader/src/gryphn_return_code.h | 3 +- .../src/extensions/vulkan_ext_swapchain.c | 58 ++++++++++++++++++- Gryphn/apis/GryphnVulkan/src/vulkan_device.c | 3 + Gryphn/apis/GryphnVulkan/src/vulkan_device.h | 4 +- Gryphn/apis/GryphnVulkan/src/vulkan_helpers.c | 36 ++++++++++++ Gryphn/apis/GryphnVulkan/src/vulkan_helpers.h | 4 ++ 6 files changed, 103 insertions(+), 5 deletions(-) diff --git a/Gryphn/GryphnLoader/src/gryphn_return_code.h b/Gryphn/GryphnLoader/src/gryphn_return_code.h index a938491..45c9437 100644 --- a/Gryphn/GryphnLoader/src/gryphn_return_code.h +++ b/Gryphn/GryphnLoader/src/gryphn_return_code.h @@ -4,5 +4,6 @@ typedef enum gnReturnCode { GN_SUCCESS = 0, GN_FAILED_TO_FIND_LIBARY = 1, GN_UNSUPPORTED_BACKEND = 2, - GN_EXTENSION_NOT_PRESENT = 3 + GN_EXTENSION_NOT_PRESENT = 3, + GN_UNSUPPOTED_SURFACE } gnReturnCode; diff --git a/Gryphn/apis/GryphnVulkan/src/extensions/vulkan_ext_swapchain.c b/Gryphn/apis/GryphnVulkan/src/extensions/vulkan_ext_swapchain.c index 8db0f15..9e5f775 100644 --- a/Gryphn/apis/GryphnVulkan/src/extensions/vulkan_ext_swapchain.c +++ b/Gryphn/apis/GryphnVulkan/src/extensions/vulkan_ext_swapchain.c @@ -1,9 +1,61 @@ #include "../vulkan_functions.h" +#include "gryphn_handle.h" #include "gryphn_return_code.h" +#include "ext/device/swapchain/gryphn_swapchain.h" +#include "../vulkan_helpers.h" +#include "../vulkan_device.h" +#include -gnReturnCode vulkanCreateSwapchain(gnDevice device, gnSwapchainCreateInfo* createInfo, gnSwapchain* swapchain) { - return GN_UNSUPPORTED_BACKEND; +typedef struct vulkanSwapchain { + uint32_t presentQueueIndex; + VkQueue presentQueue; +} vulkanSwapchain; + +gnReturnCode vulkanCreateSwapchain(gnDevice device, gnSwapchainCreateInfo* info, gnSwapchain* swapchain) { + uint32_t presentQueueIndex; + VkBool32 presentSupport = VK_FALSE; + for (int i = 0; i < ((vulkanDevice*)device->internalData)->queueCount; i++) { + vkGetPhysicalDeviceSurfaceSupportKHR(((vulkanDevice*)device->internalData)->physicalDevice, i, info->surface, &presentSupport); + if (presentSupport == VK_TRUE) { + presentQueueIndex = i; + break; + } + } + if (presentSupport == VK_FALSE) return GN_UNSUPPOTED_SURFACE; + + VkSurfaceCapabilitiesKHR capabilities; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(((vulkanDevice*)device->internalData)->physicalDevice, info->surface, &capabilities); + + VkSwapchainCreateInfoKHR createInfo = { + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .pNext = NULL, + .flags = 0, + .surface = info->surface, + .minImageCount = info->minImageCount, + .imageFormat = gryphnFormatToVulkanFormat(info->imageFormat), + .imageColorSpace = gryphnColorSpaceToVulkanColorSpace(info->imageColorSpace), + .imageExtent = { info->imageExtent.width, info->imageExtent.height }, + .imageArrayLayers = info->imageArrayLayers, + .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = NULL, + .preTransform = capabilities.currentTransform, + .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + .presentMode = gryphnPresentModeToVulkanPresentMode(info->presentMode), + .clipped = VK_TRUE, + .oldSwapchain = NULL, + }; + + if (((vulkanDevice*)device->internalData)->graphicsQueueIndex != presentQueueIndex) { + createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; + createInfo.queueFamilyIndexCount = 2; + createInfo.pQueueFamilyIndices = (uint32_t[]){((vulkanDevice*)device->internalData)->graphicsQueueIndex, presentQueueIndex}; + } + + return vulkanCodeToGryphnCode(vkCreateSwapchainKHR(((vulkanDevice*)device->internalData)->device, &createInfo, NULL, (VkSwapchainKHR*)swapchain)); } gnReturnCode vulkanDestroySwapchain(gnDevice device, gnSwapchain* swapchain) { - return GN_UNSUPPORTED_BACKEND; + vkDestroySwapchainKHR(((vulkanDevice*)device->internalData)->device, *((VkSwapchainKHR*)swapchain), NULL); + return GN_SUCCESS; } diff --git a/Gryphn/apis/GryphnVulkan/src/vulkan_device.c b/Gryphn/apis/GryphnVulkan/src/vulkan_device.c index 4b3dd36..1cda851 100644 --- a/Gryphn/apis/GryphnVulkan/src/vulkan_device.c +++ b/Gryphn/apis/GryphnVulkan/src/vulkan_device.c @@ -107,9 +107,12 @@ gnReturnCode vulkanCreateDevice(gnInstance instance, gnDeviceCreateInfo* info, g VkResult result = vkCreateDevice(info->physicalDevice->internalData, &createInfo, NULL, &vkDevice); device->internalData = malloc(sizeof(vulkanDevice)); ((vulkanDevice*)device->internalData)->device = vkDevice; + ((vulkanDevice*)device->internalData)->physicalDevice = info->physicalDevice->internalData; + ((vulkanDevice*)device->internalData)->queueCount = queueFamilyCount; for (int i = 0; i < queueFamilyCount; i++) { if ((queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT) { + ((vulkanDevice*)device->internalData)->graphicsQueueIndex = i; vkGetDeviceQueue(vkDevice, i, 0, &((vulkanDevice*)device->internalData)->graphicsQueue); break; } diff --git a/Gryphn/apis/GryphnVulkan/src/vulkan_device.h b/Gryphn/apis/GryphnVulkan/src/vulkan_device.h index d5949ec..e22fdf0 100644 --- a/Gryphn/apis/GryphnVulkan/src/vulkan_device.h +++ b/Gryphn/apis/GryphnVulkan/src/vulkan_device.h @@ -3,7 +3,9 @@ #include typedef struct vulkanDevice { VkDevice device; - uint32_t queueCount; + VkPhysicalDevice physicalDevice; + uint32_t queueCount; + uint32_t graphicsQueueIndex; VkQueue graphicsQueue; } vulkanDevice; diff --git a/Gryphn/apis/GryphnVulkan/src/vulkan_helpers.c b/Gryphn/apis/GryphnVulkan/src/vulkan_helpers.c index 94ab055..ba5d053 100644 --- a/Gryphn/apis/GryphnVulkan/src/vulkan_helpers.c +++ b/Gryphn/apis/GryphnVulkan/src/vulkan_helpers.c @@ -1,5 +1,6 @@ #include "vulkan_helpers.h" #include "core/gryphn_format.h" +#include "core/gryphn_present_mode.h" #include "gryphn_return_code.h" #include "stdio.h" #include @@ -51,3 +52,38 @@ gnPresentMode vulkanPresentModeToGryphnPresentMode(VkPresentModeKHR presentMode) default: return GN_PRESENT_MODE_UNKNOWN; } } + +VkFormat gryphnFormatToVulkanFormat(gnFormat format) { + switch (format) { + case GN_FORMAT_UNDEFINED: return VK_FORMAT_UNDEFINED; + case GN_FORMAT_RGBA8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM; + case GN_FORMAT_RGBA8_SNORM: return VK_FORMAT_R8G8B8A8_SNORM; + case GN_FORMAT_RGBA8_USCALED: return VK_FORMAT_R8G8B8A8_USCALED; + case GN_FORMAT_RGBA8_SSCALED: return VK_FORMAT_R8G8B8A8_SSCALED; + case GN_FORMAT_RGBA8_UINT: return VK_FORMAT_R8G8B8A8_UINT; + case GN_FORMAT_RGBA8_SINT: return VK_FORMAT_R8G8B8A8_SINT; + case GN_FORMAT_RGBA8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB; + case GN_FORMAT_BGRA8_UNORM: return VK_FORMAT_B8G8R8A8_UNORM; + case GN_FORMAT_BGRA8_SNORM: return VK_FORMAT_B8G8R8A8_SNORM; + case GN_FORMAT_BGRA8_USCALED: return VK_FORMAT_B8G8R8A8_USCALED; + case GN_FORMAT_BGRA8_SSCALED: return VK_FORMAT_B8G8R8A8_SSCALED; + case GN_FORMAT_BGRA8_UINT: return VK_FORMAT_B8G8R8A8_UINT; + case GN_FORMAT_BGRA8_SINT: return VK_FORMAT_B8G8R8A8_SINT; + case GN_FORMAT_BGRA8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB; + } +} +VkColorSpaceKHR gryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace) { + switch (colorSpace) { + case GN_COLOR_SPACE_SRGB_NONLINEAR: return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + case GN_COLOR_SPACE_UNKNOWN: return VK_COLOR_SPACE_MAX_ENUM_KHR; + } +} +VkPresentModeKHR gryphnPresentModeToVulkanPresentMode(gnPresentMode presentMode) { + switch (presentMode) { + case GN_PRESENT_MODE_IMMEDIATE: return VK_PRESENT_MODE_IMMEDIATE_KHR; + case GN_PRESENT_MODE_MAILBOX: return VK_PRESENT_MODE_MAILBOX_KHR; + case GN_PRESENT_MODE_FIFO: return VK_PRESENT_MODE_FIFO_KHR; + case GN_PRESENT_MODE_FIFO_RELAXED: return VK_PRESENT_MODE_FIFO_RELAXED_KHR; + case GN_PRESENT_MODE_UNKNOWN: return VK_PRESENT_MODE_MAX_ENUM_KHR; + } +} diff --git a/Gryphn/apis/GryphnVulkan/src/vulkan_helpers.h b/Gryphn/apis/GryphnVulkan/src/vulkan_helpers.h index 6ad14fb..d1e7701 100644 --- a/Gryphn/apis/GryphnVulkan/src/vulkan_helpers.h +++ b/Gryphn/apis/GryphnVulkan/src/vulkan_helpers.h @@ -8,3 +8,7 @@ gnReturnCode vulkanCodeToGryphnCode(VkResult result); gnFormat vulkanFormatToGryphnFormat(VkFormat format); gnColorSpace vulkanColorSpaceToGryphnColorSpace(VkColorSpaceKHR colorSpace); gnPresentMode vulkanPresentModeToGryphnPresentMode(VkPresentModeKHR presentMode); + +VkFormat gryphnFormatToVulkanFormat(gnFormat format); +VkColorSpaceKHR gryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace); +VkPresentModeKHR gryphnPresentModeToVulkanPresentMode(gnPresentMode presentMode);