This commit is contained in:
2024-09-13 23:51:01 +02:00
parent 8888bd03d8
commit cd29248fc6
2 changed files with 512 additions and 274 deletions

View File

@@ -42,6 +42,9 @@ namespace mlx
Window window(1, 1, "", true); Window window(1, 1, "", true);
std::vector<const char*> instance_extentions = window.GetRequiredVulkanInstanceExtentions(); std::vector<const char*> instance_extentions = window.GetRequiredVulkanInstanceExtentions();
#ifdef MLX_PLAT_MACOS
instance_extentions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
#endif
m_instance = kvfCreateInstance(instance_extensions.data(), instance_extensions.size()); m_instance = kvfCreateInstance(instance_extensions.data(), instance_extensions.size());
DebugLog("Vulkan : instance created"); DebugLog("Vulkan : instance created");

467
third_party/kvf.h vendored
View File

@@ -43,6 +43,8 @@
* or VK_NO_PROTOTYPES before including this file to avoid conflicts with Vulkan prototypes. * or VK_NO_PROTOTYPES before including this file to avoid conflicts with Vulkan prototypes.
* *
* You can also #define KVF_ENABLE_VALIDATION_LAYERS to enable validation layers. * You can also #define KVF_ENABLE_VALIDATION_LAYERS to enable validation layers.
*
* Use #define KVF_NO_KHR to remove all functions that use KHR calls.
*/ */
#ifndef KBZ_8_VULKAN_FRAMEWORK_H #ifndef KBZ_8_VULKAN_FRAMEWORK_H
@@ -89,20 +91,30 @@ void kvfSetValidationWarningCallback(KvfErrorCallback callback);
void kvfAddLayer(const char* layer); void kvfAddLayer(const char* layer);
VkInstance kvfCreateInstance(const char** extensionsEnabled, uint32_t extensionsCount); VkInstance kvfCreateInstance(const char** extensions_enabled, uint32_t extensions_count);
void kvfDestroyInstance(VkInstance instance); void kvfDestroyInstance(VkInstance instance);
// If surfaces given to theses functions are VK_NULL_HANDLE no present queues will be searched and thus kvfQueuePresentKHR will not work // If surfaces given to theses functions are VK_NULL_HANDLE no present queues will be searched and thus kvfQueuePresentKHR will not work
VkPhysicalDevice kvfPickFirstPhysicalDevice(VkInstance instance, VkSurfaceKHR surface); VkPhysicalDevice kvfPickFirstPhysicalDevice(VkInstance instance, VkSurfaceKHR surface);
VkPhysicalDevice kvfPickGoodDefaultPhysicalDevice(VkInstance instance, VkSurfaceKHR surface); VkPhysicalDevice kvfPickGoodDefaultPhysicalDevice(VkInstance instance, VkSurfaceKHR surface);
VkPhysicalDevice kvfPickGoodPhysicalDevice(VkInstance instance, VkSurfaceKHR surface, const char** deviceExtensions, uint32_t deviceExtensionsCount); VkPhysicalDevice kvfPickGoodPhysicalDevice(VkInstance instance, VkSurfaceKHR surface, const char** device_extensions, uint32_t device_extensions_count);
VkQueue kvfGetDeviceQueue(VkDevice device, KvfQueueType queue); VkQueue kvfGetDeviceQueue(VkDevice device, KvfQueueType queue);
uint32_t kvfGetDeviceQueueFamily(VkDevice device, KvfQueueType queue); uint32_t kvfGetDeviceQueueFamily(VkDevice device, KvfQueueType queue);
bool kvfQueuePresentKHR(VkDevice device, VkSemaphore wait, VkSwapchainKHR swapchain, uint32_t image_index); // return false when the swapchain must be recreated #ifndef KVF_NO_KHR
bool kvfQueuePresentKHR(VkDevice device, VkSemaphore wait, VkSwapchainKHR swapchain, uint32_t image_index); // return false when the swapchain must be recreated
#endif
// Meant to be used when creating a VkDevice with a custom VkPhysicalDevice
int32_t kvfFindDeviceQueueFamily(VkPhysicalDevice physical, KvfQueueType type); // This function cannot find present queue
#ifndef KVF_NO_KHR
int32_t kvfFindDeviceQueueFamilyKHR(VkPhysicalDevice physical, VkSurfaceKHR surface, KvfQueueType type); // This one can find present queue
#endif
VkDevice kvfCreateDefaultDevice(VkPhysicalDevice physical); VkDevice kvfCreateDefaultDevice(VkPhysicalDevice physical);
VkDevice kvfCreateDevice(VkPhysicalDevice physical, const char** extensions, uint32_t extensions_count, VkPhysicalDeviceFeatures* features); VkDevice kvfCreateDevice(VkPhysicalDevice physical, const char** extensions, uint32_t extensions_count, VkPhysicalDeviceFeatures* features);
VkDevice kvfCreateDefaultDevicePhysicalDeviceAndCustomQueues(VkPhysicalDevice physical, int32_t graphics_queue, int32_t present_queue, int32_t compute_queue);
VkDevice kvfCreateDeviceCustomPhysicalDeviceAndQueues(VkPhysicalDevice physical, const char** extensions, uint32_t extensions_count, VkPhysicalDeviceFeatures* features, int32_t graphics_queue, int32_t present_queue, int32_t compute_queue);
void kvfDestroyDevice(VkDevice device); void kvfDestroyDevice(VkDevice device);
VkFence kvfCreateFence(VkDevice device); VkFence kvfCreateFence(VkDevice device);
@@ -112,15 +124,17 @@ void kvfDestroyFence(VkDevice device, VkFence fence);
VkSemaphore kvfCreateSemaphore(VkDevice device); VkSemaphore kvfCreateSemaphore(VkDevice device);
void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore); void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore);
VkSwapchainKHR kvfCreateSwapchainKHR(VkDevice device, VkPhysicalDevice physical, VkSurfaceKHR surface, VkExtent2D extent, bool tryVsync); #ifndef KVF_NO_KHR
VkFormat kvfGetSwapchainImagesFormat(VkSwapchainKHR swapchain); VkSwapchainKHR kvfCreateSwapchainKHR(VkDevice device, VkPhysicalDevice physical, VkSurfaceKHR surface, VkExtent2D extent, bool try_vsync);
uint32_t kvfGetSwapchainImagesCount(VkSwapchainKHR swapchain); VkFormat kvfGetSwapchainImagesFormat(VkSwapchainKHR swapchain);
uint32_t kvfGetSwapchainMinImagesCount(VkSwapchainKHR swapchain); uint32_t kvfGetSwapchainImagesCount(VkSwapchainKHR swapchain);
VkExtent2D kvfGetSwapchainImagesSize(VkSwapchainKHR swapchain); uint32_t kvfGetSwapchainMinImagesCount(VkSwapchainKHR swapchain);
void kvfDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain); VkExtent2D kvfGetSwapchainImagesSize(VkSwapchainKHR swapchain);
void kvfDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain);
#endif
VkImage kvfCreateImage(VkDevice device, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, KvfImageType type); VkImage kvfCreateImage(VkDevice device, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, KvfImageType type);
void kvfImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage src, size_t size); void kvfImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage src, size_t buffer_offset, VkImageAspectFlagBits aspect, VkExtent3D extent);
void kvfDestroyImage(VkDevice device, VkImage image); void kvfDestroyImage(VkDevice device, VkImage image);
VkImageView kvfCreateImageView(VkDevice device, VkImage image, VkFormat format, VkImageViewType type, VkImageAspectFlags aspect, int layer_count); VkImageView kvfCreateImageView(VkDevice device, VkImage image, VkFormat format, VkImageViewType type, VkImageAspectFlags aspect, int layer_count);
void kvfDestroyImageView(VkDevice device, VkImageView image_view); void kvfDestroyImageView(VkDevice device, VkImageView image_view);
@@ -145,7 +159,9 @@ void kvfSubmitCommandBuffer(VkDevice device, VkCommandBuffer buffer, KvfQueueTyp
void kvfSubmitSingleTimeCommandBuffer(VkDevice device, VkCommandBuffer buffer, KvfQueueType queue, VkFence fence); void kvfSubmitSingleTimeCommandBuffer(VkDevice device, VkCommandBuffer buffer, KvfQueueType queue, VkFence fence);
VkAttachmentDescription kvfBuildAttachmentDescription(KvfImageType type, VkFormat format, VkImageLayout initial, VkImageLayout final, bool clear, VkSampleCountFlagBits samples); VkAttachmentDescription kvfBuildAttachmentDescription(KvfImageType type, VkFormat format, VkImageLayout initial, VkImageLayout final, bool clear, VkSampleCountFlagBits samples);
VkAttachmentDescription kvfBuildSwapchainAttachmentDescription(VkSwapchainKHR swapchain, bool clear); #ifndef KVF_NO_KHR
VkAttachmentDescription kvfBuildSwapchainAttachmentDescription(VkSwapchainKHR swapchain, bool clear);
#endif
VkRenderPass kvfCreateRenderPass(VkDevice device, VkAttachmentDescription* attachments, size_t attachments_count, VkPipelineBindPoint bind_point); VkRenderPass kvfCreateRenderPass(VkDevice device, VkAttachmentDescription* attachments, size_t attachments_count, VkPipelineBindPoint bind_point);
VkRenderPass kvfCreateRenderPassWithSubpassDependencies(VkDevice device, VkAttachmentDescription* attachments, size_t attachments_count, VkPipelineBindPoint bind_point, VkSubpassDependency* dependencies, size_t dependencies_count); VkRenderPass kvfCreateRenderPassWithSubpassDependencies(VkDevice device, VkAttachmentDescription* attachments, size_t attachments_count, VkPipelineBindPoint bind_point, VkSubpassDependency* dependencies, size_t dependencies_count);
@@ -260,23 +276,25 @@ typedef struct
size_t sets_pools_size; size_t sets_pools_size;
} __KvfDevice; } __KvfDevice;
typedef struct #ifndef KVF_NO_KHR
{ typedef struct
{
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
VkSurfaceFormatKHR* formats; VkSurfaceFormatKHR* formats;
VkPresentModeKHR* presentModes; VkPresentModeKHR* presentModes;
uint32_t formatsCount; uint32_t formats_count;
uint32_t presentModesCount; uint32_t presentModes_count;
} __KvfSwapchainSupportInternal; } __KvfSwapchainSupportInternal;
typedef struct typedef struct
{ {
__KvfSwapchainSupportInternal support; __KvfSwapchainSupportInternal support;
VkSwapchainKHR swapchain; VkSwapchainKHR swapchain;
VkExtent2D images_extent; VkExtent2D images_extent;
VkFormat images_format; VkFormat images_format;
uint32_t images_count; uint32_t images_count;
} __KvfSwapchain; } __KvfSwapchain;
#endif
typedef struct typedef struct
{ {
@@ -302,9 +320,11 @@ __KvfDevice* __kvf_internal_devices = NULL;
size_t __kvf_internal_devices_size = 0; size_t __kvf_internal_devices_size = 0;
size_t __kvf_internal_devices_capacity = 0; size_t __kvf_internal_devices_capacity = 0;
__KvfSwapchain* __kvf_internal_swapchains = NULL; #ifndef KVF_NO_KHR
size_t __kvf_internal_swapchains_size = 0; __KvfSwapchain* __kvf_internal_swapchains = NULL;
size_t __kvf_internal_swapchains_capacity = 0; size_t __kvf_internal_swapchains_size = 0;
size_t __kvf_internal_swapchains_capacity = 0;
#endif
__KvfFramebuffer* __kvf_internal_framebuffers = NULL; __KvfFramebuffer* __kvf_internal_framebuffers = NULL;
size_t __kvf_internal_framebuffers_size = 0; size_t __kvf_internal_framebuffers_size = 0;
@@ -346,7 +366,7 @@ void kvfCheckVk(VkResult result)
__kvfCheckVk(result); __kvfCheckVk(result);
} }
void __kvfAddDeviceToArray(VkPhysicalDevice device, int32_t graphics_queue, int32_t present_queue) void __kvfAddDeviceToArray(VkPhysicalDevice device, int32_t graphics_queue, int32_t present_queue, int32_t compute_queue)
{ {
KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(device != VK_NULL_HANDLE);
if(__kvf_internal_devices_size == __kvf_internal_devices_capacity) if(__kvf_internal_devices_size == __kvf_internal_devices_capacity)
@@ -358,6 +378,7 @@ void __kvfAddDeviceToArray(VkPhysicalDevice device, int32_t graphics_queue, int3
__kvf_internal_devices[__kvf_internal_devices_size].physical = device; __kvf_internal_devices[__kvf_internal_devices_size].physical = device;
__kvf_internal_devices[__kvf_internal_devices_size].queues.graphics = graphics_queue; __kvf_internal_devices[__kvf_internal_devices_size].queues.graphics = graphics_queue;
__kvf_internal_devices[__kvf_internal_devices_size].queues.compute = compute_queue;
__kvf_internal_devices[__kvf_internal_devices_size].queues.present = present_queue; __kvf_internal_devices[__kvf_internal_devices_size].queues.present = present_queue;
__kvf_internal_devices_size++; __kvf_internal_devices_size++;
} }
@@ -390,6 +411,36 @@ void __kvfCompleteDevice(VkPhysicalDevice physical, VkDevice device)
kvf_device->sets_pools_size = 0; kvf_device->sets_pools_size = 0;
} }
void __kvfCompleteDeviceCustomPhysicalDeviceAndQueues(VkPhysicalDevice physical, VkDevice device, int32_t graphics_queue, int32_t present_queue, int32_t compute_queue)
{
KVF_ASSERT(device != VK_NULL_HANDLE);
KVF_ASSERT(physical != VK_NULL_HANDLE);
__kvfAddDeviceToArray(physical, graphics_queue, present_queue, compute_queue);
__KvfDevice* kvf_device = NULL;
for(size_t i = 0; i < __kvf_internal_devices_size; i++)
{
if(__kvf_internal_devices[i].physical == physical)
kvf_device = &__kvf_internal_devices[i];
}
KVF_ASSERT(kvf_device != NULL);
VkCommandPool pool;
VkCommandPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
pool_info.queueFamilyIndex = kvf_device->queues.graphics;
__kvfCheckVk(vkCreateCommandPool(device, &pool_info, NULL, &pool));
kvf_device->device = device;
kvf_device->cmd_pool = pool;
kvf_device->sets_pools = NULL;
kvf_device->sets_pools_size = 0;
}
void __kvfDestroyDescriptorPools(VkDevice device); void __kvfDestroyDescriptorPools(VkDevice device);
void __kvfDestroyDevice(VkDevice device) void __kvfDestroyDevice(VkDevice device)
@@ -438,8 +489,9 @@ __KvfDevice* __kvfGetKvfDeviceFromVkDevice(VkDevice device)
return NULL; return NULL;
} }
void __kvfAddSwapchainToArray(VkSwapchainKHR swapchain, __KvfSwapchainSupportInternal support, VkFormat format, uint32_t images_count, VkExtent2D extent) #ifndef KVF_NO_KHR
{ void __kvfAddSwapchainToArray(VkSwapchainKHR swapchain, __KvfSwapchainSupportInternal support, VkFormat format, uint32_t images_count, VkExtent2D extent)
{
KVF_ASSERT(swapchain != VK_NULL_HANDLE); KVF_ASSERT(swapchain != VK_NULL_HANDLE);
if(__kvf_internal_swapchains_size == __kvf_internal_swapchains_capacity) if(__kvf_internal_swapchains_size == __kvf_internal_swapchains_capacity)
{ {
@@ -454,10 +506,10 @@ void __kvfAddSwapchainToArray(VkSwapchainKHR swapchain, __KvfSwapchainSupportInt
__kvf_internal_swapchains[__kvf_internal_swapchains_size].images_count = images_count; __kvf_internal_swapchains[__kvf_internal_swapchains_size].images_count = images_count;
__kvf_internal_swapchains[__kvf_internal_swapchains_size].images_extent = extent; __kvf_internal_swapchains[__kvf_internal_swapchains_size].images_extent = extent;
__kvf_internal_swapchains_size++; __kvf_internal_swapchains_size++;
} }
void __kvfDestroySwapchain(VkDevice device, VkSwapchainKHR swapchain) void __kvfDestroySwapchain(VkDevice device, VkSwapchainKHR swapchain)
{ {
KVF_ASSERT(swapchain != VK_NULL_HANDLE); KVF_ASSERT(swapchain != VK_NULL_HANDLE);
KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(device != VK_NULL_HANDLE);
@@ -478,10 +530,10 @@ void __kvfDestroySwapchain(VkDevice device, VkSwapchainKHR swapchain)
return; return;
} }
} }
} }
__KvfSwapchain* __kvfGetKvfSwapchainFromVkSwapchainKHR(VkSwapchainKHR swapchain) __KvfSwapchain* __kvfGetKvfSwapchainFromVkSwapchainKHR(VkSwapchainKHR swapchain)
{ {
KVF_ASSERT(swapchain != VK_NULL_HANDLE); KVF_ASSERT(swapchain != VK_NULL_HANDLE);
for(size_t i = 0; i < __kvf_internal_swapchains_size; i++) for(size_t i = 0; i < __kvf_internal_swapchains_size; i++)
{ {
@@ -489,7 +541,8 @@ __KvfSwapchain* __kvfGetKvfSwapchainFromVkSwapchainKHR(VkSwapchainKHR swapchain)
return &__kvf_internal_swapchains[i]; return &__kvf_internal_swapchains[i];
} }
return NULL; return NULL;
} }
#endif
void __kvfAddFramebufferToArray(VkFramebuffer framebuffer, VkExtent2D extent) void __kvfAddFramebufferToArray(VkFramebuffer framebuffer, VkExtent2D extent)
{ {
@@ -1025,19 +1078,23 @@ VkInstance kvfCreateInstance(const char** extensions_enabled, uint32_t extension
VkInstanceCreateInfo create_info = {}; VkInstanceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
create_info.pApplicationInfo = NULL; create_info.pApplicationInfo = NULL;
create_info.flags = 0;
create_info.enabledExtensionCount = extensions_count; create_info.enabledExtensionCount = extensions_count;
create_info.ppEnabledExtensionNames = extensions_enabled; create_info.ppEnabledExtensionNames = extensions_enabled;
create_info.enabledLayerCount = 0; create_info.enabledLayerCount = 0;
create_info.ppEnabledLayerNames = NULL; create_info.ppEnabledLayerNames = NULL;
create_info.pNext = NULL; create_info.pNext = NULL;
#if defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)
create_info.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#else
create_info.flags = 0;
#endif
#ifdef KVF_ENABLE_VALIDATION_LAYERS #ifdef KVF_ENABLE_VALIDATION_LAYERS
kvfAddLayer("VK_LAYER_KHRONOS_validation"); kvfAddLayer("VK_LAYER_KHRONOS_validation");
const char** new_extension_set = NULL; const char** new_extension_set = NULL;
VkDebugUtilsMessengerCreateInfoEXT debug_create_info = {};
if(__kvfCheckValidationLayerSupport()) if(__kvfCheckValidationLayerSupport())
{ {
VkDebugUtilsMessengerCreateInfoEXT debug_create_info = {};
__kvfPopulateDebugMessengerCreateInfo(&debug_create_info); __kvfPopulateDebugMessengerCreateInfo(&debug_create_info);
new_extension_set = (const char**)KVF_MALLOC(sizeof(char*) * (extensions_count + 1)); new_extension_set = (const char**)KVF_MALLOC(sizeof(char*) * (extensions_count + 1));
memcpy(new_extension_set, extensions_enabled, sizeof(char*) * extensions_count); memcpy(new_extension_set, extensions_enabled, sizeof(char*) * extensions_count);
@@ -1090,6 +1147,7 @@ __KvfQueueFamilies __kvfFindQueueFamilies(VkPhysicalDevice physical, VkSurfaceKH
queues.compute = i; queues.compute = i;
if(queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) if(queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
queues.graphics = i; queues.graphics = i;
#ifndef KVF_NO_KHR
VkBool32 present_support = false; VkBool32 present_support = false;
if(surface != VK_NULL_HANDLE) if(surface != VK_NULL_HANDLE)
{ {
@@ -1101,6 +1159,10 @@ __KvfQueueFamilies __kvfFindQueueFamilies(VkPhysicalDevice physical, VkSurfaceKH
} }
else if(queues.graphics != -1 && queues.compute != -1) else if(queues.graphics != -1 && queues.compute != -1)
break; break;
#else
if(queues.graphics != -1 && queues.compute != -1)
break;
#endif
} }
KVF_FREE(queue_families); KVF_FREE(queue_families);
return queues; return queues;
@@ -1120,7 +1182,7 @@ VkPhysicalDevice kvfPickFirstPhysicalDevice(VkInstance instance, VkSurfaceKHR su
chosen_one = devices[0]; chosen_one = devices[0];
KVF_FREE(devices); KVF_FREE(devices);
__KvfQueueFamilies queues = __kvfFindQueueFamilies(chosen_one, surface); __KvfQueueFamilies queues = __kvfFindQueueFamilies(chosen_one, surface);
__kvfAddDeviceToArray(chosen_one, queues.graphics, queues.present); __kvfAddDeviceToArray(chosen_one, queues.graphics, queues.present, queues.present);
return chosen_one; return chosen_one;
} }
@@ -1130,21 +1192,21 @@ VkPhysicalDevice kvfPickGoodDefaultPhysicalDevice(VkInstance instance, VkSurface
return kvfPickGoodPhysicalDevice(instance, surface, extensions, sizeof(extensions) / sizeof(extensions[0])); return kvfPickGoodPhysicalDevice(instance, surface, extensions, sizeof(extensions) / sizeof(extensions[0]));
} }
int32_t __kvfScorePhysicalDevice(VkPhysicalDevice device, VkSurfaceKHR surface, const char** deviceExtensions, uint32_t deviceExtensionsCount) int32_t __kvfScorePhysicalDevice(VkPhysicalDevice device, VkSurfaceKHR surface, const char** device_extensions, uint32_t device_extensions_count)
{ {
/* Check Extensions Support */ /* Check extensions support */
uint32_t extension_count; uint32_t extension_count;
vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, NULL); vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, NULL);
VkExtensionProperties* props = (VkExtensionProperties*)KVF_MALLOC(sizeof(VkExtensionProperties) * extension_count + 1); VkExtensionProperties* props = (VkExtensionProperties*)KVF_MALLOC(sizeof(VkExtensionProperties) * extension_count + 1);
vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, props); vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, props);
bool are_there_required_device_extensions = true; bool are_there_required_device_extensions = true;
for(int j = 0; j < deviceExtensionsCount; j++) for(int j = 0; j < device_extensions_count; j++)
{ {
bool is_there_extension = false; bool is_there_extension = false;
for(int k = 0; k < extension_count; k++) for(int k = 0; k < extension_count; k++)
{ {
if(strcmp(deviceExtensions[j], props[k].extensionName) == 0) if(strcmp(device_extensions[j], props[k].extensionName) == 0)
{ {
is_there_extension = true; is_there_extension = true;
break; break;
@@ -1162,14 +1224,19 @@ int32_t __kvfScorePhysicalDevice(VkPhysicalDevice device, VkSurfaceKHR surface,
/* Check Queue Families Support */ /* Check Queue Families Support */
__KvfQueueFamilies queues = __kvfFindQueueFamilies(device, surface); __KvfQueueFamilies queues = __kvfFindQueueFamilies(device, surface);
if(queues.graphics == -1 || queues.present == -1) if(queues.graphics == -1 || (surface != VK_NULL_HANDLE && queues.present == -1))
return -1; return -1;
/* Check Surface Formats Counts */ #ifndef KVF_NO_KHR
if(surface != VK_NULL_HANDLE)
{
/* Check surface formats counts */
uint32_t format_count; uint32_t format_count;
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, NULL); vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, NULL);
if(format_count == 0) if(format_count == 0)
return -1; return -1;
}
#endif
VkPhysicalDeviceProperties device_props; VkPhysicalDeviceProperties device_props;
vkGetPhysicalDeviceProperties(device, &device_props); vkGetPhysicalDeviceProperties(device, &device_props);
@@ -1190,7 +1257,7 @@ int32_t __kvfScorePhysicalDevice(VkPhysicalDevice device, VkSurfaceKHR surface,
return score; return score;
} }
VkPhysicalDevice kvfPickGoodPhysicalDevice(VkInstance instance, VkSurfaceKHR surface, const char** deviceExtensions, uint32_t deviceExtensionsCount) VkPhysicalDevice kvfPickGoodPhysicalDevice(VkInstance instance, VkSurfaceKHR surface, const char** device_extensions, uint32_t device_extensions_count)
{ {
VkPhysicalDevice* devices = NULL; VkPhysicalDevice* devices = NULL;
VkPhysicalDevice chosen_one = VK_NULL_HANDLE; VkPhysicalDevice chosen_one = VK_NULL_HANDLE;
@@ -1198,7 +1265,6 @@ VkPhysicalDevice kvfPickGoodPhysicalDevice(VkInstance instance, VkSurfaceKHR sur
int32_t best_device_score = -1; int32_t best_device_score = -1;
KVF_ASSERT(instance != VK_NULL_HANDLE); KVF_ASSERT(instance != VK_NULL_HANDLE);
KVF_ASSERT(surface != VK_NULL_HANDLE);
vkEnumeratePhysicalDevices(instance, &device_count, NULL); vkEnumeratePhysicalDevices(instance, &device_count, NULL);
devices = (VkPhysicalDevice*)KVF_MALLOC(sizeof(VkPhysicalDevice) * device_count + 1); devices = (VkPhysicalDevice*)KVF_MALLOC(sizeof(VkPhysicalDevice) * device_count + 1);
@@ -1206,7 +1272,7 @@ VkPhysicalDevice kvfPickGoodPhysicalDevice(VkInstance instance, VkSurfaceKHR sur
for(int i = 0; i < device_count; i++) for(int i = 0; i < device_count; i++)
{ {
int32_t current_device_score = __kvfScorePhysicalDevice(devices[i], surface, deviceExtensions, deviceExtensionsCount); int32_t current_device_score = __kvfScorePhysicalDevice(devices[i], surface, device_extensions, device_extensions_count);
if(current_device_score > best_device_score) if(current_device_score > best_device_score)
{ {
best_device_score = current_device_score; best_device_score = current_device_score;
@@ -1217,7 +1283,7 @@ VkPhysicalDevice kvfPickGoodPhysicalDevice(VkInstance instance, VkSurfaceKHR sur
if(chosen_one != VK_NULL_HANDLE) if(chosen_one != VK_NULL_HANDLE)
{ {
__KvfQueueFamilies queues = __kvfFindQueueFamilies(chosen_one, surface); __KvfQueueFamilies queues = __kvfFindQueueFamilies(chosen_one, surface);
__kvfAddDeviceToArray(chosen_one, queues.graphics, queues.present); __kvfAddDeviceToArray(chosen_one, queues.graphics, queues.present, queues.compute);
return chosen_one; return chosen_one;
} }
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
@@ -1237,27 +1303,49 @@ VkDevice kvfCreateDevice(VkPhysicalDevice physical, const char** extensions, uin
__KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkPhysicalDevice(physical); __KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkPhysicalDevice(physical);
KVF_ASSERT(kvfdevice != NULL); KVF_ASSERT(kvfdevice != NULL);
KVF_ASSERT(kvfdevice->queues.graphics != -1);
KVF_ASSERT(kvfdevice->queues.present != -1);
VkDeviceQueueCreateInfo queue_create_info[2]; uint32_t queue_count = 0;
queue_create_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_count += (kvfdevice->queues.graphics != -1);
queue_create_info[0].queueFamilyIndex = kvfdevice->queues.graphics; queue_count += (kvfdevice->queues.present != -1);
queue_create_info[0].queueCount = 1; queue_count += (kvfdevice->queues.compute != -1);
queue_create_info[0].pQueuePriorities = &queue_priority;
queue_create_info[0].flags = 0; VkDeviceQueueCreateInfo* queue_create_infos = (VkDeviceQueueCreateInfo*)KVF_MALLOC(queue_count * sizeof(VkDeviceQueueCreateInfo));
queue_create_info[0].pNext = NULL; size_t i = 0;
queue_create_info[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; if(kvfdevice->queues.graphics != -1)
queue_create_info[1].queueFamilyIndex = kvfdevice->queues.present; {
queue_create_info[1].queueCount = 1; queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_info[1].pQueuePriorities = &queue_priority; queue_create_infos[i].queueFamilyIndex = kvfdevice->queues.graphics;
queue_create_info[1].flags = 0; queue_create_infos[i].queueCount = 1;
queue_create_info[1].pNext = NULL; queue_create_infos[i].pQueuePriorities = &queue_priority;
queue_create_infos[i].flags = 0;
queue_create_infos[i].pNext = NULL;
i++;
}
if(kvfdevice->queues.present != -1 && kvfdevice->queues.present != kvfdevice->queues.graphics)
{
queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_infos[i].queueFamilyIndex = kvfdevice->queues.present;
queue_create_infos[i].queueCount = 1;
queue_create_infos[i].pQueuePriorities = &queue_priority;
queue_create_infos[i].flags = 0;
queue_create_infos[i].pNext = NULL;
i++;
}
if(kvfdevice->queues.compute != -1 && kvfdevice->queues.present != kvfdevice->queues.compute && kvfdevice->queues.graphics != kvfdevice->queues.compute)
{
queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_infos[i].queueFamilyIndex = kvfdevice->queues.compute;
queue_create_infos[i].queueCount = 1;
queue_create_infos[i].pQueuePriorities = &queue_priority;
queue_create_infos[i].flags = 0;
queue_create_infos[i].pNext = NULL;
i++;
}
VkDeviceCreateInfo createInfo; VkDeviceCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.queueCreateInfoCount = (kvfdevice->queues.graphics == kvfdevice->queues.present ? 1 : 2); createInfo.queueCreateInfoCount = i;
createInfo.pQueueCreateInfos = queue_create_info; createInfo.pQueueCreateInfos = queue_create_infos;
createInfo.pEnabledFeatures = features; createInfo.pEnabledFeatures = features;
createInfo.enabledExtensionCount = extensions_count; createInfo.enabledExtensionCount = extensions_count;
createInfo.ppEnabledExtensionNames = extensions; createInfo.ppEnabledExtensionNames = extensions;
@@ -1273,6 +1361,74 @@ VkDevice kvfCreateDevice(VkPhysicalDevice physical, const char** extensions, uin
return device; return device;
} }
VkDevice kvfCreateDefaultDevicePhysicalDeviceAndCustomQueues(VkPhysicalDevice physical, int32_t graphics_queue, int32_t present_queue, int32_t compute_queue)
{
const char* extensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
VkPhysicalDeviceFeatures device_features = { VK_FALSE };
return kvfCreateDeviceCustomPhysicalDeviceAndQueues(physical, extensions, sizeof(extensions) / sizeof(extensions[0]), &device_features, graphics_queue, present_queue, compute_queue);
}
VkDevice kvfCreateDeviceCustomPhysicalDeviceAndQueues(VkPhysicalDevice physical, const char** extensions, uint32_t extensions_count, VkPhysicalDeviceFeatures* features, int32_t graphics_queue, int32_t present_queue, int32_t compute_queue)
{
const float queue_priority = 1.0f;
uint32_t queue_count = 0;
queue_count += (graphics_queue != -1);
queue_count += (present_queue != -1);
queue_count += (compute_queue != -1);
VkDeviceQueueCreateInfo* queue_create_infos = (VkDeviceQueueCreateInfo*)KVF_MALLOC(queue_count * sizeof(VkDeviceQueueCreateInfo));
size_t i = 0;
if(graphics_queue != -1)
{
queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_infos[i].queueFamilyIndex = graphics_queue;
queue_create_infos[i].queueCount = 1;
queue_create_infos[i].pQueuePriorities = &queue_priority;
queue_create_infos[i].flags = 0;
queue_create_infos[i].pNext = NULL;
i++;
}
if(present_queue != -1 && present_queue != graphics_queue)
{
queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_infos[i].queueFamilyIndex = present_queue;
queue_create_infos[i].queueCount = 1;
queue_create_infos[i].pQueuePriorities = &queue_priority;
queue_create_infos[i].flags = 0;
queue_create_infos[i].pNext = NULL;
i++;
}
if(compute_queue != -1 && present_queue != compute_queue && graphics_queue != compute_queue)
{
queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_infos[i].queueFamilyIndex = compute_queue;
queue_create_infos[i].queueCount = 1;
queue_create_infos[i].pQueuePriorities = &queue_priority;
queue_create_infos[i].flags = 0;
queue_create_infos[i].pNext = NULL;
i++;
}
VkDeviceCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.queueCreateInfoCount = queue_count;
createInfo.pQueueCreateInfos = queue_create_infos;
createInfo.pEnabledFeatures = features;
createInfo.enabledExtensionCount = extensions_count;
createInfo.ppEnabledExtensionNames = extensions;
createInfo.enabledLayerCount = 0;
createInfo.ppEnabledLayerNames = NULL;
createInfo.flags = 0;
createInfo.pNext = NULL;
VkDevice device;
__kvfCheckVk(vkCreateDevice(physical, &createInfo, NULL, &device));
__kvfCompleteDeviceCustomPhysicalDeviceAndQueues(physical, device, graphics_queue, present_queue, compute_queue);
return device;
}
void kvfDestroyDevice(VkDevice device) void kvfDestroyDevice(VkDevice device)
{ {
if(device == VK_NULL_HANDLE) if(device == VK_NULL_HANDLE)
@@ -1287,11 +1443,20 @@ VkQueue kvfGetDeviceQueue(VkDevice device, KvfQueueType queue)
KVF_ASSERT(kvfdevice != NULL); KVF_ASSERT(kvfdevice != NULL);
VkQueue vk_queue = VK_NULL_HANDLE; VkQueue vk_queue = VK_NULL_HANDLE;
if(queue == KVF_GRAPHICS_QUEUE) if(queue == KVF_GRAPHICS_QUEUE)
{
KVF_ASSERT(kvfdevice->queues.graphics != -1);
vkGetDeviceQueue(device, kvfdevice->queues.graphics, 0, &vk_queue); vkGetDeviceQueue(device, kvfdevice->queues.graphics, 0, &vk_queue);
}
else if(queue == KVF_PRESENT_QUEUE) else if(queue == KVF_PRESENT_QUEUE)
{
KVF_ASSERT(kvfdevice->queues.present != -1);
vkGetDeviceQueue(device, kvfdevice->queues.present, 0, &vk_queue); vkGetDeviceQueue(device, kvfdevice->queues.present, 0, &vk_queue);
}
else if(queue == KVF_COMPUTE_QUEUE) else if(queue == KVF_COMPUTE_QUEUE)
{
KVF_ASSERT(kvfdevice->queues.compute != -1);
vkGetDeviceQueue(device, kvfdevice->queues.compute, 0, &vk_queue); vkGetDeviceQueue(device, kvfdevice->queues.compute, 0, &vk_queue);
}
return vk_queue; return vk_queue;
} }
@@ -1311,8 +1476,9 @@ uint32_t kvfGetDeviceQueueFamily(VkDevice device, KvfQueueType queue)
return 0; return 0;
} }
bool kvfQueuePresentKHR(VkDevice device, VkSemaphore wait, VkSwapchainKHR swapchain, uint32_t image_index) #ifndef KVF_NO_KHR
{ bool kvfQueuePresentKHR(VkDevice device, VkSemaphore wait, VkSwapchainKHR swapchain, uint32_t image_index)
{
KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(device != VK_NULL_HANDLE);
VkPresentInfoKHR present_info = {}; VkPresentInfoKHR present_info = {};
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
@@ -1327,8 +1493,73 @@ bool kvfQueuePresentKHR(VkDevice device, VkSemaphore wait, VkSwapchainKHR swapch
else else
__kvfCheckVk(result); __kvfCheckVk(result);
return true; return true;
}
#endif
int32_t kvfFindDeviceQueueFamily(VkPhysicalDevice physical, KvfQueueType type)
{
KVF_ASSERT(physical != VK_NULL_HANDLE);
KVF_ASSERT(type != KVF_PRESENT_QUEUE && "Use kvfFindDeviceQueueFamilyKHR to find present queue");
uint32_t queue_family_count;
vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, NULL);
VkQueueFamilyProperties* queue_families = (VkQueueFamilyProperties*)KVF_MALLOC(sizeof(VkQueueFamilyProperties) * queue_family_count);
vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, queue_families);
int32_t queue = -1;
for(int i = 0; i < queue_family_count; i++)
{
if(type == KVF_COMPUTE_QUEUE)
{
if(queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT && (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)
queue = i;
else if(queue != -1 && queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) // else just find a compute queue
queue = i;
}
else if(type == KVF_GRAPHICS_QUEUE)
{
if(queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
queue = i;
}
if(queue != -1)
break;
}
KVF_FREE(queue_families);
return queue;
} }
#ifndef KVF_NO_KHR
int32_t kvfFindDeviceQueueFamilyKHR(VkPhysicalDevice physical, VkSurfaceKHR surface, KvfQueueType type)
{
KVF_ASSERT(physical != VK_NULL_HANDLE);
KVF_ASSERT(surface != VK_NULL_HANDLE);
if(type != KVF_PRESENT_QUEUE)
return kvfFindDeviceQueueFamily(physical, type);
uint32_t queue_family_count;
vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, NULL);
VkQueueFamilyProperties* queue_families = (VkQueueFamilyProperties*)KVF_MALLOC(sizeof(VkQueueFamilyProperties) * queue_family_count);
vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, queue_families);
int32_t queue = -1;
for(int i = 0; i < queue_family_count; i++)
{
VkBool32 present_support = false;
vkGetPhysicalDeviceSurfaceSupportKHR(physical, i, surface, &present_support);
if(present_support)
queue = i;
if(queue != -1)
break;
}
KVF_FREE(queue_families);
return queue;
}
#endif
VkFence kvfCreateFence(VkDevice device) VkFence kvfCreateFence(VkDevice device)
{ {
KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(device != VK_NULL_HANDLE);
@@ -1373,73 +1604,74 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore)
vkDestroySemaphore(device, semaphore, NULL); vkDestroySemaphore(device, semaphore, NULL);
} }
__KvfSwapchainSupportInternal __kvfQuerySwapchainSupport(VkPhysicalDevice physical, VkSurfaceKHR surface) #ifndef KVF_NO_KHR
{ __KvfSwapchainSupportInternal __kvfQuerySwapchainSupport(VkPhysicalDevice physical, VkSurfaceKHR surface)
{
__KvfSwapchainSupportInternal support; __KvfSwapchainSupportInternal support;
__kvfCheckVk(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical, surface, &support.capabilities)); __kvfCheckVk(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical, surface, &support.capabilities));
vkGetPhysicalDeviceSurfaceFormatsKHR(physical, surface, &support.formatsCount, NULL); vkGetPhysicalDeviceSurfaceFormatsKHR(physical, surface, &support.formats_count, NULL);
if(support.formatsCount != 0) if(support.formats_count != 0)
{ {
support.formats = (VkSurfaceFormatKHR*)KVF_MALLOC(sizeof(VkSurfaceFormatKHR) * support.formatsCount); support.formats = (VkSurfaceFormatKHR*)KVF_MALLOC(sizeof(VkSurfaceFormatKHR) * support.formats_count);
vkGetPhysicalDeviceSurfaceFormatsKHR(physical, surface, &support.formatsCount, support.formats); vkGetPhysicalDeviceSurfaceFormatsKHR(physical, surface, &support.formats_count, support.formats);
} }
vkGetPhysicalDeviceSurfacePresentModesKHR(physical, surface, &support.presentModesCount, NULL); vkGetPhysicalDeviceSurfacePresentModesKHR(physical, surface, &support.presentModes_count, NULL);
if(support.presentModesCount != 0) if(support.presentModes_count != 0)
{ {
support.presentModes = (VkPresentModeKHR*)KVF_MALLOC(sizeof(VkPresentModeKHR) * support.presentModesCount); support.presentModes = (VkPresentModeKHR*)KVF_MALLOC(sizeof(VkPresentModeKHR) * support.presentModes_count);
vkGetPhysicalDeviceSurfacePresentModesKHR(physical, surface, &support.presentModesCount, support.presentModes); vkGetPhysicalDeviceSurfacePresentModesKHR(physical, surface, &support.presentModes_count, support.presentModes);
} }
return support; return support;
} }
VkSurfaceFormatKHR __kvfChooseSwapSurfaceFormat(__KvfSwapchainSupportInternal* support) VkSurfaceFormatKHR __kvfChooseSwapSurfaceFormat(__KvfSwapchainSupportInternal* support)
{ {
for(int i = 0; i < support->formatsCount; i++) for(int i = 0; i < support->formats_count; i++)
{ {
if(support->formats[i].format == VK_FORMAT_R8G8B8A8_SRGB && support->formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) if(support->formats[i].format == VK_FORMAT_R8G8B8A8_SRGB && support->formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
return support->formats[i]; return support->formats[i];
} }
return support->formats[0]; return support->formats[0];
} }
VkPresentModeKHR __kvfChooseSwapPresentMode(__KvfSwapchainSupportInternal* support, bool tryVsync) VkPresentModeKHR __kvfChooseSwapPresentMode(__KvfSwapchainSupportInternal* support, bool try_vsync)
{ {
if(tryVsync == false) if(try_vsync == false)
return VK_PRESENT_MODE_IMMEDIATE_KHR; return VK_PRESENT_MODE_IMMEDIATE_KHR;
for(int i = 0; i < support->presentModesCount; i++) for(int i = 0; i < support->presentModes_count; i++)
{ {
if(support->presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) if(support->presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
return support->presentModes[i]; return support->presentModes[i];
} }
return VK_PRESENT_MODE_FIFO_KHR; return VK_PRESENT_MODE_FIFO_KHR;
} }
uint32_t __kvfClamp(uint32_t i, uint32_t min, uint32_t max) uint32_t __kvfClamp(uint32_t i, uint32_t min, uint32_t max)
{ {
const uint32_t t = i < min ? min : i; const uint32_t t = i < min ? min : i;
return t > max ? max : t; return t > max ? max : t;
} }
VkSwapchainKHR kvfCreateSwapchainKHR(VkDevice device, VkPhysicalDevice physical, VkSurfaceKHR surface, VkExtent2D extent, bool tryVsync) VkSwapchainKHR kvfCreateSwapchainKHR(VkDevice device, VkPhysicalDevice physical, VkSurfaceKHR surface, VkExtent2D extent, bool try_vsync)
{ {
KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(device != VK_NULL_HANDLE);
VkSwapchainKHR swapchain; VkSwapchainKHR swapchain;
__KvfSwapchainSupportInternal support = __kvfQuerySwapchainSupport(physical, surface); __KvfSwapchainSupportInternal support = __kvfQuerySwapchainSupport(physical, surface);
VkSurfaceFormatKHR surfaceFormat = __kvfChooseSwapSurfaceFormat(&support); VkSurfaceFormatKHR surfaceFormat = __kvfChooseSwapSurfaceFormat(&support);
VkPresentModeKHR presentMode = __kvfChooseSwapPresentMode(&support, tryVsync); VkPresentModeKHR presentMode = __kvfChooseSwapPresentMode(&support, try_vsync);
uint32_t imageCount = support.capabilities.minImageCount + 1; uint32_t image_count = support.capabilities.minImageCount + 1;
if(support.capabilities.maxImageCount > 0 && imageCount > support.capabilities.maxImageCount) if(support.capabilities.maxImageCount > 0 && image_count > support.capabilities.maxImageCount)
imageCount = support.capabilities.maxImageCount; image_count = support.capabilities.maxImageCount;
__KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkDevice(device); __KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkDevice(device);
KVF_ASSERT(kvfdevice != NULL); KVF_ASSERT(kvfdevice != NULL);
uint32_t queueFamilyIndices[] = { (uint32_t)kvfdevice->queues.graphics, (uint32_t)kvfdevice->queues.present }; uint32_t queue_family_indices[] = { (uint32_t)kvfdevice->queues.graphics, (uint32_t)kvfdevice->queues.present };
if(support.capabilities.currentExtent.width != UINT32_MAX) if(support.capabilities.currentExtent.width != UINT32_MAX)
extent = support.capabilities.currentExtent; extent = support.capabilities.currentExtent;
@@ -1452,7 +1684,7 @@ VkSwapchainKHR kvfCreateSwapchainKHR(VkDevice device, VkPhysicalDevice physical,
VkSwapchainCreateInfoKHR createInfo = {}; VkSwapchainCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = surface; createInfo.surface = surface;
createInfo.minImageCount = imageCount; createInfo.minImageCount = image_count;
createInfo.imageFormat = surfaceFormat.format; createInfo.imageFormat = surfaceFormat.format;
createInfo.imageColorSpace = surfaceFormat.colorSpace; createInfo.imageColorSpace = surfaceFormat.colorSpace;
createInfo.imageExtent = extent; createInfo.imageExtent = extent;
@@ -1468,7 +1700,7 @@ VkSwapchainKHR kvfCreateSwapchainKHR(VkDevice device, VkPhysicalDevice physical,
{ {
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
createInfo.queueFamilyIndexCount = 2; createInfo.queueFamilyIndexCount = 2;
createInfo.pQueueFamilyIndices = queueFamilyIndices; createInfo.pQueueFamilyIndices = queue_family_indices;
} }
else else
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
@@ -1481,43 +1713,44 @@ VkSwapchainKHR kvfCreateSwapchainKHR(VkDevice device, VkPhysicalDevice physical,
__kvfAddSwapchainToArray(swapchain, support, surfaceFormat.format, images_count, extent); __kvfAddSwapchainToArray(swapchain, support, surfaceFormat.format, images_count, extent);
return swapchain; return swapchain;
} }
VkFormat kvfGetSwapchainImagesFormat(VkSwapchainKHR swapchain) VkFormat kvfGetSwapchainImagesFormat(VkSwapchainKHR swapchain)
{ {
__KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain); __KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain);
KVF_ASSERT(kvf_swapchain != NULL); KVF_ASSERT(kvf_swapchain != NULL);
return kvf_swapchain->images_format; return kvf_swapchain->images_format;
} }
uint32_t kvfGetSwapchainImagesCount(VkSwapchainKHR swapchain) uint32_t kvfGetSwapchainImagesCount(VkSwapchainKHR swapchain)
{ {
__KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain); __KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain);
KVF_ASSERT(kvf_swapchain != NULL); KVF_ASSERT(kvf_swapchain != NULL);
return kvf_swapchain->images_count; return kvf_swapchain->images_count;
} }
uint32_t kvfGetSwapchainMinImagesCount(VkSwapchainKHR swapchain) uint32_t kvfGetSwapchainMinImagesCount(VkSwapchainKHR swapchain)
{ {
__KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain); __KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain);
KVF_ASSERT(kvf_swapchain != NULL); KVF_ASSERT(kvf_swapchain != NULL);
return kvf_swapchain->support.capabilities.minImageCount; return kvf_swapchain->support.capabilities.minImageCount;
} }
VkExtent2D kvfGetSwapchainImagesSize(VkSwapchainKHR swapchain) VkExtent2D kvfGetSwapchainImagesSize(VkSwapchainKHR swapchain)
{ {
__KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain); __KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain);
KVF_ASSERT(kvf_swapchain != NULL); KVF_ASSERT(kvf_swapchain != NULL);
return kvf_swapchain->images_extent; return kvf_swapchain->images_extent;
} }
void kvfDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain) void kvfDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain)
{ {
if(swapchain == VK_NULL_HANDLE) if(swapchain == VK_NULL_HANDLE)
return; return;
KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(device != VK_NULL_HANDLE);
__kvfDestroySwapchain(device, swapchain); __kvfDestroySwapchain(device, swapchain);
} }
#endif
VkImage kvfCreateImage(VkDevice device, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, KvfImageType type) VkImage kvfCreateImage(VkDevice device, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, KvfImageType type)
{ {
@@ -1564,7 +1797,7 @@ void kvfImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage src, size_t buf
region.imageSubresource.layerCount = 1; region.imageSubresource.layerCount = 1;
region.imageOffset = offset; region.imageOffset = offset;
region.imageExtent = extent; region.imageExtent = extent;
vkCmdCopyImageToBuffer(cmd, src, dst, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, &region); vkCmdCopyImageToBuffer(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst, 1, &region);
} }
void kvfDestroyImage(VkDevice device, VkImage image) void kvfDestroyImage(VkDevice device, VkImage image)
@@ -1899,13 +2132,15 @@ VkAttachmentDescription kvfBuildAttachmentDescription(KvfImageType type, VkForma
return attachment; return attachment;
} }
VkAttachmentDescription kvfBuildSwapchainAttachmentDescription(VkSwapchainKHR swapchain, bool clear) #ifndef KVF_NO_KHR
{ VkAttachmentDescription kvfBuildSwapchainAttachmentDescription(VkSwapchainKHR swapchain, bool clear)
{
__KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain); __KvfSwapchain* kvf_swapchain = __kvfGetKvfSwapchainFromVkSwapchainKHR(swapchain);
KVF_ASSERT(kvf_swapchain != NULL); KVF_ASSERT(kvf_swapchain != NULL);
KVF_ASSERT(kvf_swapchain->images_count != 0); KVF_ASSERT(kvf_swapchain->images_count != 0);
return kvfBuildAttachmentDescription(KVF_IMAGE_COLOR, kvf_swapchain->images_format, VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, clear, VK_SAMPLE_COUNT_1_BIT); return kvfBuildAttachmentDescription(KVF_IMAGE_COLOR, kvf_swapchain->images_format, VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, clear, VK_SAMPLE_COUNT_1_BIT);
} }
#endif
VkRenderPass kvfCreateRenderPass(VkDevice device, VkAttachmentDescription* attachments, size_t attachments_count, VkPipelineBindPoint bind_point) VkRenderPass kvfCreateRenderPass(VkDevice device, VkAttachmentDescription* attachments, size_t attachments_count, VkPipelineBindPoint bind_point)
{ {