diff --git a/kvf.h b/kvf.h index 47d430c..acb29b2 100755 --- a/kvf.h +++ b/kvf.h @@ -41,6 +41,7 @@ * * If you are using Volk or any other meta loader you must define KVF_IMPL_VK_NO_PROTOTYPES * or VK_NO_PROTOTYPES before including this file to avoid conflicts with Vulkan prototypes. + * You will also need to pass the function pointers to kvf using dedicated functions. * * You can also #define KVF_ENABLE_VALIDATION_LAYERS to enable validation layers. * @@ -50,6 +51,7 @@ #ifndef KBZ_8_VULKAN_FRAMEWORK_H #define KBZ_8_VULKAN_FRAMEWORK_H +#include "vulkan/vulkan_core.h" #ifdef KVF_IMPL_VK_NO_PROTOTYPES #define VK_NO_PROTOTYPES #endif @@ -83,12 +85,22 @@ typedef enum typedef void (*KvfErrorCallback)(const char* message); +#ifdef KVF_IMPL_VK_NO_PROTOTYPES + typedef struct KvfGlobalVulkanFunctions KvfGlobalVulkanFunctions; + typedef struct KvfDeviceVulkanFunctions KvfDeviceVulkanFunctions; + typedef struct KvfInstanceVulkanFunctions KvfInstanceVulkanFunctions; +#endif typedef struct KvfGraphicsPipelineBuilder KvfGraphicsPipelineBuilder; void kvfSetErrorCallback(KvfErrorCallback callback); void kvfSetValidationErrorCallback(KvfErrorCallback callback); void kvfSetValidationWarningCallback(KvfErrorCallback callback); +#ifdef KVF_IMPL_VK_NO_PROTOTYPES + void kvfPassGlobalVulkanFunctionPointers(const KvfGlobalVulkanFunctions* fns); + void kvfPassInstanceVulkanFunctionPointers(const KvfInstanceVulkanFunctions* fns); +#endif + void kvfAddLayer(const char* layer); VkInstance kvfCreateInstance(const char** extensions_enabled, uint32_t extensions_count); @@ -115,6 +127,9 @@ VkDevice kvfCreateDefaultDevice(VkPhysicalDevice physical); 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); +#ifdef KVF_IMPL_VK_NO_PROTOTYPES + void kvfPassDeviceVulkanFunctionPointers(VkDevice device, const KvfDeviceVulkanFunctions* fns); +#endif void kvfDestroyDevice(VkDevice device); VkFence kvfCreateFence(VkDevice device); @@ -134,7 +149,7 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore); #endif 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 buffer_offset, VkImageAspectFlagBits aspect, VkExtent3D extent); +void kvfCopyImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage src, size_t buffer_offset, VkImageAspectFlagBits aspect, VkExtent3D extent); void kvfDestroyImage(VkDevice device, VkImage image); VkImageView kvfCreateImageView(VkDevice device, VkImage image, VkFormat format, VkImageViewType type, VkImageAspectFlags aspect, int layer_count); void kvfDestroyImageView(VkDevice device, VkImageView image_view); @@ -219,6 +234,102 @@ void kvfDestroyPipeline(VkDevice device, VkPipeline pipeline); void kvfCheckVk(VkResult result); +#ifdef KVF_IMPL_VK_NO_PROTOTYPES + #ifdef KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE + #undef KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE + #endif + #define KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(fn) PFN_##fn fn + + struct KvfGlobalVulkanFunctions + { + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateInstance); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkEnumerateInstanceExtensionProperties); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkEnumerateInstanceLayerProperties); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetInstanceProcAddr); + }; + + struct KvfInstanceVulkanFunctions + { + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateDevice); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyInstance); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkEnumerateDeviceExtensionProperties); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkEnumeratePhysicalDevices); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceFeatures); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceFormatProperties); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceImageFormatProperties); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceMemoryProperties); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceProperties); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceQueueFamilyProperties); + #ifndef KVF_NO_KHR + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroySurfaceKHR); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceSurfaceFormatsKHR); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceSurfacePresentModesKHR); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceSurfaceSupportKHR); + #endif + }; + + struct KvfDeviceVulkanFunctions + { + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkAllocateCommandBuffers); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkAllocateDescriptorSets); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkBeginCommandBuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCmdBeginRenderPass); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCmdCopyBuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCmdCopyBufferToImage); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCmdCopyImage); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCmdCopyImageToBuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCmdEndRenderPass); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCmdPipelineBarrier); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateBuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateCommandPool); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateDescriptorPool); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateDescriptorSetLayout); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateFence); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateFramebuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateGraphicsPipelines); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateImage); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateImageView); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreatePipelineLayout); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateRenderPass); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateSampler); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateSemaphore); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateShaderModule); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyBuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyCommandPool); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyDescriptorPool); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyDescriptorSetLayout); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyDevice); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyFence); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyFramebuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyImage); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyImageView); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyPipeline); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyPipelineLayout); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyRenderPass); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroySampler); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroySemaphore); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyShaderModule); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDeviceWaitIdle); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkEndCommandBuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetDeviceQueue); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetImageSubresourceLayout); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkQueueSubmit); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkResetCommandBuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkResetDescriptorPool); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkResetEvent); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkResetFences); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkUpdateDescriptorSets); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkWaitForFences); + #ifndef KVF_NO_KHR + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateSwapchainKHR); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroySwapchainKHR); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetSwapchainImagesKHR); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkQueuePresentKHR); + #endif + }; +#endif + #ifdef __cplusplus } #endif @@ -243,6 +354,16 @@ void kvfCheckVk(VkResult result); #define KVF_ASSERT(x) assert(x) #endif +#ifdef KVF_IMPL_VK_NO_PROTOTYPES + #define KVF_GET_GLOBAL_FUNCTION(fn) __kvf_g_fns.fn + #define KVF_GET_INSTANCE_FUNCTION(fn) __kvf_i_fns.fn + #define KVF_GET_DEVICE_FUNCTION(fn) kvf_device->fns.fn +#else + #define KVF_GET_GLOBAL_FUNCTION(fn) fn + #define KVF_GET_INSTANCE_FUNCTION(fn) fn + #define KVF_GET_DEVICE_FUNCTION(fn) fn +#endif + #include #include #include @@ -252,6 +373,11 @@ void kvfCheckVk(VkResult result); #endif #define KVF_DESCRIPTOR_POOL_CAPACITY 512 +#ifdef KVF_COMMAND_POOL_CAPACITY + #undef KVF_COMMAND_POOL_CAPACITY +#endif +#define KVF_COMMAND_POOL_CAPACITY 512 + typedef struct { int32_t graphics; @@ -259,25 +385,31 @@ typedef struct int32_t compute; } __KvfQueueFamilies; -typedef struct +typedef struct __KvfDescriptorPool { VkDescriptorPool pool; size_t capacity; size_t size; } __KvfDescriptorPool; -typedef struct +typedef struct __KvfDevice { + __KvfQueueFamilies queues; + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + KvfDeviceVulkanFunctions fns; + #endif VkDevice device; VkPhysicalDevice physical; VkCommandPool cmd_pool; - __KvfQueueFamilies queues; + VkCommandBuffer* cmd_buffers = NULL; __KvfDescriptorPool* sets_pools; + size_t cmd_buffers_size = 0; + size_t cmd_buffers_capacity = 0; size_t sets_pools_size; } __KvfDevice; #ifndef KVF_NO_KHR - typedef struct + typedef struct __KvfSwapchainSupportInternal { VkSurfaceCapabilitiesKHR capabilities; VkSurfaceFormatKHR* formats; @@ -286,7 +418,7 @@ typedef struct uint32_t presentModes_count; } __KvfSwapchainSupportInternal; - typedef struct + typedef struct __KvfSwapchain { __KvfSwapchainSupportInternal support; VkSwapchainKHR swapchain; @@ -296,7 +428,7 @@ typedef struct } __KvfSwapchain; #endif -typedef struct +typedef struct __KvfFramebuffer { VkFramebuffer framebuffer; VkExtent2D extent; @@ -340,6 +472,11 @@ KvfErrorCallback __kvf_error_callback = NULL; KvfErrorCallback __kvf_validation_error_callback = NULL; KvfErrorCallback __kvf_validation_warning_callback = NULL; +#ifdef KVF_IMPL_VK_NO_PROTOTYPES + KvfGlobalVulkanFunctions __kvf_g_fns; + KvfInstanceVulkanFunctions __kvf_i_fns; +#endif + void __kvfCheckVk(VkResult result, const char* function) { if(result != VK_SUCCESS) @@ -403,12 +540,16 @@ void __kvfCompleteDevice(VkPhysicalDevice physical, VkDevice device) 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)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(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; + kvf_device->cmd_buffers_size = 0; + kvf_device->cmd_buffers_capacity = KVF_COMMAND_POOL_CAPACITY; + kvf_device->cmd_buffers = (VkCommandBuffer*)KVF_MALLOC(KVF_COMMAND_POOL_CAPACITY * sizeof(VkCommandBuffer)); + KVF_ASSERT(kvf_device->cmd_buffers != NULL && "allocation failed :("); } void __kvfCompleteDeviceCustomPhysicalDeviceAndQueues(VkPhysicalDevice physical, VkDevice device, int32_t graphics_queue, int32_t present_queue, int32_t compute_queue) @@ -433,12 +574,16 @@ void __kvfCompleteDeviceCustomPhysicalDeviceAndQueues(VkPhysicalDevice physical, 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)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(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; + kvf_device->cmd_buffers_size = 0; + kvf_device->cmd_buffers_capacity = KVF_COMMAND_POOL_CAPACITY; + kvf_device->cmd_buffers = (VkCommandBuffer*)KVF_MALLOC(KVF_COMMAND_POOL_CAPACITY * sizeof(VkCommandBuffer)); + KVF_ASSERT(kvf_device->cmd_buffers != NULL && "allocation failed :("); } void __kvfDestroyDescriptorPools(VkDevice device); @@ -450,9 +595,11 @@ void __kvfDestroyDevice(VkDevice device) { if(__kvf_internal_devices[i].device == device) { - vkDestroyCommandPool(device, __kvf_internal_devices[i].cmd_pool, NULL); + __KvfDevice* kvf_device = &__kvf_internal_devices[i]; + KVF_FREE(kvf_device->cmd_buffers); + KVF_GET_DEVICE_FUNCTION(vkDestroyCommandPool)(device, kvf_device->cmd_pool, NULL); __kvfDestroyDescriptorPools(device); - vkDestroyDevice(device, NULL); + KVF_GET_DEVICE_FUNCTION(vkDestroyDevice)(device, NULL); // Shift the elements to fill the gap for(size_t j = i; j < __kvf_internal_devices_size - 1; j++) __kvf_internal_devices[j] = __kvf_internal_devices[j + 1]; @@ -489,6 +636,20 @@ __KvfDevice* __kvfGetKvfDeviceFromVkDevice(VkDevice device) return NULL; } +__KvfDevice* __kvfGetKvfDeviceFromVkCommandBuffer(VkCommandBuffer cmd) +{ + KVF_ASSERT(cmd != VK_NULL_HANDLE); + for(size_t i = 0; i < __kvf_internal_devices_size; i++) + { + for(size_t j = 0; j < __kvf_internal_devices[i].cmd_buffers_size; j++) + { + if(__kvf_internal_devices[i].cmd_buffers[j] == cmd) + return &__kvf_internal_devices[i]; + } + } + return NULL; +} + #ifndef KVF_NO_KHR void __kvfAddSwapchainToArray(VkSwapchainKHR swapchain, __KvfSwapchainSupportInternal support, VkFormat format, uint32_t images_count, VkExtent2D extent) { @@ -513,11 +674,16 @@ __KvfDevice* __kvfGetKvfDeviceFromVkDevice(VkDevice device) KVF_ASSERT(swapchain != VK_NULL_HANDLE); KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + for(size_t i = 0; i < __kvf_internal_swapchains_size; i++) { if(__kvf_internal_swapchains[i].swapchain == swapchain) { - vkDestroySwapchainKHR(device, swapchain, NULL); + KVF_GET_DEVICE_FUNCTION(vkDestroySwapchainKHR)(device, swapchain, NULL); // Shift the elements to fill the gap for(size_t j = i; j < __kvf_internal_swapchains_size - 1; j++) __kvf_internal_swapchains[j] = __kvf_internal_swapchains[j + 1]; @@ -564,11 +730,16 @@ void __kvfDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer) KVF_ASSERT(framebuffer != VK_NULL_HANDLE); KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + for(size_t i = 0; i < __kvf_internal_framebuffers_size; i++) { if(__kvf_internal_framebuffers[i].framebuffer == framebuffer) { - vkDestroyFramebuffer(device, framebuffer, NULL); + KVF_GET_DEVICE_FUNCTION(vkDestroyFramebuffer)(device, framebuffer, NULL); // Shift the elements to fill the gap for(size_t j = i; j < __kvf_internal_framebuffers_size - 1; j++) __kvf_internal_framebuffers[j] = __kvf_internal_framebuffers[j + 1]; @@ -624,7 +795,7 @@ VkDescriptorPool __kvfDeviceCreateDescriptorPool(VkDevice device) pool_info.maxSets = KVF_DESCRIPTOR_POOL_CAPACITY; pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; - __kvfCheckVk(vkCreateDescriptorPool(device, &pool_info, NULL, &kvf_device->sets_pools[kvf_device->sets_pools_size - 1].pool)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateDescriptorPool)(device, &pool_info, NULL, &kvf_device->sets_pools[kvf_device->sets_pools_size - 1].pool)); kvf_device->sets_pools[kvf_device->sets_pools_size - 1].capacity = KVF_DESCRIPTOR_POOL_CAPACITY; return kvf_device->sets_pools[kvf_device->sets_pools_size - 1].pool; } @@ -636,7 +807,7 @@ void __kvfDestroyDescriptorPools(VkDevice device) KVF_ASSERT(kvf_device != NULL); for(size_t i = 0; i < kvf_device->sets_pools_size; i++) - vkDestroyDescriptorPool(device, kvf_device->sets_pools[i].pool, NULL); + KVF_GET_DEVICE_FUNCTION(vkDestroyDescriptorPool)(device, kvf_device->sets_pools[i].pool, NULL); KVF_FREE(kvf_device->sets_pools); kvf_device->sets_pools_size = 0; } @@ -656,6 +827,20 @@ void kvfSetValidationWarningCallback(KvfErrorCallback callback) __kvf_validation_warning_callback = callback; } +#ifdef KVF_IMPL_VK_NO_PROTOTYPES + void kvfPassGlobalVulkanFunctionPointers(const KvfGlobalVulkanFunctions* fns) + { + KVF_ASSERT(fns != NULL); + __kvf_g_fns = *fns; + } + + void kvfPassInstanceVulkanFunctionPointers(const KvfInstanceVulkanFunctions* fns) + { + KVF_ASSERT(fns != NULL); + __kvf_i_fns = *fns; + } +#endif + bool kvfIsStencilFormat(VkFormat format) { switch(format) @@ -763,7 +948,7 @@ VkFormat kvfFindSupportFormatInCandidates(VkDevice device, VkFormat* candidates, for(size_t i = 0; i < candidates_count; i++) { VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(kvf_device->physical, candidates[i], &props); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceFormatProperties)(kvf_device->physical, candidates[i], &props); if(tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & flags) == flags) return candidates[i]; else if(tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & flags) == flags) @@ -944,9 +1129,10 @@ const char* kvfVerbaliseVkResult(VkResult result) bool __kvfCheckValidationLayerSupport() { uint32_t layer_count; - vkEnumerateInstanceLayerProperties(&layer_count, NULL); + KVF_GET_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties)(&layer_count, NULL); VkLayerProperties* available_layers = (VkLayerProperties*)KVF_MALLOC(sizeof(VkLayerProperties) * layer_count); - vkEnumerateInstanceLayerProperties(&layer_count, available_layers); + KVF_ASSERT(available_layers != NULL && "allocation failed :("); + KVF_GET_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties)(&layer_count, available_layers); for(size_t i = 0; i < __kvf_extra_layers_count; i++) { bool found = false; @@ -970,6 +1156,8 @@ const char* kvfVerbaliseVkResult(VkResult result) VKAPI_ATTR VkBool32 VKAPI_CALL __kvfDebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) { + (void)messageType; + (void)pUserData; if(messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { if(__kvf_validation_error_callback != NULL) @@ -1005,16 +1193,17 @@ const char* kvfVerbaliseVkResult(VkResult result) VkResult __kvfCreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* create_info, VkDebugUtilsMessengerEXT* messenger) { - PFN_vkCreateDebugUtilsMessengerEXT func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); + PFN_vkCreateDebugUtilsMessengerEXT func = (PFN_vkCreateDebugUtilsMessengerEXT)KVF_GET_GLOBAL_FUNCTION(vkGetInstanceProcAddr)(instance, "vkCreateDebugUtilsMessengerEXT"); return func ? func(instance, create_info, NULL, messenger) : VK_ERROR_EXTENSION_NOT_PRESENT; } void __kvfInitValidationLayers(VkInstance instance) { uint32_t extension_count; - vkEnumerateInstanceExtensionProperties(NULL, &extension_count, NULL); + KVF_GET_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties)(NULL, &extension_count, NULL); VkExtensionProperties* extensions = (VkExtensionProperties*)KVF_MALLOC(extension_count * sizeof(VkExtensionProperties)); - vkEnumerateInstanceExtensionProperties(NULL, &extension_count, extensions); + KVF_ASSERT(extensions != NULL && "allocation failed :("); + KVF_GET_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties)(NULL, &extension_count, extensions); bool extension_found = false; for(uint32_t i = 0; i < extension_count; i++) { @@ -1044,7 +1233,7 @@ const char* kvfVerbaliseVkResult(VkResult result) void __kvfDestroyDebugUtilsMessengerEXT(VkInstance instance) { - PFN_vkDestroyDebugUtilsMessengerEXT func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); + PFN_vkDestroyDebugUtilsMessengerEXT func = (PFN_vkDestroyDebugUtilsMessengerEXT)KVF_GET_GLOBAL_FUNCTION(vkGetInstanceProcAddr)(instance, "vkDestroyDebugUtilsMessengerEXT"); if(func) func(instance, __kvf_debug_messenger, NULL); } @@ -1056,10 +1245,11 @@ void kvfAddLayer(const char* layer) __kvf_extra_layers = (char**)KVF_REALLOC(__kvf_extra_layers, sizeof(char*) * (__kvf_extra_layers_count + 1)); KVF_ASSERT(__kvf_extra_layers != NULL); __kvf_extra_layers[__kvf_extra_layers_count] = (char*)KVF_MALLOC(strlen(layer) + 1); - KVF_ASSERT(__kvf_extra_layers[__kvf_extra_layers_count] != NULL); + KVF_ASSERT(__kvf_extra_layers[__kvf_extra_layers_count] != NULL && "allocation failed :("); strcpy(__kvf_extra_layers[__kvf_extra_layers_count], layer); __kvf_extra_layers_count++; #else + (void)layer; if(__kvf_validation_error_callback != NULL) { char buffer[4096]; @@ -1078,12 +1268,16 @@ VkInstance kvfCreateInstance(const char** extensions_enabled, uint32_t extension VkInstanceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.pApplicationInfo = NULL; - create_info.flags = 0; create_info.enabledExtensionCount = extensions_count; create_info.ppEnabledExtensionNames = extensions_enabled; create_info.enabledLayerCount = 0; create_info.ppEnabledLayerNames = 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 kvfAddLayer("VK_LAYER_KHRONOS_validation"); @@ -1093,6 +1287,7 @@ VkInstance kvfCreateInstance(const char** extensions_enabled, uint32_t extension { __kvfPopulateDebugMessengerCreateInfo(&debug_create_info); new_extension_set = (const char**)KVF_MALLOC(sizeof(char*) * (extensions_count + 1)); + KVF_ASSERT(new_extension_set != NULL && "allocation failed :("); memcpy(new_extension_set, extensions_enabled, sizeof(char*) * extensions_count); new_extension_set[extensions_count] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; @@ -1104,7 +1299,7 @@ VkInstance kvfCreateInstance(const char** extensions_enabled, uint32_t extension } #endif - __kvfCheckVk(vkCreateInstance(&create_info, NULL, &instance)); + __kvfCheckVk(KVF_GET_GLOBAL_FUNCTION(vkCreateInstance)(&create_info, NULL, &instance)); #ifdef KVF_ENABLE_VALIDATION_LAYERS KVF_FREE(new_extension_set); __kvfInitValidationLayers(instance); @@ -1123,18 +1318,19 @@ void kvfDestroyInstance(VkInstance instance) KVF_FREE(__kvf_extra_layers); __kvf_extra_layers_count = 0; #endif - vkDestroyInstance(instance, NULL); + KVF_GET_INSTANCE_FUNCTION(vkDestroyInstance)(instance, NULL); } __KvfQueueFamilies __kvfFindQueueFamilies(VkPhysicalDevice physical, VkSurfaceKHR surface) { __KvfQueueFamilies queues = { -1, -1, -1 }; uint32_t queue_family_count; - vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)(physical, &queue_family_count, NULL); VkQueueFamilyProperties* queue_families = (VkQueueFamilyProperties*)KVF_MALLOC(sizeof(VkQueueFamilyProperties) * queue_family_count); - vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, queue_families); + KVF_ASSERT(queue_families != NULL && "allocation failed :("); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)(physical, &queue_family_count, queue_families); - for(int i = 0; i < queue_family_count; i++) + for(uint32_t i = 0; i < queue_family_count; i++) { // try to find a queue family index that supports compute but not graphics if(queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT && (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0) @@ -1147,7 +1343,7 @@ __KvfQueueFamilies __kvfFindQueueFamilies(VkPhysicalDevice physical, VkSurfaceKH VkBool32 present_support = false; if(surface != VK_NULL_HANDLE) { - vkGetPhysicalDeviceSurfaceSupportKHR(physical, i, surface, &present_support); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR)(physical, i, surface, &present_support); if(present_support) queues.present = i; if(queues.graphics != -1 && queues.present != -1 && queues.compute != -1) @@ -1172,9 +1368,10 @@ VkPhysicalDevice kvfPickFirstPhysicalDevice(VkInstance instance, VkSurfaceKHR su KVF_ASSERT(instance != VK_NULL_HANDLE); - vkEnumeratePhysicalDevices(instance, &device_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)(instance, &device_count, NULL); devices = (VkPhysicalDevice*)KVF_MALLOC(sizeof(VkPhysicalDevice) * device_count + 1); - vkEnumeratePhysicalDevices(instance, &device_count, devices); + KVF_ASSERT(devices != NULL && "allocation failed :("); + KVF_GET_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)(instance, &device_count, devices); chosen_one = devices[0]; KVF_FREE(devices); __KvfQueueFamilies queues = __kvfFindQueueFamilies(chosen_one, surface); @@ -1192,15 +1389,16 @@ int32_t __kvfScorePhysicalDevice(VkPhysicalDevice device, VkSurfaceKHR surface, { /* Check extensions support */ uint32_t extension_count; - vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties)(device, NULL, &extension_count, NULL); VkExtensionProperties* props = (VkExtensionProperties*)KVF_MALLOC(sizeof(VkExtensionProperties) * extension_count + 1); - vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, props); + KVF_ASSERT(props != NULL && "allocation failed :("); + KVF_GET_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties)(device, NULL, &extension_count, props); bool are_there_required_device_extensions = true; - for(int j = 0; j < device_extensions_count; j++) + for(uint32_t j = 0; j < device_extensions_count; j++) { bool is_there_extension = false; - for(int k = 0; k < extension_count; k++) + for(uint32_t k = 0; k < extension_count; k++) { if(strcmp(device_extensions[j], props[k].extensionName) == 0) { @@ -1228,17 +1426,17 @@ int32_t __kvfScorePhysicalDevice(VkPhysicalDevice device, VkSurfaceKHR surface, { /* Check surface formats counts */ uint32_t format_count; - vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR)(device, surface, &format_count, NULL); if(format_count == 0) return -1; } #endif VkPhysicalDeviceProperties device_props; - vkGetPhysicalDeviceProperties(device, &device_props); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)(device, &device_props); VkPhysicalDeviceFeatures device_features; - vkGetPhysicalDeviceFeatures(device, &device_features); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures)(device, &device_features); int32_t score = -1; if(device_props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) @@ -1262,11 +1460,12 @@ VkPhysicalDevice kvfPickGoodPhysicalDevice(VkInstance instance, VkSurfaceKHR sur KVF_ASSERT(instance != VK_NULL_HANDLE); - vkEnumeratePhysicalDevices(instance, &device_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)(instance, &device_count, NULL); devices = (VkPhysicalDevice*)KVF_MALLOC(sizeof(VkPhysicalDevice) * device_count + 1); - vkEnumeratePhysicalDevices(instance, &device_count, devices); + KVF_ASSERT(devices != NULL && "allocation failed :("); + KVF_GET_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)(instance, &device_count, devices); - for(int i = 0; i < device_count; i++) + for(uint32_t i = 0; i < device_count; i++) { int32_t current_device_score = __kvfScorePhysicalDevice(devices[i], surface, device_extensions, device_extensions_count); if(current_device_score > best_device_score) @@ -1296,41 +1495,42 @@ VkDevice kvfCreateDevice(VkPhysicalDevice physical, const char** extensions, uin { const float queue_priority = 1.0f; - __KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkPhysicalDevice(physical); + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkPhysicalDevice(physical); - KVF_ASSERT(kvfdevice != NULL); + KVF_ASSERT(kvf_device != NULL); uint32_t queue_count = 0; - queue_count += (kvfdevice->queues.graphics != -1); - queue_count += (kvfdevice->queues.present != -1); - queue_count += (kvfdevice->queues.compute != -1); + queue_count += (kvf_device->queues.graphics != -1); + queue_count += (kvf_device->queues.present != -1); + queue_count += (kvf_device->queues.compute != -1); VkDeviceQueueCreateInfo* queue_create_infos = (VkDeviceQueueCreateInfo*)KVF_MALLOC(queue_count * sizeof(VkDeviceQueueCreateInfo)); + KVF_ASSERT(queue_create_infos != NULL && "allocation failed :("); size_t i = 0; - if(kvfdevice->queues.graphics != -1) + if(kvf_device->queues.graphics != -1) { queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue_create_infos[i].queueFamilyIndex = kvfdevice->queues.graphics; + queue_create_infos[i].queueFamilyIndex = kvf_device->queues.graphics; 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.present != -1 && kvfdevice->queues.present != kvfdevice->queues.graphics) + if(kvf_device->queues.present != -1 && kvf_device->queues.present != kvf_device->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].queueFamilyIndex = kvf_device->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) + if(kvf_device->queues.compute != -1 && kvf_device->queues.present != kvf_device->queues.compute && kvf_device->queues.graphics != kvf_device->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].queueFamilyIndex = kvf_device->queues.compute; queue_create_infos[i].queueCount = 1; queue_create_infos[i].pQueuePriorities = &queue_priority; queue_create_infos[i].flags = 0; @@ -1351,7 +1551,7 @@ VkDevice kvfCreateDevice(VkPhysicalDevice physical, const char** extensions, uin createInfo.pNext = NULL; VkDevice device; - __kvfCheckVk(vkCreateDevice(physical, &createInfo, NULL, &device)); + __kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkCreateDevice)(physical, &createInfo, NULL, &device)); __kvfCompleteDevice(physical, device); return device; @@ -1374,6 +1574,7 @@ VkDevice kvfCreateDeviceCustomPhysicalDeviceAndQueues(VkPhysicalDevice physical, queue_count += (compute_queue != -1); VkDeviceQueueCreateInfo* queue_create_infos = (VkDeviceQueueCreateInfo*)KVF_MALLOC(queue_count * sizeof(VkDeviceQueueCreateInfo)); + KVF_ASSERT(queue_create_infos != NULL && "allocation failed :("); size_t i = 0; if(graphics_queue != -1) { @@ -1419,12 +1620,23 @@ VkDevice kvfCreateDeviceCustomPhysicalDeviceAndQueues(VkPhysicalDevice physical, createInfo.pNext = NULL; VkDevice device; - __kvfCheckVk(vkCreateDevice(physical, &createInfo, NULL, &device)); + __kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkCreateDevice)(physical, &createInfo, NULL, &device)); __kvfCompleteDeviceCustomPhysicalDeviceAndQueues(physical, device, graphics_queue, present_queue, compute_queue); return device; } +#ifdef KVF_IMPL_VK_NO_PROTOTYPES + void kvfPassDeviceVulkanFunctionPointers(VkDevice device, const KvfDeviceVulkanFunctions* fns) + { + KVF_ASSERT(device != VK_NULL_HANDLE); + KVF_ASSERT(fns != NULL); + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + kvf_device->fns = *fns; + } +#endif + void kvfDestroyDevice(VkDevice device) { if(device == VK_NULL_HANDLE) @@ -1435,23 +1647,23 @@ void kvfDestroyDevice(VkDevice device) VkQueue kvfGetDeviceQueue(VkDevice device, KvfQueueType queue) { KVF_ASSERT(device != VK_NULL_HANDLE); - __KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkDevice(device); - KVF_ASSERT(kvfdevice != NULL); + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); VkQueue vk_queue = VK_NULL_HANDLE; if(queue == KVF_GRAPHICS_QUEUE) { - KVF_ASSERT(kvfdevice->queues.graphics != -1); - vkGetDeviceQueue(device, kvfdevice->queues.graphics, 0, &vk_queue); + KVF_ASSERT(kvf_device->queues.graphics != -1); + KVF_GET_DEVICE_FUNCTION(vkGetDeviceQueue)(device, kvf_device->queues.graphics, 0, &vk_queue); } else if(queue == KVF_PRESENT_QUEUE) { - KVF_ASSERT(kvfdevice->queues.present != -1); - vkGetDeviceQueue(device, kvfdevice->queues.present, 0, &vk_queue); + KVF_ASSERT(kvf_device->queues.present != -1); + KVF_GET_DEVICE_FUNCTION(vkGetDeviceQueue)(device, kvf_device->queues.present, 0, &vk_queue); } else if(queue == KVF_COMPUTE_QUEUE) { - KVF_ASSERT(kvfdevice->queues.compute != -1); - vkGetDeviceQueue(device, kvfdevice->queues.compute, 0, &vk_queue); + KVF_ASSERT(kvf_device->queues.compute != -1); + KVF_GET_DEVICE_FUNCTION(vkGetDeviceQueue)(device, kvf_device->queues.compute, 0, &vk_queue); } return vk_queue; } @@ -1459,15 +1671,14 @@ VkQueue kvfGetDeviceQueue(VkDevice device, KvfQueueType queue) uint32_t kvfGetDeviceQueueFamily(VkDevice device, KvfQueueType queue) { KVF_ASSERT(device != VK_NULL_HANDLE); - __KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkDevice(device); - KVF_ASSERT(kvfdevice != NULL); - VkQueue vk_queue = VK_NULL_HANDLE; + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); if(queue == KVF_GRAPHICS_QUEUE) - return kvfdevice->queues.graphics; + return kvf_device->queues.graphics; else if(queue == KVF_PRESENT_QUEUE) - return kvfdevice->queues.present; + return kvf_device->queues.present; else if(queue == KVF_COMPUTE_QUEUE) - return kvfdevice->queues.compute; + return kvf_device->queues.compute; KVF_ASSERT(false && "invalid queue"); return 0; } @@ -1476,6 +1687,10 @@ uint32_t kvfGetDeviceQueueFamily(VkDevice device, KvfQueueType queue) bool kvfQueuePresentKHR(VkDevice device, VkSemaphore wait, VkSwapchainKHR swapchain, uint32_t image_index) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkPresentInfoKHR present_info = {}; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.waitSemaphoreCount = 1; @@ -1483,7 +1698,7 @@ uint32_t kvfGetDeviceQueueFamily(VkDevice device, KvfQueueType queue) present_info.swapchainCount = 1; present_info.pSwapchains = &swapchain; present_info.pImageIndices = &image_index; - VkResult result = vkQueuePresentKHR(kvfGetDeviceQueue(device, KVF_PRESENT_QUEUE), &present_info); + VkResult result = KVF_GET_DEVICE_FUNCTION(vkQueuePresentKHR)(kvfGetDeviceQueue(device, KVF_PRESENT_QUEUE), &present_info); if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) return false; else @@ -1498,13 +1713,14 @@ int32_t kvfFindDeviceQueueFamily(VkPhysicalDevice physical, KvfQueueType type) KVF_ASSERT(type != KVF_PRESENT_QUEUE && "Use kvfFindDeviceQueueFamilyKHR to find present queue"); uint32_t queue_family_count; - vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)(physical, &queue_family_count, NULL); VkQueueFamilyProperties* queue_families = (VkQueueFamilyProperties*)KVF_MALLOC(sizeof(VkQueueFamilyProperties) * queue_family_count); - vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, queue_families); + KVF_ASSERT(queue_families != NULL && "allocation failed :("); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)(physical, &queue_family_count, queue_families); int32_t queue = -1; - for(int i = 0; i < queue_family_count; i++) + for(uint32_t i = 0; i < queue_family_count; i++) { if(type == KVF_COMPUTE_QUEUE) { @@ -1536,16 +1752,17 @@ int32_t kvfFindDeviceQueueFamily(VkPhysicalDevice physical, KvfQueueType type) return kvfFindDeviceQueueFamily(physical, type); uint32_t queue_family_count; - vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)(physical, &queue_family_count, NULL); VkQueueFamilyProperties* queue_families = (VkQueueFamilyProperties*)KVF_MALLOC(sizeof(VkQueueFamilyProperties) * queue_family_count); - vkGetPhysicalDeviceQueueFamilyProperties(physical, &queue_family_count, queue_families); + KVF_ASSERT(queue_families != NULL && "allocation failed :("); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)(physical, &queue_family_count, queue_families); int32_t queue = -1; - for(int i = 0; i < queue_family_count; i++) + for(uint32_t i = 0; i < queue_family_count; i++) { VkBool32 present_support = false; - vkGetPhysicalDeviceSurfaceSupportKHR(physical, i, surface, &present_support); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR)(physical, i, surface, &present_support); if(present_support) queue = i; if(queue != -1) @@ -1559,11 +1776,15 @@ int32_t kvfFindDeviceQueueFamily(VkPhysicalDevice physical, KvfQueueType type) VkFence kvfCreateFence(VkDevice device) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkFenceCreateInfo fence_info = {}; fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; VkFence fence; - __kvfCheckVk(vkCreateFence(device, &fence_info, NULL, &fence)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateFence)(device, &fence_info, NULL, &fence)); return fence; } @@ -1571,7 +1792,11 @@ void kvfWaitForFence(VkDevice device, VkFence fence) { KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(fence != VK_NULL_HANDLE); - vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkWaitForFences)(device, 1, &fence, VK_TRUE, UINT64_MAX); } void kvfDestroyFence(VkDevice device, VkFence fence) @@ -1579,16 +1804,24 @@ void kvfDestroyFence(VkDevice device, VkFence fence) if(fence == VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroyFence(device, fence, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyFence)(device, fence, NULL); } VkSemaphore kvfCreateSemaphore(VkDevice device) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkSemaphoreCreateInfo semaphore_info = {}; semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; VkSemaphore semaphore; - __kvfCheckVk(vkCreateSemaphore(device, &semaphore_info, NULL, &semaphore)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateSemaphore)(device, &semaphore_info, NULL, &semaphore)); return semaphore; } @@ -1597,7 +1830,11 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore) if(semaphore == VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroySemaphore(device, semaphore, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroySemaphore)(device, semaphore, NULL); } #ifndef KVF_NO_KHR @@ -1605,27 +1842,29 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore) { __KvfSwapchainSupportInternal support; - __kvfCheckVk(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical, surface, &support.capabilities)); + __kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(physical, surface, &support.capabilities)); - vkGetPhysicalDeviceSurfaceFormatsKHR(physical, surface, &support.formats_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR)(physical, surface, &support.formats_count, NULL); if(support.formats_count != 0) { support.formats = (VkSurfaceFormatKHR*)KVF_MALLOC(sizeof(VkSurfaceFormatKHR) * support.formats_count); - vkGetPhysicalDeviceSurfaceFormatsKHR(physical, surface, &support.formats_count, support.formats); + KVF_ASSERT(support.formats != NULL && "allocation failed :("); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR)(physical, surface, &support.formats_count, support.formats); } - vkGetPhysicalDeviceSurfacePresentModesKHR(physical, surface, &support.presentModes_count, NULL); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR)(physical, surface, &support.presentModes_count, NULL); if(support.presentModes_count != 0) { support.presentModes = (VkPresentModeKHR*)KVF_MALLOC(sizeof(VkPresentModeKHR) * support.presentModes_count); - vkGetPhysicalDeviceSurfacePresentModesKHR(physical, surface, &support.presentModes_count, support.presentModes); + KVF_ASSERT(support.presentModes != NULL && "allocation failed :("); + KVF_GET_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR)(physical, surface, &support.presentModes_count, support.presentModes); } return support; } VkSurfaceFormatKHR __kvfChooseSwapSurfaceFormat(__KvfSwapchainSupportInternal* support) { - for(int i = 0; i < support->formats_count; i++) + for(uint32_t 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) return support->formats[i]; @@ -1637,7 +1876,7 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore) { if(try_vsync == false) return VK_PRESENT_MODE_IMMEDIATE_KHR; - for(int i = 0; i < support->presentModes_count; i++) + for(uint32_t i = 0; i < support->presentModes_count; i++) { if(support->presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) return support->presentModes[i]; @@ -1664,10 +1903,10 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore) if(support.capabilities.maxImageCount > 0 && image_count > support.capabilities.maxImageCount) image_count = support.capabilities.maxImageCount; - __KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkDevice(device); - KVF_ASSERT(kvfdevice != NULL); + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); - uint32_t queue_family_indices[] = { (uint32_t)kvfdevice->queues.graphics, (uint32_t)kvfdevice->queues.present }; + uint32_t queue_family_indices[] = { (uint32_t)kvf_device->queues.graphics, (uint32_t)kvf_device->queues.present }; if(support.capabilities.currentExtent.width != UINT32_MAX) extent = support.capabilities.currentExtent; @@ -1692,7 +1931,7 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore) createInfo.clipped = VK_TRUE; createInfo.oldSwapchain = VK_NULL_HANDLE; - if(kvfdevice->queues.graphics != kvfdevice->queues.present) + if(kvf_device->queues.graphics != kvf_device->queues.present) { createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; createInfo.queueFamilyIndexCount = 2; @@ -1701,10 +1940,10 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore) else createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - __kvfCheckVk(vkCreateSwapchainKHR(device, &createInfo, NULL, &swapchain)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateSwapchainKHR)(device, &createInfo, NULL, &swapchain)); uint32_t images_count; - vkGetSwapchainImagesKHR(device, swapchain, (uint32_t*)&images_count, NULL); + KVF_GET_DEVICE_FUNCTION(vkGetSwapchainImagesKHR)(device, swapchain, (uint32_t*)&images_count, NULL); __kvfAddSwapchainToArray(swapchain, support, surfaceFormat.format, images_count, extent); @@ -1751,6 +1990,10 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore) VkImage kvfCreateImage(VkDevice device, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, KvfImageType type) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkImageCreateInfo image_info = {}; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image_info.imageType = VK_IMAGE_TYPE_2D; @@ -1773,15 +2016,19 @@ VkImage kvfCreateImage(VkDevice device, uint32_t width, uint32_t height, VkForma } VkImage image; - __kvfCheckVk(vkCreateImage(device, &image_info, NULL, &image)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateImage)(device, &image_info, NULL, &image)); return image; } -void kvfImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage src, size_t buffer_offset, VkImageAspectFlagBits aspect, VkExtent3D extent) +void kvfCopyImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage src, size_t buffer_offset, VkImageAspectFlagBits aspect, VkExtent3D extent) { KVF_ASSERT(cmd != VK_NULL_HANDLE); KVF_ASSERT(dst != VK_NULL_HANDLE); KVF_ASSERT(src != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkCommandBuffer(cmd); + KVF_ASSERT(kvf_device != NULL); + #endif VkOffset3D offset = { 0, 0, 0 }; VkBufferImageCopy region = {}; region.bufferOffset = buffer_offset; @@ -1793,7 +2040,7 @@ void kvfImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage src, size_t buf region.imageSubresource.layerCount = 1; region.imageOffset = offset; region.imageExtent = extent; - vkCmdCopyImageToBuffer(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst, 1, ®ion); + KVF_GET_DEVICE_FUNCTION(vkCmdCopyImageToBuffer)(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst, 1, ®ion); } void kvfDestroyImage(VkDevice device, VkImage image) @@ -1801,12 +2048,20 @@ void kvfDestroyImage(VkDevice device, VkImage image) if(image == VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroyImage(device, image, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyImage)(device, image, NULL); } VkImageView kvfCreateImageView(VkDevice device, VkImage image, VkFormat format, VkImageViewType type, VkImageAspectFlags aspect, int layer_count) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkImageViewCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; create_info.image = image; @@ -1822,7 +2077,7 @@ VkImageView kvfCreateImageView(VkDevice device, VkImage image, VkFormat format, create_info.subresourceRange.baseArrayLayer = 0; create_info.subresourceRange.layerCount = layer_count; VkImageView view; - __kvfCheckVk(vkCreateImageView(device, &create_info, NULL, &view)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateImageView)(device, &create_info, NULL, &view)); return view; } @@ -1830,7 +2085,11 @@ void kvfDestroyImageView(VkDevice device, VkImageView image_view) { KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(image_view != VK_NULL_HANDLE); - vkDestroyImageView(device, image_view, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyImageView)(device, image_view, NULL); } void kvfTransitionImageLayout(VkDevice device, VkImage image, KvfImageType type, VkCommandBuffer cmd, VkFormat format, VkImageLayout old_layout, VkImageLayout new_layout, bool is_single_time_cmd_buffer) @@ -1840,6 +2099,11 @@ void kvfTransitionImageLayout(VkDevice device, VkImage image, KvfImageType type, if(new_layout == old_layout) return; + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + if(is_single_time_cmd_buffer) kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); @@ -1876,7 +2140,7 @@ void kvfTransitionImageLayout(VkDevice device, VkImage image, KvfImageType type, else destination_stage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - vkCmdPipelineBarrier(cmd, source_stage, destination_stage, 0, 0, NULL, 0, NULL, 1, &barrier); + KVF_GET_DEVICE_FUNCTION(vkCmdPipelineBarrier)(cmd, source_stage, destination_stage, 0, 0, NULL, 0, NULL, 1, &barrier); if(is_single_time_cmd_buffer) { @@ -1890,6 +2154,10 @@ void kvfTransitionImageLayout(VkDevice device, VkImage image, KvfImageType type, VkSampler kvfCreateSampler(VkDevice device, VkFilter filters, VkSamplerAddressMode address_modes, VkSamplerMipmapMode mipmap_mode) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkSamplerCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; info.magFilter = filters; @@ -1903,7 +2171,7 @@ VkSampler kvfCreateSampler(VkDevice device, VkFilter filters, VkSamplerAddressMo info.anisotropyEnable = VK_FALSE; info.maxAnisotropy = 1.0f; VkSampler sampler; - __kvfCheckVk(vkCreateSampler(device, &info, NULL, &sampler)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateSampler)(device, &info, NULL, &sampler)); return sampler; } @@ -1912,19 +2180,27 @@ void kvfDestroySampler(VkDevice device, VkSampler sampler) if(sampler == VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroySampler(device, sampler, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroySampler)(device, sampler, NULL); } VkBuffer kvfCreateBuffer(VkDevice device, VkBufferUsageFlags usage, VkDeviceSize size) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkBufferCreateInfo buffer_info = {}; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.size = size; buffer_info.usage = usage; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VkBuffer buffer; - __kvfCheckVk(vkCreateBuffer(device, &buffer_info, NULL, &buffer)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateBuffer)(device, &buffer_info, NULL, &buffer)); return buffer; } @@ -1933,9 +2209,13 @@ void kvfCopyBufferToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkBuffer src, size KVF_ASSERT(cmd != VK_NULL_HANDLE); KVF_ASSERT(dst != VK_NULL_HANDLE); KVF_ASSERT(src != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkCommandBuffer(cmd); + KVF_ASSERT(kvf_device != NULL); + #endif VkBufferCopy copy_region = {}; copy_region.size = size; - vkCmdCopyBuffer(cmd, src, dst, 1, ©_region); + KVF_GET_DEVICE_FUNCTION(vkCmdCopyBuffer)(cmd, src, dst, 1, ©_region); } void kvfCopyBufferToImage(VkCommandBuffer cmd, VkImage dst, VkBuffer src, size_t buffer_offset, VkImageAspectFlagBits aspect, VkExtent3D extent) @@ -1943,6 +2223,10 @@ void kvfCopyBufferToImage(VkCommandBuffer cmd, VkImage dst, VkBuffer src, size_t KVF_ASSERT(cmd != VK_NULL_HANDLE); KVF_ASSERT(dst != VK_NULL_HANDLE); KVF_ASSERT(src != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkCommandBuffer(cmd); + KVF_ASSERT(kvf_device != NULL); + #endif VkOffset3D offset = { 0, 0, 0 }; VkBufferImageCopy region = {}; region.bufferOffset = buffer_offset; @@ -1954,7 +2238,7 @@ void kvfCopyBufferToImage(VkCommandBuffer cmd, VkImage dst, VkBuffer src, size_t region.imageSubresource.layerCount = 1; region.imageOffset = offset; region.imageExtent = extent; - vkCmdCopyBufferToImage(cmd, src, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + KVF_GET_DEVICE_FUNCTION(vkCmdCopyBufferToImage)(cmd, src, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); } void kvfDestroyBuffer(VkDevice device, VkBuffer buffer) @@ -1962,13 +2246,21 @@ void kvfDestroyBuffer(VkDevice device, VkBuffer buffer) if(buffer != VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroyBuffer(device, buffer, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyBuffer)(device, buffer, NULL); } VkFramebuffer kvfCreateFramebuffer(VkDevice device, VkRenderPass render_pass, VkImageView* image_views, size_t image_views_count, VkExtent2D extent) { KVF_ASSERT(device != VK_NULL_HANDLE); KVF_ASSERT(image_views != NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkFramebufferCreateInfo framebuffer_info = {}; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; @@ -1979,7 +2271,7 @@ VkFramebuffer kvfCreateFramebuffer(VkDevice device, VkRenderPass render_pass, Vk framebuffer_info.height = extent.height; framebuffer_info.layers = 1; VkFramebuffer framebuffer = VK_NULL_HANDLE; - __kvfCheckVk(vkCreateFramebuffer(device, &framebuffer_info, NULL, &framebuffer)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateFramebuffer)(device, &framebuffer_info, NULL, &framebuffer)); __kvfAddFramebufferToArray(framebuffer, extent); return framebuffer; } @@ -2008,46 +2300,69 @@ VkCommandBuffer kvfCreateCommandBuffer(VkDevice device) VkCommandBuffer kvfCreateCommandBufferLeveled(VkDevice device, VkCommandBufferLevel level) { KVF_ASSERT(device != VK_NULL_HANDLE); - __KvfDevice* kvfdevice = __kvfGetKvfDeviceFromVkDevice(device); - KVF_ASSERT(kvfdevice != NULL); + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); - VkCommandPool pool = kvfdevice->cmd_pool; + VkCommandPool pool = kvf_device->cmd_pool; VkCommandBuffer buffer; VkCommandBufferAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; alloc_info.commandPool = pool; alloc_info.level = level; alloc_info.commandBufferCount = 1; - __kvfCheckVk(vkAllocateCommandBuffers(device, &alloc_info, &buffer)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkAllocateCommandBuffers)(device, &alloc_info, &buffer)); + + if(kvf_device->cmd_buffers_size == kvf_device->cmd_buffers_capacity) + { + // Resize the dynamic array if necessary + kvf_device->cmd_buffers_capacity += KVF_COMMAND_POOL_CAPACITY; + kvf_device->cmd_buffers = (VkCommandBuffer*)KVF_REALLOC(kvf_device->cmd_buffers, kvf_device->cmd_buffers_capacity * sizeof(VkCommandBuffer)); + KVF_ASSERT(kvf_device->cmd_buffers != NULL && "allocation failed :("); + kvf_device->cmd_buffers[kvf_device->cmd_buffers_size] = buffer; + kvf_device->cmd_buffers_size++; + } + return buffer; } void kvfBeginCommandBuffer(VkCommandBuffer buffer, VkCommandBufferUsageFlags usage) { KVF_ASSERT(buffer != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkCommandBuffer(buffer); + KVF_ASSERT(kvf_device != NULL); + #endif VkCommandBufferBeginInfo begin_info = {}; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.flags = usage; - __kvfCheckVk(vkBeginCommandBuffer(buffer, &begin_info)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkBeginCommandBuffer)(buffer, &begin_info)); } void kvfEndCommandBuffer(VkCommandBuffer buffer) { KVF_ASSERT(buffer != VK_NULL_HANDLE); - __kvfCheckVk(vkEndCommandBuffer(buffer)); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkCommandBuffer(buffer); + KVF_ASSERT(kvf_device != NULL); + #endif + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkEndCommandBuffer)(buffer)); } void kvfSubmitCommandBuffer(VkDevice device, VkCommandBuffer buffer, KvfQueueType queue, VkSemaphore signal, VkSemaphore wait, VkFence fence, VkPipelineStageFlags* stages) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkSemaphore signal_semaphores[1]; VkSemaphore wait_semaphores[1]; signal_semaphores[0] = signal; wait_semaphores[0] = wait; if(fence != VK_NULL_HANDLE) - vkResetFences(device, 1, &fence); + KVF_GET_DEVICE_FUNCTION(vkResetFences)(device, 1, &fence); VkSubmitInfo submit_info = {}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; @@ -2058,23 +2373,27 @@ void kvfSubmitCommandBuffer(VkDevice device, VkCommandBuffer buffer, KvfQueueTyp submit_info.pCommandBuffers = &buffer; submit_info.signalSemaphoreCount = (signal == VK_NULL_HANDLE ? 0 : 1); submit_info.pSignalSemaphores = signal_semaphores; - __kvfCheckVk(vkQueueSubmit(kvfGetDeviceQueue(device, queue), 1, &submit_info, fence)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkQueueSubmit)(kvfGetDeviceQueue(device, queue), 1, &submit_info, fence)); } void kvfSubmitSingleTimeCommandBuffer(VkDevice device, VkCommandBuffer buffer, KvfQueueType queue, VkFence fence) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif if(fence != VK_NULL_HANDLE) - vkResetFences(device, 1, &fence); + KVF_GET_DEVICE_FUNCTION(vkResetFences)(device, 1, &fence); VkSubmitInfo submit_info = {}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &buffer; - __kvfCheckVk(vkQueueSubmit(kvfGetDeviceQueue(device, queue), 1, &submit_info, fence)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkQueueSubmit)(kvfGetDeviceQueue(device, queue), 1, &submit_info, fence)); if(fence != VK_NULL_HANDLE) - vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX); + KVF_GET_DEVICE_FUNCTION(vkWaitForFences)(device, 1, &fence, VK_TRUE, UINT64_MAX); } VkAttachmentDescription kvfBuildAttachmentDescription(KvfImageType type, VkFormat format, VkImageLayout initial, VkImageLayout final, bool clear, VkSampleCountFlagBits samples) @@ -2163,12 +2482,12 @@ VkRenderPass kvfCreateRenderPassWithSubpassDependencies(VkDevice device, VkAttac if(color_attachment_count != 0) { color_references = (VkAttachmentReference*)KVF_MALLOC(color_attachment_count * sizeof(VkAttachmentReference)); - KVF_ASSERT(color_references != NULL); + KVF_ASSERT(color_references != NULL && "allocation failed :("); } if(depth_attachment_count != 0) { depth_references = (VkAttachmentReference*)KVF_MALLOC(depth_attachment_count * sizeof(VkAttachmentReference)); - KVF_ASSERT(depth_references != NULL); + KVF_ASSERT(depth_references != NULL && "allocation failed :("); } for(size_t i = 0, c = 0, d = 0; i < attachments_count; i++) @@ -2188,6 +2507,11 @@ VkRenderPass kvfCreateRenderPassWithSubpassDependencies(VkDevice device, VkAttac } } + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + VkSubpassDescription subpass = {}; subpass.pipelineBindPoint = bind_point; subpass.colorAttachmentCount = color_attachment_count; @@ -2204,7 +2528,7 @@ VkRenderPass kvfCreateRenderPassWithSubpassDependencies(VkDevice device, VkAttac renderpass_create_info.pDependencies = dependencies; VkRenderPass render_pass = VK_NULL_HANDLE; - __kvfCheckVk(vkCreateRenderPass(device, &renderpass_create_info, NULL, &render_pass)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateRenderPass)(device, &renderpass_create_info, NULL, &render_pass)); KVF_FREE(color_references); KVF_FREE(depth_references); return render_pass; @@ -2215,13 +2539,21 @@ void kvfDestroyRenderPass(VkDevice device, VkRenderPass renderPass) if(renderPass == VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroyRenderPass(device, renderPass, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyRenderPass)(device, renderPass, NULL); } void kvfBeginRenderPass(VkRenderPass pass, VkCommandBuffer cmd, VkFramebuffer framebuffer, VkExtent2D framebuffer_extent, VkClearValue* clears, size_t clears_count) { KVF_ASSERT(pass != VK_NULL_HANDLE); KVF_ASSERT(framebuffer != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkCommandBuffer(cmd); + KVF_ASSERT(kvf_device != NULL); + #endif VkOffset2D offset = { 0, 0 }; VkRenderPassBeginInfo renderpass_info = {}; @@ -2232,18 +2564,22 @@ void kvfBeginRenderPass(VkRenderPass pass, VkCommandBuffer cmd, VkFramebuffer fr renderpass_info.renderArea.extent = framebuffer_extent; renderpass_info.clearValueCount = clears_count; renderpass_info.pClearValues = clears; - vkCmdBeginRenderPass(cmd, &renderpass_info, VK_SUBPASS_CONTENTS_INLINE); + KVF_GET_DEVICE_FUNCTION(vkCmdBeginRenderPass)(cmd, &renderpass_info, VK_SUBPASS_CONTENTS_INLINE); } VkShaderModule kvfCreateShaderModule(VkDevice device, uint32_t* code, size_t size) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkShaderModuleCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; createInfo.codeSize = size * sizeof(uint32_t); createInfo.pCode = code; VkShaderModule shader = VK_NULL_HANDLE; - __kvfCheckVk(vkCreateShaderModule(device, &createInfo, NULL, &shader)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateShaderModule)(device, &createInfo, NULL, &shader)); return shader; } @@ -2252,19 +2588,27 @@ void kvfDestroyShaderModule(VkDevice device, VkShaderModule shader) if(shader == VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroyShaderModule(device, shader, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyShaderModule)(device, shader, NULL); } VkDescriptorSetLayout kvfCreateDescriptorSetLayout(VkDevice device, VkDescriptorSetLayoutBinding* bindings, size_t bindings_count) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkDescriptorSetLayoutCreateInfo layout_info = {}; layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; layout_info.bindingCount = bindings_count; layout_info.pBindings = bindings; VkDescriptorSetLayout layout; - __kvfCheckVk(vkCreateDescriptorSetLayout(device, &layout_info, NULL, &layout)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateDescriptorSetLayout)(device, &layout_info, NULL, &layout)); return layout; } @@ -2273,7 +2617,11 @@ void kvfDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout layout if(layout == VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroyDescriptorSetLayout(device, layout, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyDescriptorSetLayout)(device, layout, NULL); } VkDescriptorSet kvfAllocateDescriptorSet(VkDevice device, VkDescriptorSetLayout layout) @@ -2282,7 +2630,7 @@ VkDescriptorSet kvfAllocateDescriptorSet(VkDevice device, VkDescriptorSetLayout __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); KVF_ASSERT(kvf_device != NULL); VkDescriptorPool pool = VK_NULL_HANDLE; - for(int i = 0; i < kvf_device->sets_pools_size; i++) + for(uint32_t i = 0; i < kvf_device->sets_pools_size; i++) { if(kvf_device->sets_pools[i].size < kvf_device->sets_pools[i].capacity) pool = kvf_device->sets_pools[i].pool; @@ -2297,27 +2645,39 @@ VkDescriptorSet kvfAllocateDescriptorSet(VkDevice device, VkDescriptorSetLayout alloc_info.descriptorPool = pool; alloc_info.descriptorSetCount = 1; alloc_info.pSetLayouts = &layout; - __kvfCheckVk(vkAllocateDescriptorSets(device, &alloc_info, &set)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkAllocateDescriptorSets)(device, &alloc_info, &set)); KVF_ASSERT(set != VK_NULL_HANDLE); return set; } void kvfUpdateStorageBufferToDescriptorSet(VkDevice device, VkDescriptorSet set, const VkDescriptorBufferInfo* info, uint32_t binding) { + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkWriteDescriptorSet write = kvfWriteStorageBufferToDescriptorSet(device, set, info, binding); - vkUpdateDescriptorSets(device, 1, &write, 0, NULL); + KVF_GET_DEVICE_FUNCTION(vkUpdateDescriptorSets)(device, 1, &write, 0, NULL); } void kvfUpdateUniformBufferToDescriptorSet(VkDevice device, VkDescriptorSet set, const VkDescriptorBufferInfo* info, uint32_t binding) { + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkWriteDescriptorSet write = kvfWriteUniformBufferToDescriptorSet(device, set, info, binding); - vkUpdateDescriptorSets(device, 1, &write, 0, NULL); + KVF_GET_DEVICE_FUNCTION(vkUpdateDescriptorSets)(device, 1, &write, 0, NULL); } void kvfUpdateImageToDescriptorSet(VkDevice device, VkDescriptorSet set, const VkDescriptorImageInfo* info, uint32_t binding) { + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkWriteDescriptorSet write = kvfWriteImageToDescriptorSet(device, set, info, binding); - vkUpdateDescriptorSets(device, 1, &write, 0, NULL); + KVF_GET_DEVICE_FUNCTION(vkUpdateDescriptorSets)(device, 1, &write, 0, NULL); } VkWriteDescriptorSet kvfWriteStorageBufferToDescriptorSet(VkDevice device, VkDescriptorSet set, const VkDescriptorBufferInfo* info, uint32_t binding) @@ -2368,6 +2728,10 @@ VkWriteDescriptorSet kvfWriteImageToDescriptorSet(VkDevice device, VkDescriptorS VkPipelineLayout kvfCreatePipelineLayout(VkDevice device, VkDescriptorSetLayout* set_layouts, size_t set_layouts_count, VkPushConstantRange* pc, size_t pc_count) { KVF_ASSERT(device != VK_NULL_HANDLE); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkPipelineLayoutCreateInfo pipeline_layout_info = {}; pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeline_layout_info.setLayoutCount = set_layouts_count; @@ -2376,7 +2740,7 @@ VkPipelineLayout kvfCreatePipelineLayout(VkDevice device, VkDescriptorSetLayout* pipeline_layout_info.pPushConstantRanges = pc; VkPipelineLayout layout; - __kvfCheckVk(vkCreatePipelineLayout(device, &pipeline_layout_info, NULL, &layout)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreatePipelineLayout)(device, &pipeline_layout_info, NULL, &layout)); return layout; } @@ -2385,7 +2749,11 @@ void kvfDestroyPipelineLayout(VkDevice device, VkPipelineLayout layout) if(layout == VK_NULL_HANDLE) return; KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroyPipelineLayout(device, layout, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyPipelineLayout)(device, layout, NULL); } void kvfResetDeviceDescriptorPools(VkDevice device) @@ -2393,9 +2761,9 @@ void kvfResetDeviceDescriptorPools(VkDevice device) KVF_ASSERT(device != VK_NULL_HANDLE); __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); KVF_ASSERT(kvf_device != NULL); - for(int i = 0; i < kvf_device->sets_pools_size; i++) + for(uint32_t i = 0; i < kvf_device->sets_pools_size; i++) { - vkResetDescriptorPool(device, kvf_device->sets_pools[i].pool, 0); + KVF_GET_DEVICE_FUNCTION(vkResetDescriptorPool)(device, kvf_device->sets_pools[i].pool, 0); kvf_device->sets_pools[i].size = 0; } } @@ -2403,6 +2771,7 @@ void kvfResetDeviceDescriptorPools(VkDevice device) KvfGraphicsPipelineBuilder* kvfCreateGPipelineBuilder() { KvfGraphicsPipelineBuilder* builder = (KvfGraphicsPipelineBuilder*)KVF_MALLOC(sizeof(KvfGraphicsPipelineBuilder)); + KVF_ASSERT(builder != NULL && "allocation failed :("); memset(builder, 0, sizeof(KvfGraphicsPipelineBuilder)); kvfGPipelineBuilderReset(builder); return builder; @@ -2533,10 +2902,10 @@ void kvfGPipelineBuilderSetVertexInputs(KvfGraphicsPipelineBuilder* builder, VkV KVF_ASSERT(builder != NULL); KVF_ASSERT(attributes != NULL); VkVertexInputBindingDescription* binds_ptr = (VkVertexInputBindingDescription*)KVF_MALLOC(sizeof(VkVertexInputBindingDescription)); - KVF_ASSERT(binds_ptr != NULL); + KVF_ASSERT(binds_ptr != NULL && "allocation failed :("); *binds_ptr = binds; VkVertexInputAttributeDescription* attributes_descriptions = (VkVertexInputAttributeDescription*)KVF_MALLOC(sizeof(VkVertexInputAttributeDescription) * attributes_count); - KVF_ASSERT(attributes_descriptions != NULL); + KVF_ASSERT(attributes_descriptions != NULL && "allocation failed :("); memcpy(attributes_descriptions, attributes, sizeof(VkVertexInputAttributeDescription) * attributes_count); builder->vertex_input_state.vertexBindingDescriptionCount = 1; builder->vertex_input_state.pVertexBindingDescriptions = binds_ptr; @@ -2551,7 +2920,7 @@ void kvfGPipelineBuilderAddShaderStage(KvfGraphicsPipelineBuilder* builder, VkSh KVF_ASSERT(builder->shader_stages != NULL); memset(&builder->shader_stages[builder->shader_stages_count], 0, sizeof(VkPipelineShaderStageCreateInfo)); char* entry_ptr = (char*)KVF_MALLOC(strlen(entry)); - KVF_ASSERT(entry_ptr != NULL); + KVF_ASSERT(entry_ptr != NULL && "allocation failed :("); strcpy(entry_ptr, entry); builder->shader_stages[builder->shader_stages_count].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; builder->shader_stages[builder->shader_stages_count].stage = stage; @@ -2619,15 +2988,23 @@ VkPipeline kvfCreateGraphicsPipeline(VkDevice device, VkPipelineLayout layout, K pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.pDepthStencilState = &builder->depth_stencil_state; + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif VkPipeline pipeline; - __kvfCheckVk(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &pipeline)); + __kvfCheckVk(KVF_GET_DEVICE_FUNCTION(vkCreateGraphicsPipelines)(device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &pipeline)); return pipeline; } void kvfDestroyPipeline(VkDevice device, VkPipeline pipeline) { KVF_ASSERT(device != VK_NULL_HANDLE); - vkDestroyPipeline(device, pipeline, NULL); + #ifdef KVF_IMPL_VK_NO_PROTOTYPES + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + #endif + KVF_GET_DEVICE_FUNCTION(vkDestroyPipeline)(device, pipeline, NULL); } #endif // KVF_IMPLEMENTATION