From 092e5acd9b61f07400833bb944c38fd3a8bad14b Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Fri, 20 Sep 2024 16:14:14 +0200 Subject: [PATCH] fixing vulkan loader, moving vulkan pfns to RenderCore --- runtime/Includes/Core/Application.h | 1 + runtime/Includes/PreCompiled.h | 3 + runtime/Includes/Renderer/Buffer.h | 4 +- runtime/Includes/Renderer/Descriptor.h | 1 - runtime/Includes/Renderer/Image.h | 2 +- .../Includes/Renderer/Pipelines/Pipeline.h | 4 +- runtime/Includes/Renderer/RenderCore.h | 30 +- runtime/Includes/Renderer/Vulkan/VulkanDefs.h | 121 ++++ .../Renderer/Vulkan/VulkanPrototypes.h | 170 ----- runtime/Sources/Core/Application.cpp | 2 +- runtime/Sources/Core/Bridge.cpp | 2 - runtime/Sources/Graphics/Mesh.cpp | 2 +- runtime/Sources/Renderer/Descriptor.cpp | 2 +- runtime/Sources/Renderer/Image.cpp | 8 +- runtime/Sources/Renderer/Memory.cpp | 34 +- .../Sources/Renderer/Pipelines/Graphics.cpp | 10 +- runtime/Sources/Renderer/RenderCore.cpp | 110 ++- .../Sources/Renderer/RenderPasses/2DPass.cpp | 4 +- .../Renderer/RenderPasses/FinalPass.cpp | 4 +- runtime/Sources/Renderer/Renderer.cpp | 8 +- .../Sources/Renderer/Vulkan/VulkanLoader.cpp | 354 +--------- third_party/kvf.h | 629 ++++++++++++++---- 22 files changed, 821 insertions(+), 684 deletions(-) create mode 100644 runtime/Includes/Renderer/Vulkan/VulkanDefs.h delete mode 100644 runtime/Includes/Renderer/Vulkan/VulkanPrototypes.h diff --git a/runtime/Includes/Core/Application.h b/runtime/Includes/Core/Application.h index 213010b..7521d77 100644 --- a/runtime/Includes/Core/Application.h +++ b/runtime/Includes/Core/Application.h @@ -47,6 +47,7 @@ namespace mlx ~Application(); private: + RenderCore m_render_core; FpsManager m_fps; Inputs m_in; ImageRegistry m_image_registry; diff --git a/runtime/Includes/PreCompiled.h b/runtime/Includes/PreCompiled.h index f0041a9..f948b11 100644 --- a/runtime/Includes/PreCompiled.h +++ b/runtime/Includes/PreCompiled.h @@ -9,6 +9,8 @@ #include #include +#include + #include #include @@ -81,6 +83,7 @@ #include #include +#define KVF_IMPL_VK_NO_PROTOTYPES #ifdef DEBUG #define KVF_ENABLE_VALIDATION_LAYERS #endif diff --git a/runtime/Includes/Renderer/Buffer.h b/runtime/Includes/Renderer/Buffer.h index 8d0b489..d6574fa 100644 --- a/runtime/Includes/Renderer/Buffer.h +++ b/runtime/Includes/Renderer/Buffer.h @@ -51,7 +51,7 @@ namespace mlx public: inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags = 0) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | additional_flags, {}); } void SetData(CPUBuffer data); - inline void Bind(VkCommandBuffer cmd) const noexcept { VkDeviceSize offset = 0; vkCmdBindVertexBuffers(cmd, 0, 1, &m_buffer, &offset); } + inline void Bind(VkCommandBuffer cmd) const noexcept { VkDeviceSize offset = 0; RenderCore::Get().vkCmdBindVertexBuffers(cmd, 0, 1, &m_buffer, &offset); } }; class IndexBuffer : public GPUBuffer @@ -59,7 +59,7 @@ namespace mlx public: inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags = 0) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | additional_flags, {}); } void SetData(CPUBuffer data); - inline void Bind(VkCommandBuffer cmd) const noexcept { vkCmdBindIndexBuffer(cmd, m_buffer, 0, VK_INDEX_TYPE_UINT32); } + inline void Bind(VkCommandBuffer cmd) const noexcept { RenderCore::Get().vkCmdBindIndexBuffer(cmd, m_buffer, 0, VK_INDEX_TYPE_UINT32); } }; class UniformBuffer diff --git a/runtime/Includes/Renderer/Descriptor.h b/runtime/Includes/Renderer/Descriptor.h index b99fbfa..ad37ae4 100644 --- a/runtime/Includes/Renderer/Descriptor.h +++ b/runtime/Includes/Renderer/Descriptor.h @@ -4,7 +4,6 @@ #include #include #include -#include namespace mlx { diff --git a/runtime/Includes/Renderer/Image.h b/runtime/Includes/Renderer/Image.h index 996a3ac..ebde1ad 100644 --- a/runtime/Includes/Renderer/Image.h +++ b/runtime/Includes/Renderer/Image.h @@ -99,7 +99,7 @@ namespace mlx kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, cmd); kvfCopyBufferToImage(cmd, Image::Get(), staging_buffer.Get(), staging_buffer.GetOffset(), VK_IMAGE_ASPECT_COLOR_BIT, { width, height, 1 }); - vkEndCommandBuffer(cmd); + RenderCore::Get().vkEndCommandBuffer(cmd); VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice()); kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence); kvfDestroyFence(RenderCore::Get().GetDevice(), fence); diff --git a/runtime/Includes/Renderer/Pipelines/Pipeline.h b/runtime/Includes/Renderer/Pipelines/Pipeline.h index 126fb34..f92f1b9 100644 --- a/runtime/Includes/Renderer/Pipelines/Pipeline.h +++ b/runtime/Includes/Renderer/Pipelines/Pipeline.h @@ -1,8 +1,6 @@ #ifndef __MLX_PIPELINE__ #define __MLX_PIPELINE__ -#include - namespace mlx { class Pipeline @@ -10,7 +8,7 @@ namespace mlx public: Pipeline() = default; - inline virtual bool BindPipeline(VkCommandBuffer command_buffer) noexcept { vkCmdBindPipeline(command_buffer, GetPipelineBindPoint(), GetPipeline()); return true; } + inline virtual bool BindPipeline(VkCommandBuffer command_buffer) noexcept { RenderCore::Get().vkCmdBindPipeline(command_buffer, GetPipelineBindPoint(), GetPipeline()); return true; } inline virtual void EndPipeline([[maybe_unused]] VkCommandBuffer command_buffer) noexcept {} virtual VkPipeline GetPipeline() const = 0; diff --git a/runtime/Includes/Renderer/RenderCore.h b/runtime/Includes/Renderer/RenderCore.h index 5885064..36947a6 100644 --- a/runtime/Includes/Renderer/RenderCore.h +++ b/runtime/Includes/Renderer/RenderCore.h @@ -1,21 +1,17 @@ #ifndef __MLX_RENDER_CORE__ #define __MLX_RENDER_CORE__ -#include #include namespace mlx { constexpr const int MAX_FRAMES_IN_FLIGHT = 3; - class RenderCore : public Singleton + class RenderCore { - friend class Singleton; + friend class Application; public: - void Init() noexcept; - void Destroy() noexcept; - [[nodiscard]] MLX_FORCEINLINE VkInstance GetInstance() const noexcept { return m_instance; } [[nodiscard]] MLX_FORCEINLINE VkInstance& GetInstanceRef() noexcept { return m_instance; } [[nodiscard]] MLX_FORCEINLINE VkDevice GetDevice() const noexcept { return m_device; } @@ -24,11 +20,27 @@ namespace mlx inline void WaitDeviceIdle() const noexcept { vkDeviceWaitIdle(m_device); } - private: - RenderCore() = default; - ~RenderCore() = default; + inline static bool IsInit() noexcept { return s_instance != nullptr; } + inline static RenderCore& Get() noexcept { return *s_instance; } + + #define MLX_VULKAN_GLOBAL_FUNCTION(fn) PFN_##fn fn = nullptr; + #define MLX_VULKAN_INSTANCE_FUNCTION(fn) PFN_##fn fn = nullptr; + #define MLX_VULKAN_DEVICE_FUNCTION(fn) PFN_##fn fn = nullptr; + #include + #undef MLX_VULKAN_GLOBAL_FUNCTION + #undef MLX_VULKAN_INSTANCE_FUNCTION + #undef MLX_VULKAN_DEVICE_FUNCTION private: + RenderCore(); + void LoadKVFGlobalVulkanFunctionPointers() const noexcept; + void LoadKVFInstanceVulkanFunctionPointers() const noexcept; + void LoadKVFDeviceVulkanFunctionPointers() const noexcept; + ~RenderCore(); + + private: + static RenderCore* s_instance; + GPUAllocator m_allocator; VkInstance m_instance = VK_NULL_HANDLE; VkDevice m_device = VK_NULL_HANDLE; diff --git a/runtime/Includes/Renderer/Vulkan/VulkanDefs.h b/runtime/Includes/Renderer/Vulkan/VulkanDefs.h new file mode 100644 index 0000000..2c9972d --- /dev/null +++ b/runtime/Includes/Renderer/Vulkan/VulkanDefs.h @@ -0,0 +1,121 @@ +// No header guard + +#ifdef VK_VERSION_1_0 + #ifdef MLX_VULKAN_GLOBAL_FUNCTION + MLX_VULKAN_GLOBAL_FUNCTION(vkCreateInstance) + MLX_VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties) + MLX_VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties) + MLX_VULKAN_GLOBAL_FUNCTION(vkGetInstanceProcAddr) + #endif + + #ifdef MLX_VULKAN_INSTANCE_FUNCTION + MLX_VULKAN_INSTANCE_FUNCTION(vkCreateDevice) + MLX_VULKAN_INSTANCE_FUNCTION(vkDestroyInstance) + MLX_VULKAN_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties) + MLX_VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFormatProperties) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceImageFormatProperties) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties) + #endif + + #ifdef MLX_VULKAN_DEVICE_FUNCTION + MLX_VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers) + MLX_VULKAN_DEVICE_FUNCTION(vkAllocateDescriptorSets) + MLX_VULKAN_DEVICE_FUNCTION(vkAllocateMemory) + MLX_VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkBindBufferMemory) + MLX_VULKAN_DEVICE_FUNCTION(vkBindImageMemory) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdBeginRenderPass) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdBindDescriptorSets) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdBindIndexBuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdBindPipeline) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdBindVertexBuffers) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdClearAttachments) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdClearColorImage) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdClearDepthStencilImage) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdCopyBuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdCopyBufferToImage) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdCopyImage) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdCopyImageToBuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdDraw) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdDrawIndexed) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdEndRenderPass) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdPushConstants) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdSetScissor) + MLX_VULKAN_DEVICE_FUNCTION(vkCmdSetViewport) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateBuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateCommandPool) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateDescriptorPool) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateDescriptorSetLayout) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateFence) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateFramebuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateGraphicsPipelines) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateImage) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateImageView) + MLX_VULKAN_DEVICE_FUNCTION(vkCreatePipelineLayout) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateRenderPass) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateSampler) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateSemaphore) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateShaderModule) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyBuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorPool) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorSetLayout) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyDevice) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyFence) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyFramebuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyImage) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyImageView) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyPipeline) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyPipelineLayout) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyRenderPass) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroySampler) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroySemaphore) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroyShaderModule) + MLX_VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle) + MLX_VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkFlushMappedMemoryRanges) + MLX_VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers) + MLX_VULKAN_DEVICE_FUNCTION(vkFreeMemory) + MLX_VULKAN_DEVICE_FUNCTION(vkGetBufferMemoryRequirements) + MLX_VULKAN_DEVICE_FUNCTION(vkGetDeviceMemoryCommitment) + MLX_VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue) + MLX_VULKAN_DEVICE_FUNCTION(vkGetFenceStatus) + MLX_VULKAN_DEVICE_FUNCTION(vkGetImageMemoryRequirements) + MLX_VULKAN_DEVICE_FUNCTION(vkGetImageSubresourceLayout) + MLX_VULKAN_DEVICE_FUNCTION(vkInvalidateMappedMemoryRanges) + MLX_VULKAN_DEVICE_FUNCTION(vkMapMemory) + MLX_VULKAN_DEVICE_FUNCTION(vkQueueSubmit) + MLX_VULKAN_DEVICE_FUNCTION(vkQueueWaitIdle) + MLX_VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer) + MLX_VULKAN_DEVICE_FUNCTION(vkResetDescriptorPool) + MLX_VULKAN_DEVICE_FUNCTION(vkResetEvent) + MLX_VULKAN_DEVICE_FUNCTION(vkResetFences) + MLX_VULKAN_DEVICE_FUNCTION(vkUnmapMemory) + MLX_VULKAN_DEVICE_FUNCTION(vkUpdateDescriptorSets) + MLX_VULKAN_DEVICE_FUNCTION(vkWaitForFences) + #endif +#endif +#ifdef VK_KHR_swapchain + #ifdef MLX_VULKAN_DEVICE_FUNCTION + MLX_VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR) + MLX_VULKAN_DEVICE_FUNCTION(vkCreateSwapchainKHR) + MLX_VULKAN_DEVICE_FUNCTION(vkDestroySwapchainKHR) + MLX_VULKAN_DEVICE_FUNCTION(vkGetSwapchainImagesKHR) + MLX_VULKAN_DEVICE_FUNCTION(vkQueuePresentKHR) + #endif +#endif +#ifdef VK_KHR_surface + #ifdef MLX_VULKAN_INSTANCE_FUNCTION + MLX_VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) + MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR) + #endif +#endif diff --git a/runtime/Includes/Renderer/Vulkan/VulkanPrototypes.h b/runtime/Includes/Renderer/Vulkan/VulkanPrototypes.h deleted file mode 100644 index d3e9ad9..0000000 --- a/runtime/Includes/Renderer/Vulkan/VulkanPrototypes.h +++ /dev/null @@ -1,170 +0,0 @@ -#ifndef __MLX_VK_PROTOTYPES__ -#define __MLX_VK_PROTOTYPES__ - -#if defined(VULKAN_H_) && !defined(VK_NO_PROTOTYPES) - #error "define VK_NO_PROTOTYPES needed" -#endif - -#ifndef VK_NO_PROTOTYPES - #define VK_NO_PROTOTYPES -#endif - -#ifndef VULKAN_H_ - #include -#endif - -#ifdef VK_VERSION_1_0 - extern PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers; - extern PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets; - extern PFN_vkAllocateMemory vkAllocateMemory; - extern PFN_vkBeginCommandBuffer vkBeginCommandBuffer; - extern PFN_vkBindBufferMemory vkBindBufferMemory; - extern PFN_vkBindImageMemory vkBindImageMemory; - extern PFN_vkCmdBeginQuery vkCmdBeginQuery; - extern PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass; - extern PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets; - extern PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer; - extern PFN_vkCmdBindPipeline vkCmdBindPipeline; - extern PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers; - extern PFN_vkCmdBlitImage vkCmdBlitImage; - extern PFN_vkCmdClearAttachments vkCmdClearAttachments; - extern PFN_vkCmdClearColorImage vkCmdClearColorImage; - extern PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage; - extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer; - extern PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage; - extern PFN_vkCmdCopyImage vkCmdCopyImage; - extern PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer; - extern PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults; - extern PFN_vkCmdDispatch vkCmdDispatch; - extern PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect; - extern PFN_vkCmdDraw vkCmdDraw; - extern PFN_vkCmdDrawIndexed vkCmdDrawIndexed; - extern PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect; - extern PFN_vkCmdDrawIndirect vkCmdDrawIndirect; - extern PFN_vkCmdEndQuery vkCmdEndQuery; - extern PFN_vkCmdEndRenderPass vkCmdEndRenderPass; - extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands; - extern PFN_vkCmdFillBuffer vkCmdFillBuffer; - extern PFN_vkCmdNextSubpass vkCmdNextSubpass; - extern PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; - extern PFN_vkCmdPushConstants vkCmdPushConstants; - extern PFN_vkCmdResetEvent vkCmdResetEvent; - extern PFN_vkCmdResetQueryPool vkCmdResetQueryPool; - extern PFN_vkCmdResolveImage vkCmdResolveImage; - extern PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants; - extern PFN_vkCmdSetDepthBias vkCmdSetDepthBias; - extern PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds; - extern PFN_vkCmdSetEvent vkCmdSetEvent; - extern PFN_vkCmdSetLineWidth vkCmdSetLineWidth; - extern PFN_vkCmdSetScissor vkCmdSetScissor; - extern PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask; - extern PFN_vkCmdSetStencilReference vkCmdSetStencilReference; - extern PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask; - extern PFN_vkCmdSetViewport vkCmdSetViewport; - extern PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer; - extern PFN_vkCmdWaitEvents vkCmdWaitEvents; - extern PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp; - extern PFN_vkCreateBuffer vkCreateBuffer; - extern PFN_vkCreateBufferView vkCreateBufferView; - extern PFN_vkCreateCommandPool vkCreateCommandPool; - extern PFN_vkCreateComputePipelines vkCreateComputePipelines; - extern PFN_vkCreateDescriptorPool vkCreateDescriptorPool; - extern PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout; - extern PFN_vkCreateDevice vkCreateDevice; - extern PFN_vkCreateEvent vkCreateEvent; - extern PFN_vkCreateFence vkCreateFence; - extern PFN_vkCreateFramebuffer vkCreateFramebuffer; - extern PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines; - extern PFN_vkCreateImage vkCreateImage; - extern PFN_vkCreateImageView vkCreateImageView; - extern PFN_vkCreateInstance vkCreateInstance; - extern PFN_vkCreatePipelineCache vkCreatePipelineCache; - extern PFN_vkCreatePipelineLayout vkCreatePipelineLayout; - extern PFN_vkCreateQueryPool vkCreateQueryPool; - extern PFN_vkCreateRenderPass vkCreateRenderPass; - extern PFN_vkCreateSampler vkCreateSampler; - extern PFN_vkCreateSemaphore vkCreateSemaphore; - extern PFN_vkCreateShaderModule vkCreateShaderModule; - extern PFN_vkDestroyBuffer vkDestroyBuffer; - extern PFN_vkDestroyBufferView vkDestroyBufferView; - extern PFN_vkDestroyCommandPool vkDestroyCommandPool; - extern PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool; - extern PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout; - extern PFN_vkDestroyDevice vkDestroyDevice; - extern PFN_vkDestroyEvent vkDestroyEvent; - extern PFN_vkDestroyFence vkDestroyFence; - extern PFN_vkDestroyFramebuffer vkDestroyFramebuffer; - extern PFN_vkDestroyImage vkDestroyImage; - extern PFN_vkDestroyImageView vkDestroyImageView; - extern PFN_vkDestroyInstance vkDestroyInstance; - extern PFN_vkDestroyPipeline vkDestroyPipeline; - extern PFN_vkDestroyPipelineCache vkDestroyPipelineCache; - extern PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout; - extern PFN_vkDestroyQueryPool vkDestroyQueryPool; - extern PFN_vkDestroyRenderPass vkDestroyRenderPass; - extern PFN_vkDestroySampler vkDestroySampler; - extern PFN_vkDestroySemaphore vkDestroySemaphore; - extern PFN_vkDestroyShaderModule vkDestroyShaderModule; - extern PFN_vkDeviceWaitIdle vkDeviceWaitIdle; - extern PFN_vkEndCommandBuffer vkEndCommandBuffer; - extern PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties; - extern PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties; - extern PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; - extern PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties; - extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; - extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges; - extern PFN_vkFreeCommandBuffers vkFreeCommandBuffers; - extern PFN_vkFreeDescriptorSets vkFreeDescriptorSets; - extern PFN_vkFreeMemory vkFreeMemory; - extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; - extern PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment; - extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; - extern PFN_vkGetDeviceQueue vkGetDeviceQueue; - extern PFN_vkGetEventStatus vkGetEventStatus; - extern PFN_vkGetFenceStatus vkGetFenceStatus; - extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; - extern PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements; - extern PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout; - extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; - extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures; - extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties; - extern PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties; - extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; - extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; - extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties; - extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties; - extern PFN_vkGetPipelineCacheData vkGetPipelineCacheData; - extern PFN_vkGetQueryPoolResults vkGetQueryPoolResults; - extern PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity; - extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges; - extern PFN_vkMapMemory vkMapMemory; - extern PFN_vkMergePipelineCaches vkMergePipelineCaches; - extern PFN_vkQueueBindSparse vkQueueBindSparse; - extern PFN_vkQueueSubmit vkQueueSubmit; - extern PFN_vkQueueWaitIdle vkQueueWaitIdle; - extern PFN_vkResetCommandBuffer vkResetCommandBuffer; - extern PFN_vkResetCommandPool vkResetCommandPool; - extern PFN_vkResetDescriptorPool vkResetDescriptorPool; - extern PFN_vkResetEvent vkResetEvent; - extern PFN_vkResetFences vkResetFences; - extern PFN_vkSetEvent vkSetEvent; - extern PFN_vkUnmapMemory vkUnmapMemory; - extern PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets; - extern PFN_vkWaitForFences vkWaitForFences; -#endif -#ifdef VK_KHR_swapchain - extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; - extern PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR; - extern PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR; - extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR; - extern PFN_vkQueuePresentKHR vkQueuePresentKHR; -#endif -#ifdef VK_KHR_surface - extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR; - extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; - extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; - extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; - extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; -#endif - -#endif diff --git a/runtime/Sources/Core/Application.cpp b/runtime/Sources/Core/Application.cpp index 5da8017..29ffbbb 100644 --- a/runtime/Sources/Core/Application.cpp +++ b/runtime/Sources/Core/Application.cpp @@ -8,7 +8,7 @@ namespace mlx { - Application::Application() : m_fps(), m_in() + Application::Application() : m_render_core(), m_fps(), m_in() { EventBus::RegisterListener({[](const EventBase& event) { diff --git a/runtime/Sources/Core/Bridge.cpp b/runtime/Sources/Core/Bridge.cpp index 3ba1a9e..01ba894 100644 --- a/runtime/Sources/Core/Bridge.cpp +++ b/runtime/Sources/Core/Bridge.cpp @@ -29,7 +29,6 @@ extern "C" mlx::Application* app = new mlx::Application; if(app == nullptr) mlx::FatalError("Tout a pété"); - mlx::RenderCore::Get().Init(); __mlx_ptr = static_cast(app); return __mlx_ptr; } @@ -281,7 +280,6 @@ extern "C" { MLX_CHECK_APPLICATION_POINTER(mlx); delete static_cast(mlx); - mlx::RenderCore::Get().Destroy(); __mlx_ptr = nullptr; return 0; } diff --git a/runtime/Sources/Graphics/Mesh.cpp b/runtime/Sources/Graphics/Mesh.cpp index 3f8221f..3df2e95 100644 --- a/runtime/Sources/Graphics/Mesh.cpp +++ b/runtime/Sources/Graphics/Mesh.cpp @@ -15,7 +15,7 @@ namespace mlx Verify(submesh_index < m_sub_meshes.size(), "invalid submesh index"); m_sub_meshes[submesh_index].vbo.Bind(cmd); m_sub_meshes[submesh_index].ibo.Bind(cmd); - vkCmdDrawIndexed(cmd, static_cast(m_sub_meshes[submesh_index].ibo.GetSize() / sizeof(std::uint32_t)), 1, 0, 0, 0); + mlx::RenderCore::Get().vkCmdDrawIndexed(cmd, static_cast(m_sub_meshes[submesh_index].ibo.GetSize() / sizeof(std::uint32_t)), 1, 0, 0, 0); polygondrawn += m_sub_meshes[submesh_index].triangle_count; drawcalls++; } diff --git a/runtime/Sources/Renderer/Descriptor.cpp b/runtime/Sources/Renderer/Descriptor.cpp index bbed657..11a4411 100644 --- a/runtime/Sources/Renderer/Descriptor.cpp +++ b/runtime/Sources/Renderer/Descriptor.cpp @@ -136,7 +136,7 @@ namespace mlx writes.push_back(kvfWriteStorageBufferToDescriptorSet(RenderCore::Get().GetDevice(), m_set[i], &buffer_infos.back(), descriptor.binding)); } } - vkUpdateDescriptorSets(RenderCore::Get().GetDevice(), writes.size(), writes.data(), 0, nullptr); + RenderCore::Get().vkUpdateDescriptorSets(RenderCore::Get().GetDevice(), writes.size(), writes.data(), 0, nullptr); } void DescriptorSet::Reallocate() noexcept diff --git a/runtime/Sources/Renderer/Image.cpp b/runtime/Sources/Renderer/Image.cpp index 0310469..6eff769 100644 --- a/runtime/Sources/Renderer/Image.cpp +++ b/runtime/Sources/Renderer/Image.cpp @@ -76,7 +76,7 @@ namespace mlx m_layout = new_layout; if(is_single_time_cmd_buffer) { - vkEndCommandBuffer(cmd); + RenderCore::Get().vkEndCommandBuffer(cmd); VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice()); kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence); kvfDestroyFence(RenderCore::Get().GetDevice(), fence); @@ -97,7 +97,7 @@ namespace mlx TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, cmd); subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; VkClearColorValue clear_color = VkClearColorValue({ { color.x, color.y, color.z, color.w } }); - vkCmdClearColorImage(cmd, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource_range); + RenderCore::Get().vkCmdClearColorImage(cmd, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource_range); TransitionLayout(old_layout, cmd); } else if(m_type == ImageType::Depth) @@ -105,7 +105,7 @@ namespace mlx VkClearDepthStencilValue clear_depth_stencil = { 1.0f, 1 }; subresource_range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, cmd); - vkCmdClearDepthStencilImage(cmd, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_depth_stencil, 1, &subresource_range); + RenderCore::Get().vkCmdClearDepthStencilImage(cmd, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_depth_stencil, 1, &subresource_range); } } @@ -189,7 +189,7 @@ namespace mlx TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, cmd); kvfCopyImageToBuffer(cmd, m_staging_buffer->Get(), m_image, m_staging_buffer->GetOffset(), VK_IMAGE_ASPECT_COLOR_BIT, { m_width, m_height, 1 }); TransitionLayout(old_layout, cmd); - vkEndCommandBuffer(cmd); + RenderCore::Get().vkEndCommandBuffer(cmd); VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice()); kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence); kvfDestroyFence(RenderCore::Get().GetDevice(), fence); diff --git a/runtime/Sources/Renderer/Memory.cpp b/runtime/Sources/Renderer/Memory.cpp index 7812525..3587dca 100644 --- a/runtime/Sources/Renderer/Memory.cpp +++ b/runtime/Sources/Renderer/Memory.cpp @@ -27,23 +27,23 @@ namespace mlx void GPUAllocator::Init() noexcept { VmaVulkanFunctions vma_vulkan_func{}; - vma_vulkan_func.vkAllocateMemory = vkAllocateMemory; - vma_vulkan_func.vkBindBufferMemory = vkBindBufferMemory; - vma_vulkan_func.vkBindImageMemory = vkBindImageMemory; - vma_vulkan_func.vkCreateBuffer = vkCreateBuffer; - vma_vulkan_func.vkCreateImage = vkCreateImage; - vma_vulkan_func.vkDestroyBuffer = vkDestroyBuffer; - vma_vulkan_func.vkDestroyImage = vkDestroyImage; - vma_vulkan_func.vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges; - vma_vulkan_func.vkFreeMemory = vkFreeMemory; - vma_vulkan_func.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements; - vma_vulkan_func.vkGetImageMemoryRequirements = vkGetImageMemoryRequirements; - vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties; - vma_vulkan_func.vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties; - vma_vulkan_func.vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges; - vma_vulkan_func.vkMapMemory = vkMapMemory; - vma_vulkan_func.vkUnmapMemory = vkUnmapMemory; - vma_vulkan_func.vkCmdCopyBuffer = vkCmdCopyBuffer; + vma_vulkan_func.vkAllocateMemory = RenderCore::Get().vkAllocateMemory; + vma_vulkan_func.vkBindBufferMemory = RenderCore::Get().vkBindBufferMemory; + vma_vulkan_func.vkBindImageMemory = RenderCore::Get().vkBindImageMemory; + vma_vulkan_func.vkCreateBuffer = RenderCore::Get().vkCreateBuffer; + vma_vulkan_func.vkCreateImage = RenderCore::Get().vkCreateImage; + vma_vulkan_func.vkDestroyBuffer = RenderCore::Get().vkDestroyBuffer; + vma_vulkan_func.vkDestroyImage = RenderCore::Get().vkDestroyImage; + vma_vulkan_func.vkFlushMappedMemoryRanges = RenderCore::Get().vkFlushMappedMemoryRanges; + vma_vulkan_func.vkFreeMemory = RenderCore::Get().vkFreeMemory; + vma_vulkan_func.vkGetBufferMemoryRequirements = RenderCore::Get().vkGetBufferMemoryRequirements; + vma_vulkan_func.vkGetImageMemoryRequirements = RenderCore::Get().vkGetImageMemoryRequirements; + vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties = RenderCore::Get().vkGetPhysicalDeviceMemoryProperties; + vma_vulkan_func.vkGetPhysicalDeviceProperties = RenderCore::Get().vkGetPhysicalDeviceProperties; + vma_vulkan_func.vkInvalidateMappedMemoryRanges = RenderCore::Get().vkInvalidateMappedMemoryRanges; + vma_vulkan_func.vkMapMemory = RenderCore::Get().vkMapMemory; + vma_vulkan_func.vkUnmapMemory = RenderCore::Get().vkUnmapMemory; + vma_vulkan_func.vkCmdCopyBuffer = RenderCore::Get().vkCmdCopyBuffer; VmaAllocatorCreateInfo allocator_create_info{}; allocator_create_info.vulkanApiVersion = VK_API_VERSION_1_0; diff --git a/runtime/Sources/Renderer/Pipelines/Graphics.cpp b/runtime/Sources/Renderer/Pipelines/Graphics.cpp index 7939b5e..6fa92e0 100644 --- a/runtime/Sources/Renderer/Pipelines/Graphics.cpp +++ b/runtime/Sources/Renderer/Pipelines/Graphics.cpp @@ -30,7 +30,7 @@ namespace mlx CreateFramebuffers(m_attachments, descriptor.clear_color_attachments); VkPhysicalDeviceFeatures features{}; - vkGetPhysicalDeviceFeatures(RenderCore::Get().GetPhysicalDevice(), &features); + mlx::RenderCore::Get().vkGetPhysicalDeviceFeatures(RenderCore::Get().GetPhysicalDevice(), &features); KvfGraphicsPipelineBuilder* builder = kvfCreateGPipelineBuilder(); kvfGPipelineBuilderAddShaderStage(builder, p_vertex_shader->GetShaderStage(), p_vertex_shader->GetShaderModule(), "main"); @@ -73,12 +73,12 @@ namespace mlx viewport.height = fb_extent.height; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; - vkCmdSetViewport(command_buffer, 0, 1, &viewport); + RenderCore::Get().vkCmdSetViewport(command_buffer, 0, 1, &viewport); VkRect2D scissor{}; scissor.offset = { 0, 0 }; scissor.extent = fb_extent; - vkCmdSetScissor(command_buffer, 0, 1, &scissor); + RenderCore::Get().vkCmdSetScissor(command_buffer, 0, 1, &scissor); for(std::size_t i = 0; i < m_clears.size(); i++) { @@ -92,13 +92,13 @@ namespace mlx m_clears.back().depthStencil = VkClearDepthStencilValue{ 1.0f, 0 }; kvfBeginRenderPass(m_renderpass, command_buffer, fb, fb_extent, m_clears.data(), m_clears.size()); - vkCmdBindPipeline(command_buffer, GetPipelineBindPoint(), GetPipeline()); + RenderCore::Get().vkCmdBindPipeline(command_buffer, GetPipelineBindPoint(), GetPipeline()); return true; } void GraphicPipeline::EndPipeline(VkCommandBuffer command_buffer) noexcept { - vkCmdEndRenderPass(command_buffer); + RenderCore::Get().vkCmdEndRenderPass(command_buffer); } void GraphicPipeline::Destroy() noexcept diff --git a/runtime/Sources/Renderer/RenderCore.cpp b/runtime/Sources/Renderer/RenderCore.cpp index 79ca02d..c04c52f 100644 --- a/runtime/Sources/Renderer/RenderCore.cpp +++ b/runtime/Sources/Renderer/RenderCore.cpp @@ -43,10 +43,16 @@ namespace mlx std::cout << std::endl; } - void RenderCore::Init() noexcept + RenderCore* RenderCore::s_instance = nullptr; + + RenderCore::RenderCore() { + s_instance = this; + loader = std::make_unique(); + LoadKVFGlobalVulkanFunctionPointers(); + kvfSetErrorCallback(&ErrorCallback); kvfSetValidationErrorCallback(&ValidationErrorCallback); kvfSetValidationWarningCallback(&ValidationWarningCallback); @@ -63,6 +69,7 @@ namespace mlx DebugLog("Vulkan : instance created"); loader->LoadInstance(m_instance); + LoadKVFInstanceVulkanFunctionPointers(); VkSurfaceKHR surface = window.CreateVulkanSurface(m_instance); @@ -80,12 +87,109 @@ namespace mlx DebugLog("Vulkan : logical device created"); loader->LoadDevice(m_device); + LoadKVFDeviceVulkanFunctionPointers(); vkDestroySurfaceKHR(m_instance, surface, nullptr); FatalError("caca"); } - void RenderCore::Destroy() noexcept +#undef MLX_LOAD_FUNCTION +#define MLX_LOAD_FUNCTION(fn) pfns.fn = this->fn + + void RenderCore::LoadKVFGlobalVulkanFunctionPointers() const noexcept + { + KvfGlobalVulkanFunctions pfns; + MLX_LOAD_FUNCTION(vkCreateInstance); + MLX_LOAD_FUNCTION(vkEnumerateInstanceExtensionProperties); + MLX_LOAD_FUNCTION(vkEnumerateInstanceLayerProperties); + MLX_LOAD_FUNCTION(vkGetInstanceProcAddr); + kvfPassGlobalVulkanFunctionPointers(&pfns); + } + + void RenderCore::LoadKVFInstanceVulkanFunctionPointers() const noexcept + { + KvfInstanceVulkanFunctions pfns; + MLX_LOAD_FUNCTION(vkCreateDevice); + MLX_LOAD_FUNCTION(vkDestroyInstance); + MLX_LOAD_FUNCTION(vkEnumerateDeviceExtensionProperties); + MLX_LOAD_FUNCTION(vkEnumeratePhysicalDevices); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceFeatures); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceFormatProperties); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceImageFormatProperties); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceMemoryProperties); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceProperties); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties); + MLX_LOAD_FUNCTION(vkDestroySurfaceKHR); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR); + MLX_LOAD_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR); + kvfPassInstanceVulkanFunctionPointers(&pfns); + } + + void RenderCore::LoadKVFDeviceVulkanFunctionPointers() const noexcept + { + KvfDeviceVulkanFunctions pfns; + MLX_LOAD_FUNCTION(vkAllocateCommandBuffers); + MLX_LOAD_FUNCTION(vkAllocateDescriptorSets); + MLX_LOAD_FUNCTION(vkBeginCommandBuffer); + MLX_LOAD_FUNCTION(vkCmdBeginRenderPass); + MLX_LOAD_FUNCTION(vkCmdCopyBuffer); + MLX_LOAD_FUNCTION(vkCmdCopyBufferToImage); + MLX_LOAD_FUNCTION(vkCmdCopyImage); + MLX_LOAD_FUNCTION(vkCmdCopyImageToBuffer); + MLX_LOAD_FUNCTION(vkCmdEndRenderPass); + MLX_LOAD_FUNCTION(vkCmdPipelineBarrier); + MLX_LOAD_FUNCTION(vkCreateBuffer); + MLX_LOAD_FUNCTION(vkCreateCommandPool); + MLX_LOAD_FUNCTION(vkCreateDescriptorPool); + MLX_LOAD_FUNCTION(vkCreateDescriptorSetLayout); + MLX_LOAD_FUNCTION(vkCreateFence); + MLX_LOAD_FUNCTION(vkCreateFramebuffer); + MLX_LOAD_FUNCTION(vkCreateGraphicsPipelines); + MLX_LOAD_FUNCTION(vkCreateImage); + MLX_LOAD_FUNCTION(vkCreateImageView); + MLX_LOAD_FUNCTION(vkCreatePipelineLayout); + MLX_LOAD_FUNCTION(vkCreateRenderPass); + MLX_LOAD_FUNCTION(vkCreateSampler); + MLX_LOAD_FUNCTION(vkCreateSemaphore); + MLX_LOAD_FUNCTION(vkCreateShaderModule); + MLX_LOAD_FUNCTION(vkDestroyBuffer); + MLX_LOAD_FUNCTION(vkDestroyCommandPool); + MLX_LOAD_FUNCTION(vkDestroyDescriptorPool); + MLX_LOAD_FUNCTION(vkDestroyDescriptorSetLayout); + MLX_LOAD_FUNCTION(vkDestroyDevice); + MLX_LOAD_FUNCTION(vkDestroyFence); + MLX_LOAD_FUNCTION(vkDestroyFramebuffer); + MLX_LOAD_FUNCTION(vkDestroyImage); + MLX_LOAD_FUNCTION(vkDestroyImageView); + MLX_LOAD_FUNCTION(vkDestroyPipeline); + MLX_LOAD_FUNCTION(vkDestroyPipelineLayout); + MLX_LOAD_FUNCTION(vkDestroyRenderPass); + MLX_LOAD_FUNCTION(vkDestroySampler); + MLX_LOAD_FUNCTION(vkDestroySemaphore); + MLX_LOAD_FUNCTION(vkDestroyShaderModule); + MLX_LOAD_FUNCTION(vkDeviceWaitIdle); + MLX_LOAD_FUNCTION(vkEndCommandBuffer); + MLX_LOAD_FUNCTION(vkGetDeviceQueue); + MLX_LOAD_FUNCTION(vkGetImageSubresourceLayout); + MLX_LOAD_FUNCTION(vkQueueSubmit); + MLX_LOAD_FUNCTION(vkResetCommandBuffer); + MLX_LOAD_FUNCTION(vkResetDescriptorPool); + MLX_LOAD_FUNCTION(vkResetEvent); + MLX_LOAD_FUNCTION(vkResetFences); + MLX_LOAD_FUNCTION(vkUpdateDescriptorSets); + MLX_LOAD_FUNCTION(vkWaitForFences); + MLX_LOAD_FUNCTION(vkCreateSwapchainKHR); + MLX_LOAD_FUNCTION(vkDestroySwapchainKHR); + MLX_LOAD_FUNCTION(vkGetSwapchainImagesKHR); + MLX_LOAD_FUNCTION(vkQueuePresentKHR); + kvfPassDeviceVulkanFunctionPointers(m_device, &pfns); + } + +#undef MLX_LOAD_FUNCTION + + RenderCore::~RenderCore() { WaitDeviceIdle(); kvfDestroyDevice(m_device); @@ -93,5 +197,7 @@ namespace mlx kvfDestroyInstance(m_instance); DebugLog("Vulkan : instance destroyed"); loader.reset(); + + s_instance = nullptr; } } diff --git a/runtime/Sources/Renderer/RenderPasses/2DPass.cpp b/runtime/Sources/Renderer/RenderPasses/2DPass.cpp index 962ce99..19ba2d7 100644 --- a/runtime/Sources/Renderer/RenderPasses/2DPass.cpp +++ b/runtime/Sources/Renderer/RenderPasses/2DPass.cpp @@ -106,8 +106,8 @@ namespace mlx sprite->GetTexture()->Update(cmd); sprite->Bind(frame_index, cmd); std::array sets = { p_viewer_data_set->GetSet(frame_index), sprite->GetSet(frame_index) }; - vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr); - vkCmdPushConstants(cmd, m_pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(SpriteData), &sprite_data); + mlx::RenderCore::Get().vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr); + mlx::RenderCore::Get().vkCmdPushConstants(cmd, m_pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(SpriteData), &sprite_data); sprite->GetMesh()->Draw(cmd, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef()); } m_pipeline.EndPipeline(cmd); diff --git a/runtime/Sources/Renderer/RenderPasses/FinalPass.cpp b/runtime/Sources/Renderer/RenderPasses/FinalPass.cpp index c36d703..5a4014b 100644 --- a/runtime/Sources/Renderer/RenderPasses/FinalPass.cpp +++ b/runtime/Sources/Renderer/RenderPasses/FinalPass.cpp @@ -61,8 +61,8 @@ namespace mlx m_pipeline.BindPipeline(cmd, renderer.GetSwapchainImageIndex(), { 0.0f, 0.0f, 0.0f, 1.0f }); VkDescriptorSet set = p_set->GetSet(renderer.GetCurrentFrameIndex()); - vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, 1, &set, 0, nullptr); - vkCmdDraw(cmd, 3, 1, 0, 0); + RenderCore::Get().vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, 1, &set, 0, nullptr); + RenderCore::Get().vkCmdDraw(cmd, 3, 1, 0, 0); renderer.GetDrawCallsCounterRef()++; renderer.GetPolygonDrawnCounterRef()++; m_pipeline.EndPipeline(cmd); diff --git a/runtime/Sources/Renderer/Renderer.cpp b/runtime/Sources/Renderer/Renderer.cpp index e8bacc7..b240290 100644 --- a/runtime/Sources/Renderer/Renderer.cpp +++ b/runtime/Sources/Renderer/Renderer.cpp @@ -57,7 +57,7 @@ namespace mlx bool Renderer::BeginFrame() { kvfWaitForFence(RenderCore::Get().GetDevice(), m_cmd_fences[m_current_frame_index]); - VkResult result = vkAcquireNextImageKHR(RenderCore::Get().GetDevice(), m_swapchain, UINT64_MAX, m_image_available_semaphores[m_current_frame_index], VK_NULL_HANDLE, &m_swapchain_image_index); + VkResult result = RenderCore::Get().vkAcquireNextImageKHR(RenderCore::Get().GetDevice(), m_swapchain, UINT64_MAX, m_image_available_semaphores[m_current_frame_index], VK_NULL_HANDLE, &m_swapchain_image_index); if(result == VK_ERROR_OUT_OF_DATE_KHR) { DestroySwapchain(); @@ -68,7 +68,7 @@ namespace mlx else if(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) FatalError("Vulkan error : failed to acquire swapchain image, %", kvfVerbaliseVkResult(result)); - vkResetCommandBuffer(m_cmd_buffers[m_current_frame_index], 0); + RenderCore::Get().vkResetCommandBuffer(m_cmd_buffers[m_current_frame_index], 0); kvfBeginCommandBuffer(m_cmd_buffers[m_current_frame_index], 0); m_drawcalls = 0; m_polygons_drawn = 0; @@ -102,7 +102,7 @@ namespace mlx std::uint32_t images_count = kvfGetSwapchainImagesCount(m_swapchain); std::vector tmp(images_count); m_swapchain_images.resize(images_count); - vkGetSwapchainImagesKHR(RenderCore::Get().GetDevice(), m_swapchain, &images_count, tmp.data()); + RenderCore::Get().vkGetSwapchainImagesKHR(RenderCore::Get().GetDevice(), m_swapchain, &images_count, tmp.data()); for(std::size_t i = 0; i < images_count; i++) { m_swapchain_images[i].Init(tmp[i], kvfGetSwapchainImagesFormat(m_swapchain), extent.width, extent.height); @@ -136,7 +136,7 @@ namespace mlx } DestroySwapchain(); - vkDestroySurfaceKHR(RenderCore::Get().GetInstance(), m_surface, nullptr); + RenderCore::Get().vkDestroySurfaceKHR(RenderCore::Get().GetInstance(), m_surface, nullptr); DebugLog("Vulkan : surface destroyed"); m_surface = VK_NULL_HANDLE; } diff --git a/runtime/Sources/Renderer/Vulkan/VulkanLoader.cpp b/runtime/Sources/Renderer/Vulkan/VulkanLoader.cpp index 273a902..cba9310 100644 --- a/runtime/Sources/Renderer/Vulkan/VulkanLoader.cpp +++ b/runtime/Sources/Renderer/Vulkan/VulkanLoader.cpp @@ -1,7 +1,6 @@ -#include "Renderer/Vulkan/VulkanPrototypes.h" -#include "vulkan/vulkan_core.h" #include #include +#include #ifdef MLX_PLAT_WINDOWS __declspec(dllimport) HMODULE __stdcall LoadLibraryA(LPCSTR); @@ -29,19 +28,19 @@ namespace mlx { static inline PFN_vkVoidFunction vkGetInstanceProcAddrStub(Handle context, const char* name) { - PFN_vkVoidFunction function = vkGetInstanceProcAddr(static_cast(context), name); + PFN_vkVoidFunction function = RenderCore::Get().vkGetInstanceProcAddr(static_cast(context), name); if(!function) FatalError("Vulkan loader : could not load '%'", name); - DebugLog("Vulkan loader : loaded %", name); + //DebugLog("Vulkan loader : loaded %", name); return function; } static inline PFN_vkVoidFunction vkGetDeviceProcAddrStub(Handle context, const char* name) { - PFN_vkVoidFunction function = vkGetDeviceProcAddr(static_cast(context), name); + PFN_vkVoidFunction function = RenderCore::Get().vkGetDeviceProcAddr(static_cast(context), name); if(!function) FatalError("Vulkan loader : could not load '%'", name); - DebugLog("Vulkan loader : loaded %", name); + //DebugLog("Vulkan loader : loaded %", name); return function; } @@ -90,19 +89,20 @@ namespace mlx { p_module = Internal::LoadLib(libname); if(p_module != nullptr) - break; + { + DISABLE_GCC_PEDANTIC_WARNINGS + RenderCore::Get().vkGetInstanceProcAddr = reinterpret_cast(Internal::GetSymbol(p_module, "vkGetInstanceProcAddr")); + RESTORE_GCC_PEDANTIC_WARNINGS + if(RenderCore::Get().vkGetInstanceProcAddr) + { + DebugLog("Vulkan loader : libvulkan loaded using '%'", libname); + break; + } + } } - if(!p_module) + if(!p_module || !RenderCore::Get().vkGetInstanceProcAddr) FatalError("Vulkan loader : failed to load libvulkan"); - - DISABLE_GCC_PEDANTIC_WARNINGS - vkGetInstanceProcAddr = reinterpret_cast(Internal::GetSymbol(p_module, "vkGetInstanceProcAddr")); - RESTORE_GCC_PEDANTIC_WARNINGS - - if(!vkGetInstanceProcAddr) - FatalError("Vulkan loader : could not get symbol for 'vkGetInstanceProcAddr'"); - DebugLog("Vulkan loader : libvulkan loaded"); - LoadGlobalFunctions(NULL, Internal::vkGetInstanceProcAddrStub); + LoadGlobalFunctions(nullptr, Internal::vkGetInstanceProcAddrStub); } void VulkanLoader::LoadInstance(VkInstance instance) @@ -117,173 +117,25 @@ namespace mlx void VulkanLoader::LoadGlobalFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*)) noexcept { - #ifdef VK_VERSION_1_0 - vkCreateInstance = reinterpret_cast(load(context, "vkCreateInstance")); - vkEnumerateInstanceExtensionProperties = reinterpret_cast(load(context, "vkEnumerateInstanceExtensionProperties")); - vkEnumerateInstanceLayerProperties = reinterpret_cast(load(context, "vkEnumerateInstanceLayerProperties")); - #endif + #define MLX_VULKAN_GLOBAL_FUNCTION(fn) RenderCore::Get().fn = reinterpret_cast(load(context, #fn)); + #include + #undef MLX_VULKAN_GLOBAL_FUNCTION DebugLog("Vulkan loader : global functions loaded"); } void VulkanLoader::LoadInstanceFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*)) noexcept { - #ifdef VK_VERSION_1_0 - vkCreateDevice = reinterpret_cast(load(context, "vkCreateDevice")); - vkDestroyInstance = reinterpret_cast(load(context, "vkDestroyInstance")); - vkEnumerateDeviceExtensionProperties = reinterpret_cast(load(context, "vkEnumerateDeviceExtensionProperties")); - vkEnumerateDeviceLayerProperties = reinterpret_cast(load(context, "vkEnumerateDeviceLayerProperties")); - vkEnumeratePhysicalDevices = reinterpret_cast(load(context, "vkEnumeratePhysicalDevices")); - vkGetDeviceProcAddr = reinterpret_cast(load(context, "vkGetDeviceProcAddr")); - vkGetPhysicalDeviceFeatures = reinterpret_cast(load(context, "vkGetPhysicalDeviceFeatures")); - vkGetPhysicalDeviceFormatProperties = reinterpret_cast(load(context, "vkGetPhysicalDeviceFormatProperties")); - vkGetPhysicalDeviceImageFormatProperties = reinterpret_cast(load(context, "vkGetPhysicalDeviceImageFormatProperties")); - vkGetPhysicalDeviceMemoryProperties = reinterpret_cast(load(context, "vkGetPhysicalDeviceMemoryProperties")); - vkGetPhysicalDeviceProperties = reinterpret_cast(load(context, "vkGetPhysicalDeviceProperties")); - vkGetPhysicalDeviceQueueFamilyProperties = reinterpret_cast(load(context, "vkGetPhysicalDeviceQueueFamilyProperties")); - vkGetPhysicalDeviceSparseImageFormatProperties = reinterpret_cast(load(context, "vkGetPhysicalDeviceSparseImageFormatProperties")); - #endif - #ifdef VK_KHR_surface - vkDestroySurfaceKHR = reinterpret_cast(load(context, "vkDestroySurfaceKHR")); - vkGetPhysicalDeviceSurfaceCapabilitiesKHR = reinterpret_cast(load(context, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR")); - vkGetPhysicalDeviceSurfaceFormatsKHR = reinterpret_cast(load(context, "vkGetPhysicalDeviceSurfaceFormatsKHR")); - vkGetPhysicalDeviceSurfacePresentModesKHR = reinterpret_cast(load(context, "vkGetPhysicalDeviceSurfacePresentModesKHR")); - vkGetPhysicalDeviceSurfaceSupportKHR = reinterpret_cast(load(context, "vkGetPhysicalDeviceSurfaceSupportKHR")); - #endif + #define MLX_VULKAN_INSTANCE_FUNCTION(fn) RenderCore::Get().fn = reinterpret_cast(load(context, #fn)); + #include + #undef MLX_VULKAN_INSTANCE_FUNCTION DebugLog("Vulkan loader : instance functions loaded"); } void VulkanLoader::LoadDeviceFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*)) noexcept { - #ifdef VK_VERSION_1_0 - vkAllocateCommandBuffers = reinterpret_cast(load(context, "vkAllocateCommandBuffers")); - vkAllocateDescriptorSets = reinterpret_cast(load(context, "vkAllocateDescriptorSets")); - vkAllocateMemory = reinterpret_cast(load(context, "vkAllocateMemory")); - vkBeginCommandBuffer = reinterpret_cast(load(context, "vkBeginCommandBuffer")); - vkBindBufferMemory = reinterpret_cast(load(context, "vkBindBufferMemory")); - vkBindImageMemory = reinterpret_cast(load(context, "vkBindImageMemory")); - vkCmdBeginQuery = reinterpret_cast(load(context, "vkCmdBeginQuery")); - vkCmdBeginRenderPass = reinterpret_cast(load(context, "vkCmdBeginRenderPass")); - vkCmdBindDescriptorSets = reinterpret_cast(load(context, "vkCmdBindDescriptorSets")); - vkCmdBindIndexBuffer = reinterpret_cast(load(context, "vkCmdBindIndexBuffer")); - vkCmdBindPipeline = reinterpret_cast(load(context, "vkCmdBindPipeline")); - vkCmdBindVertexBuffers = reinterpret_cast(load(context, "vkCmdBindVertexBuffers")); - vkCmdBlitImage = reinterpret_cast(load(context, "vkCmdBlitImage")); - vkCmdClearAttachments = reinterpret_cast(load(context, "vkCmdClearAttachments")); - vkCmdClearColorImage = reinterpret_cast(load(context, "vkCmdClearColorImage")); - vkCmdClearDepthStencilImage = reinterpret_cast(load(context, "vkCmdClearDepthStencilImage")); - vkCmdCopyBuffer = reinterpret_cast(load(context, "vkCmdCopyBuffer")); - vkCmdCopyBufferToImage = reinterpret_cast(load(context, "vkCmdCopyBufferToImage")); - vkCmdCopyImage = reinterpret_cast(load(context, "vkCmdCopyImage")); - vkCmdCopyImageToBuffer = reinterpret_cast(load(context, "vkCmdCopyImageToBuffer")); - vkCmdCopyQueryPoolResults = reinterpret_cast(load(context, "vkCmdCopyQueryPoolResults")); - vkCmdDispatch = reinterpret_cast(load(context, "vkCmdDispatch")); - vkCmdDispatchIndirect = reinterpret_cast(load(context, "vkCmdDispatchIndirect")); - vkCmdDraw = reinterpret_cast(load(context, "vkCmdDraw")); - vkCmdDrawIndexed = reinterpret_cast(load(context, "vkCmdDrawIndexed")); - vkCmdDrawIndexedIndirect = reinterpret_cast(load(context, "vkCmdDrawIndexedIndirect")); - vkCmdDrawIndirect = reinterpret_cast(load(context, "vkCmdDrawIndirect")); - vkCmdEndQuery = reinterpret_cast(load(context, "vkCmdEndQuery")); - vkCmdEndRenderPass = reinterpret_cast(load(context, "vkCmdEndRenderPass")); - vkCmdExecuteCommands = reinterpret_cast(load(context, "vkCmdExecuteCommands")); - vkCmdFillBuffer = reinterpret_cast(load(context, "vkCmdFillBuffer")); - vkCmdNextSubpass = reinterpret_cast(load(context, "vkCmdNextSubpass")); - vkCmdPipelineBarrier = reinterpret_cast(load(context, "vkCmdPipelineBarrier")); - vkCmdPushConstants = reinterpret_cast(load(context, "vkCmdPushConstants")); - vkCmdResetEvent = reinterpret_cast(load(context, "vkCmdResetEvent")); - vkCmdResetQueryPool = reinterpret_cast(load(context, "vkCmdResetQueryPool")); - vkCmdResolveImage = reinterpret_cast(load(context, "vkCmdResolveImage")); - vkCmdSetBlendConstants = reinterpret_cast(load(context, "vkCmdSetBlendConstants")); - vkCmdSetDepthBias = reinterpret_cast(load(context, "vkCmdSetDepthBias")); - vkCmdSetDepthBounds = reinterpret_cast(load(context, "vkCmdSetDepthBounds")); - vkCmdSetEvent = reinterpret_cast(load(context, "vkCmdSetEvent")); - vkCmdSetLineWidth = reinterpret_cast(load(context, "vkCmdSetLineWidth")); - vkCmdSetScissor = reinterpret_cast(load(context, "vkCmdSetScissor")); - vkCmdSetStencilCompareMask = reinterpret_cast(load(context, "vkCmdSetStencilCompareMask")); - vkCmdSetStencilReference = reinterpret_cast(load(context, "vkCmdSetStencilReference")); - vkCmdSetStencilWriteMask = reinterpret_cast(load(context, "vkCmdSetStencilWriteMask")); - vkCmdSetViewport = reinterpret_cast(load(context, "vkCmdSetViewport")); - vkCmdUpdateBuffer = reinterpret_cast(load(context, "vkCmdUpdateBuffer")); - vkCmdWaitEvents = reinterpret_cast(load(context, "vkCmdWaitEvents")); - vkCmdWriteTimestamp = reinterpret_cast(load(context, "vkCmdWriteTimestamp")); - vkCreateBuffer = reinterpret_cast(load(context, "vkCreateBuffer")); - vkCreateBufferView = reinterpret_cast(load(context, "vkCreateBufferView")); - vkCreateCommandPool = reinterpret_cast(load(context, "vkCreateCommandPool")); - vkCreateComputePipelines = reinterpret_cast(load(context, "vkCreateComputePipelines")); - vkCreateDescriptorPool = reinterpret_cast(load(context, "vkCreateDescriptorPool")); - vkCreateDescriptorSetLayout = reinterpret_cast(load(context, "vkCreateDescriptorSetLayout")); - vkCreateEvent = reinterpret_cast(load(context, "vkCreateEvent")); - vkCreateFence = reinterpret_cast(load(context, "vkCreateFence")); - vkCreateFramebuffer = reinterpret_cast(load(context, "vkCreateFramebuffer")); - vkCreateGraphicsPipelines = reinterpret_cast(load(context, "vkCreateGraphicsPipelines")); - vkCreateImage = reinterpret_cast(load(context, "vkCreateImage")); - vkCreateImageView = reinterpret_cast(load(context, "vkCreateImageView")); - vkCreatePipelineCache = reinterpret_cast(load(context, "vkCreatePipelineCache")); - vkCreatePipelineLayout = reinterpret_cast(load(context, "vkCreatePipelineLayout")); - vkCreateQueryPool = reinterpret_cast(load(context, "vkCreateQueryPool")); - vkCreateRenderPass = reinterpret_cast(load(context, "vkCreateRenderPass")); - vkCreateSampler = reinterpret_cast(load(context, "vkCreateSampler")); - vkCreateSemaphore = reinterpret_cast(load(context, "vkCreateSemaphore")); - vkCreateShaderModule = reinterpret_cast(load(context, "vkCreateShaderModule")); - vkDestroyBuffer = reinterpret_cast(load(context, "vkDestroyBuffer")); - vkDestroyBufferView = reinterpret_cast(load(context, "vkDestroyBufferView")); - vkDestroyCommandPool = reinterpret_cast(load(context, "vkDestroyCommandPool")); - vkDestroyDescriptorPool = reinterpret_cast(load(context, "vkDestroyDescriptorPool")); - vkDestroyDescriptorSetLayout = reinterpret_cast(load(context, "vkDestroyDescriptorSetLayout")); - vkDestroyDevice = reinterpret_cast(load(context, "vkDestroyDevice")); - vkDestroyEvent = reinterpret_cast(load(context, "vkDestroyEvent")); - vkDestroyFence = reinterpret_cast(load(context, "vkDestroyFence")); - vkDestroyFramebuffer = reinterpret_cast(load(context, "vkDestroyFramebuffer")); - vkDestroyImage = reinterpret_cast(load(context, "vkDestroyImage")); - vkDestroyImageView = reinterpret_cast(load(context, "vkDestroyImageView")); - vkDestroyPipeline = reinterpret_cast(load(context, "vkDestroyPipeline")); - vkDestroyPipelineCache = reinterpret_cast(load(context, "vkDestroyPipelineCache")); - vkDestroyPipelineLayout = reinterpret_cast(load(context, "vkDestroyPipelineLayout")); - vkDestroyQueryPool = reinterpret_cast(load(context, "vkDestroyQueryPool")); - vkDestroyRenderPass = reinterpret_cast(load(context, "vkDestroyRenderPass")); - vkDestroySampler = reinterpret_cast(load(context, "vkDestroySampler")); - vkDestroySemaphore = reinterpret_cast(load(context, "vkDestroySemaphore")); - vkDestroyShaderModule = reinterpret_cast(load(context, "vkDestroyShaderModule")); - vkDeviceWaitIdle = reinterpret_cast(load(context, "vkDeviceWaitIdle")); - vkEndCommandBuffer = reinterpret_cast(load(context, "vkEndCommandBuffer")); - vkFlushMappedMemoryRanges = reinterpret_cast(load(context, "vkFlushMappedMemoryRanges")); - vkFreeCommandBuffers = reinterpret_cast(load(context, "vkFreeCommandBuffers")); - vkFreeDescriptorSets = reinterpret_cast(load(context, "vkFreeDescriptorSets")); - vkFreeMemory = reinterpret_cast(load(context, "vkFreeMemory")); - vkGetBufferMemoryRequirements = reinterpret_cast(load(context, "vkGetBufferMemoryRequirements")); - vkGetDeviceMemoryCommitment = reinterpret_cast(load(context, "vkGetDeviceMemoryCommitment")); - vkGetDeviceQueue = reinterpret_cast(load(context, "vkGetDeviceQueue")); - vkGetEventStatus = reinterpret_cast(load(context, "vkGetEventStatus")); - vkGetFenceStatus = reinterpret_cast(load(context, "vkGetFenceStatus")); - vkGetImageMemoryRequirements = reinterpret_cast(load(context, "vkGetImageMemoryRequirements")); - vkGetImageSparseMemoryRequirements = reinterpret_cast(load(context, "vkGetImageSparseMemoryRequirements")); - vkGetImageSubresourceLayout = reinterpret_cast(load(context, "vkGetImageSubresourceLayout")); - vkGetPipelineCacheData = reinterpret_cast(load(context, "vkGetPipelineCacheData")); - vkGetQueryPoolResults = reinterpret_cast(load(context, "vkGetQueryPoolResults")); - vkGetRenderAreaGranularity = reinterpret_cast(load(context, "vkGetRenderAreaGranularity")); - vkInvalidateMappedMemoryRanges = reinterpret_cast(load(context, "vkInvalidateMappedMemoryRanges")); - vkMapMemory = reinterpret_cast(load(context, "vkMapMemory")); - vkMergePipelineCaches = reinterpret_cast(load(context, "vkMergePipelineCaches")); - vkQueueBindSparse = reinterpret_cast(load(context, "vkQueueBindSparse")); - vkQueueSubmit = reinterpret_cast(load(context, "vkQueueSubmit")); - vkQueueWaitIdle = reinterpret_cast(load(context, "vkQueueWaitIdle")); - vkResetCommandBuffer = reinterpret_cast(load(context, "vkResetCommandBuffer")); - vkResetCommandPool = reinterpret_cast(load(context, "vkResetCommandPool")); - vkResetDescriptorPool = reinterpret_cast(load(context, "vkResetDescriptorPool")); - vkResetEvent = reinterpret_cast(load(context, "vkResetEvent")); - vkResetFences = reinterpret_cast(load(context, "vkResetFences")); - vkSetEvent = reinterpret_cast(load(context, "vkSetEvent")); - vkUnmapMemory = reinterpret_cast(load(context, "vkUnmapMemory")); - vkUpdateDescriptorSets = reinterpret_cast(load(context, "vkUpdateDescriptorSets")); - vkWaitForFences = reinterpret_cast(load(context, "vkWaitForFences")); - #endif - #ifdef VK_KHR_swapchain - vkAcquireNextImageKHR = reinterpret_cast(load(context, "vkAcquireNextImageKHR")); - vkCreateSwapchainKHR = reinterpret_cast(load(context, "vkCreateSwapchainKHR")); - vkDestroySwapchainKHR = reinterpret_cast(load(context, "vkDestroySwapchainKHR")); - vkGetSwapchainImagesKHR = reinterpret_cast(load(context, "vkGetSwapchainImagesKHR")); - vkQueuePresentKHR = reinterpret_cast(load(context, "vkQueuePresentKHR")); - #endif - + #define MLX_VULKAN_DEVICE_FUNCTION(fn) RenderCore::Get().fn = reinterpret_cast(load(context, #fn)); + #include + #undef MLX_VULKAN_DEVICE_FUNCTION DebugLog("Vulkan loader : device functions loaded"); } @@ -298,157 +150,3 @@ namespace mlx DebugLog("Vulkan loader : libvulkan unloaded"); } } - -#ifdef VK_VERSION_1_0 - PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers; - PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets; - PFN_vkAllocateMemory vkAllocateMemory; - PFN_vkBeginCommandBuffer vkBeginCommandBuffer; - PFN_vkBindBufferMemory vkBindBufferMemory; - PFN_vkBindImageMemory vkBindImageMemory; - PFN_vkCmdBeginQuery vkCmdBeginQuery; - PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass; - PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets; - PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer; - PFN_vkCmdBindPipeline vkCmdBindPipeline; - PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers; - PFN_vkCmdBlitImage vkCmdBlitImage; - PFN_vkCmdClearAttachments vkCmdClearAttachments; - PFN_vkCmdClearColorImage vkCmdClearColorImage; - PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage; - PFN_vkCmdCopyBuffer vkCmdCopyBuffer; - PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage; - PFN_vkCmdCopyImage vkCmdCopyImage; - PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer; - PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults; - PFN_vkCmdDispatch vkCmdDispatch; - PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect; - PFN_vkCmdDraw vkCmdDraw; - PFN_vkCmdDrawIndexed vkCmdDrawIndexed; - PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect; - PFN_vkCmdDrawIndirect vkCmdDrawIndirect; - PFN_vkCmdEndQuery vkCmdEndQuery; - PFN_vkCmdEndRenderPass vkCmdEndRenderPass; - PFN_vkCmdExecuteCommands vkCmdExecuteCommands; - PFN_vkCmdFillBuffer vkCmdFillBuffer; - PFN_vkCmdNextSubpass vkCmdNextSubpass; - PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; - PFN_vkCmdPushConstants vkCmdPushConstants; - PFN_vkCmdResetEvent vkCmdResetEvent; - PFN_vkCmdResetQueryPool vkCmdResetQueryPool; - PFN_vkCmdResolveImage vkCmdResolveImage; - PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants; - PFN_vkCmdSetDepthBias vkCmdSetDepthBias; - PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds; - PFN_vkCmdSetEvent vkCmdSetEvent; - PFN_vkCmdSetLineWidth vkCmdSetLineWidth; - PFN_vkCmdSetScissor vkCmdSetScissor; - PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask; - PFN_vkCmdSetStencilReference vkCmdSetStencilReference; - PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask; - PFN_vkCmdSetViewport vkCmdSetViewport; - PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer; - PFN_vkCmdWaitEvents vkCmdWaitEvents; - PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp; - PFN_vkCreateBuffer vkCreateBuffer; - PFN_vkCreateBufferView vkCreateBufferView; - PFN_vkCreateCommandPool vkCreateCommandPool; - PFN_vkCreateComputePipelines vkCreateComputePipelines; - PFN_vkCreateDescriptorPool vkCreateDescriptorPool; - PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout; - PFN_vkCreateDevice vkCreateDevice; - PFN_vkCreateEvent vkCreateEvent; - PFN_vkCreateFence vkCreateFence; - PFN_vkCreateFramebuffer vkCreateFramebuffer; - PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines; - PFN_vkCreateImage vkCreateImage; - PFN_vkCreateImageView vkCreateImageView; - PFN_vkCreateInstance vkCreateInstance; - PFN_vkCreatePipelineCache vkCreatePipelineCache; - PFN_vkCreatePipelineLayout vkCreatePipelineLayout; - PFN_vkCreateQueryPool vkCreateQueryPool; - PFN_vkCreateRenderPass vkCreateRenderPass; - PFN_vkCreateSampler vkCreateSampler; - PFN_vkCreateSemaphore vkCreateSemaphore; - PFN_vkCreateShaderModule vkCreateShaderModule; - PFN_vkDestroyBuffer vkDestroyBuffer; - PFN_vkDestroyBufferView vkDestroyBufferView; - PFN_vkDestroyCommandPool vkDestroyCommandPool; - PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool; - PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout; - PFN_vkDestroyDevice vkDestroyDevice; - PFN_vkDestroyEvent vkDestroyEvent; - PFN_vkDestroyFence vkDestroyFence; - PFN_vkDestroyFramebuffer vkDestroyFramebuffer; - PFN_vkDestroyImage vkDestroyImage; - PFN_vkDestroyImageView vkDestroyImageView; - PFN_vkDestroyInstance vkDestroyInstance; - PFN_vkDestroyPipeline vkDestroyPipeline; - PFN_vkDestroyPipelineCache vkDestroyPipelineCache; - PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout; - PFN_vkDestroyQueryPool vkDestroyQueryPool; - PFN_vkDestroyRenderPass vkDestroyRenderPass; - PFN_vkDestroySampler vkDestroySampler; - PFN_vkDestroySemaphore vkDestroySemaphore; - PFN_vkDestroyShaderModule vkDestroyShaderModule; - PFN_vkDeviceWaitIdle vkDeviceWaitIdle; - PFN_vkEndCommandBuffer vkEndCommandBuffer; - PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties; - PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties; - PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; - PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties; - PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; - PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges; - PFN_vkFreeCommandBuffers vkFreeCommandBuffers; - PFN_vkFreeDescriptorSets vkFreeDescriptorSets; - PFN_vkFreeMemory vkFreeMemory; - PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; - PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment; - PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; - PFN_vkGetDeviceQueue vkGetDeviceQueue; - PFN_vkGetEventStatus vkGetEventStatus; - PFN_vkGetFenceStatus vkGetFenceStatus; - PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; - PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements; - PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout; - PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; - PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures; - PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties; - PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties; - PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; - PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; - PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties; - PFN_vkGetPipelineCacheData vkGetPipelineCacheData; - PFN_vkGetQueryPoolResults vkGetQueryPoolResults; - PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity; - PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges; - PFN_vkMapMemory vkMapMemory; - PFN_vkMergePipelineCaches vkMergePipelineCaches; - PFN_vkQueueBindSparse vkQueueBindSparse; - PFN_vkQueueSubmit vkQueueSubmit; - PFN_vkQueueWaitIdle vkQueueWaitIdle; - PFN_vkResetCommandBuffer vkResetCommandBuffer; - PFN_vkResetCommandPool vkResetCommandPool; - PFN_vkResetDescriptorPool vkResetDescriptorPool; - PFN_vkResetEvent vkResetEvent; - PFN_vkResetFences vkResetFences; - PFN_vkSetEvent vkSetEvent; - PFN_vkUnmapMemory vkUnmapMemory; - PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets; - PFN_vkWaitForFences vkWaitForFences; -#endif -#ifdef VK_KHR_swapchain - PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; - PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR; - PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR; - PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR; - PFN_vkQueuePresentKHR vkQueuePresentKHR; -#endif -#ifdef VK_KHR_surface - PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; - PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; - PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; - PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; -#endif diff --git a/third_party/kvf.h b/third_party/kvf.h index 5dd0758..acb29b2 100755 --- a/third_party/kvf.h +++ b/third_party/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); @@ -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; @@ -1007,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++) { @@ -1046,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); } @@ -1058,7 +1245,7 @@ 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 @@ -1100,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; @@ -1111,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); @@ -1130,16 +1318,17 @@ 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(uint32_t i = 0; i < queue_family_count; i++) { @@ -1154,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) @@ -1179,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); @@ -1199,9 +1389,10 @@ 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(uint32_t j = 0; j < device_extensions_count; j++) @@ -1235,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) @@ -1269,9 +1460,10 @@ 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(uint32_t i = 0; i < device_count; i++) { @@ -1303,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; @@ -1358,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; @@ -1381,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) { @@ -1426,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) @@ -1442,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; } @@ -1466,14 +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); + __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; } @@ -1482,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; @@ -1489,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 @@ -1504,9 +1713,10 @@ 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; @@ -1542,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(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) @@ -1565,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; } @@ -1577,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) @@ -1585,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; } @@ -1603,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 @@ -1611,20 +1842,22 @@ 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; } @@ -1670,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; @@ -1698,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; @@ -1707,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); @@ -1757,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; @@ -1779,7 +2016,7 @@ 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; } @@ -1788,6 +2025,10 @@ void kvfCopyImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage 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; @@ -1799,7 +2040,7 @@ void kvfCopyImageToBuffer(VkCommandBuffer cmd, VkBuffer dst, VkImage src, size_t 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) @@ -1807,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; @@ -1828,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; } @@ -1836,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) @@ -1846,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); @@ -1882,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) { @@ -1896,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; @@ -1909,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; } @@ -1918,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; } @@ -1939,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) @@ -1949,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; @@ -1960,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) @@ -1968,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; @@ -1985,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; } @@ -2014,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; @@ -2064,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) @@ -2169,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++) @@ -2194,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; @@ -2210,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; @@ -2221,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 = {}; @@ -2238,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; } @@ -2258,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; } @@ -2279,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) @@ -2303,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) @@ -2374,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; @@ -2382,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; } @@ -2391,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) @@ -2401,7 +2763,7 @@ void kvfResetDeviceDescriptorPools(VkDevice device) KVF_ASSERT(kvf_device != NULL); 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; } } @@ -2409,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; @@ -2539,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; @@ -2557,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; @@ -2625,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