github.com/Seikaijyu/gio@v0.0.1/internal/vk/vulkan.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 //go:build linux || freebsd 4 // +build linux freebsd 5 6 package vk 7 8 /* 9 #cgo linux freebsd LDFLAGS: -ldl 10 #cgo freebsd CFLAGS: -I/usr/local/include 11 #cgo CFLAGS: -Werror -Werror=return-type 12 13 #define VK_NO_PROTOTYPES 1 14 #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; 15 #include <vulkan/vulkan.h> 16 #define __USE_GNU 17 #include <dlfcn.h> 18 #include <stdlib.h> 19 20 static VkResult vkCreateInstance(PFN_vkCreateInstance f, VkInstanceCreateInfo pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { 21 return f(&pCreateInfo, pAllocator, pInstance); 22 } 23 24 static void vkDestroyInstance(PFN_vkDestroyInstance f, VkInstance instance, const VkAllocationCallbacks *pAllocator) { 25 f(instance, pAllocator); 26 } 27 28 static VkResult vkEnumeratePhysicalDevices(PFN_vkEnumeratePhysicalDevices f, VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) { 29 return f(instance, pPhysicalDeviceCount, pPhysicalDevices); 30 } 31 32 static void vkGetPhysicalDeviceQueueFamilyProperties(PFN_vkGetPhysicalDeviceQueueFamilyProperties f, VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties *pQueueFamilyProperties) { 33 f(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties); 34 } 35 36 static void vkGetPhysicalDeviceFormatProperties(PFN_vkGetPhysicalDeviceFormatProperties f, VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) { 37 f(physicalDevice, format, pFormatProperties); 38 } 39 40 static VkResult vkCreateDevice(PFN_vkCreateDevice f, VkPhysicalDevice physicalDevice, VkDeviceCreateInfo pCreateInfo, VkDeviceQueueCreateInfo qinf, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 41 pCreateInfo.pQueueCreateInfos = &qinf; 42 return f(physicalDevice, &pCreateInfo, pAllocator, pDevice); 43 } 44 45 static void vkDestroyDevice(PFN_vkDestroyDevice f, VkDevice device, const VkAllocationCallbacks *pAllocator) { 46 f(device, pAllocator); 47 } 48 49 static void vkGetDeviceQueue(PFN_vkGetDeviceQueue f, VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) { 50 f(device, queueFamilyIndex, queueIndex, pQueue); 51 } 52 53 static VkResult vkCreateImageView(PFN_vkCreateImageView f, VkDevice device, const VkImageViewCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImageView *pView) { 54 return f(device, pCreateInfo, pAllocator, pView); 55 } 56 57 static void vkDestroyImageView(PFN_vkDestroyImageView f, VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) { 58 f(device, imageView, pAllocator); 59 } 60 61 static VkResult vkCreateFramebuffer(PFN_vkCreateFramebuffer f, VkDevice device, VkFramebufferCreateInfo pCreateInfo, const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) { 62 return f(device, &pCreateInfo, pAllocator, pFramebuffer); 63 } 64 65 static void vkDestroyFramebuffer(PFN_vkDestroyFramebuffer f, VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) { 66 f(device, framebuffer, pAllocator); 67 } 68 69 static VkResult vkDeviceWaitIdle(PFN_vkDeviceWaitIdle f, VkDevice device) { 70 return f(device); 71 } 72 73 static VkResult vkQueueWaitIdle(PFN_vkQueueWaitIdle f, VkQueue queue) { 74 return f(queue); 75 } 76 77 static VkResult vkCreateSemaphore(PFN_vkCreateSemaphore f, VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) { 78 return f(device, pCreateInfo, pAllocator, pSemaphore); 79 } 80 81 static void vkDestroySemaphore(PFN_vkDestroySemaphore f, VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator) { 82 f(device, semaphore, pAllocator); 83 } 84 85 static VkResult vkCreateRenderPass(PFN_vkCreateRenderPass f, VkDevice device, VkRenderPassCreateInfo pCreateInfo, VkSubpassDescription subpassInf, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { 86 pCreateInfo.pSubpasses = &subpassInf; 87 return f(device, &pCreateInfo, pAllocator, pRenderPass); 88 } 89 90 static void vkDestroyRenderPass(PFN_vkDestroyRenderPass f, VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) { 91 f(device, renderPass, pAllocator); 92 } 93 94 static VkResult vkCreateCommandPool(PFN_vkCreateCommandPool f, VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) { 95 return f(device, pCreateInfo, pAllocator, pCommandPool); 96 } 97 98 static void vkDestroyCommandPool(PFN_vkDestroyCommandPool f, VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) { 99 f(device, commandPool, pAllocator); 100 } 101 102 static VkResult vkAllocateCommandBuffers(PFN_vkAllocateCommandBuffers f, VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers) { 103 return f(device, pAllocateInfo, pCommandBuffers); 104 } 105 106 static void vkFreeCommandBuffers(PFN_vkFreeCommandBuffers f, VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) { 107 f(device, commandPool, commandBufferCount, pCommandBuffers); 108 } 109 110 static VkResult vkBeginCommandBuffer(PFN_vkBeginCommandBuffer f, VkCommandBuffer commandBuffer, VkCommandBufferBeginInfo pBeginInfo) { 111 return f(commandBuffer, &pBeginInfo); 112 } 113 114 static VkResult vkEndCommandBuffer(PFN_vkEndCommandBuffer f, VkCommandBuffer commandBuffer) { 115 return f(commandBuffer); 116 } 117 118 static VkResult vkQueueSubmit(PFN_vkQueueSubmit f, VkQueue queue, VkSubmitInfo pSubmits, VkFence fence) { 119 return f(queue, 1, &pSubmits, fence); 120 } 121 122 static void vkCmdBeginRenderPass(PFN_vkCmdBeginRenderPass f, VkCommandBuffer commandBuffer, VkRenderPassBeginInfo pRenderPassBegin, VkSubpassContents contents) { 123 f(commandBuffer, &pRenderPassBegin, contents); 124 } 125 126 static void vkCmdEndRenderPass(PFN_vkCmdEndRenderPass f, VkCommandBuffer commandBuffer) { 127 f(commandBuffer); 128 } 129 130 static void vkCmdCopyBuffer(PFN_vkCmdCopyBuffer f, VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy *pRegions) { 131 f(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions); 132 } 133 134 static void vkCmdCopyBufferToImage(PFN_vkCmdCopyBufferToImage f, VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy *pRegions) { 135 f(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions); 136 } 137 138 static void vkCmdPipelineBarrier(PFN_vkCmdPipelineBarrier f, VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 139 f(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 140 } 141 142 static void vkCmdPushConstants(PFN_vkCmdPushConstants f, VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void *pValues) { 143 f(commandBuffer, layout, stageFlags, offset, size, pValues); 144 } 145 146 static void vkCmdBindPipeline(PFN_vkCmdBindPipeline f, VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) { 147 f(commandBuffer, pipelineBindPoint, pipeline); 148 } 149 150 static void vkCmdBindVertexBuffers(PFN_vkCmdBindVertexBuffers f, VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) { 151 f(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); 152 } 153 154 static void vkCmdSetViewport(PFN_vkCmdSetViewport f, VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) { 155 f(commandBuffer, firstViewport, viewportCount, pViewports); 156 } 157 158 static void vkCmdBindIndexBuffer(PFN_vkCmdBindIndexBuffer f, VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) { 159 f(commandBuffer, buffer, offset, indexType); 160 } 161 162 static void vkCmdDraw(PFN_vkCmdDraw f, VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) { 163 f(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance); 164 } 165 166 static void vkCmdDrawIndexed(PFN_vkCmdDrawIndexed f, VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) { 167 f(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); 168 } 169 170 static void vkCmdBindDescriptorSets(PFN_vkCmdBindDescriptorSets f, VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) { 171 f(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); 172 } 173 174 static void vkCmdCopyImageToBuffer(PFN_vkCmdCopyImageToBuffer f, VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) { 175 f(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); 176 } 177 178 static void vkCmdDispatch(PFN_vkCmdDispatch f, VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) { 179 f(commandBuffer, groupCountX, groupCountY, groupCountZ); 180 } 181 182 static VkResult vkCreateImage(PFN_vkCreateImage f, VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage) { 183 return f(device, pCreateInfo, pAllocator, pImage); 184 } 185 186 static void vkDestroyImage(PFN_vkDestroyImage f, VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) { 187 f(device, image, pAllocator); 188 } 189 190 static void vkGetImageMemoryRequirements(PFN_vkGetImageMemoryRequirements f, VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements) { 191 f(device, image, pMemoryRequirements); 192 } 193 194 static VkResult vkAllocateMemory(PFN_vkAllocateMemory f, VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) { 195 return f(device, pAllocateInfo, pAllocator, pMemory); 196 } 197 198 static VkResult vkBindImageMemory(PFN_vkBindImageMemory f, VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset) { 199 return f(device, image, memory, memoryOffset); 200 } 201 202 static void vkFreeMemory(PFN_vkFreeMemory f, VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator) { 203 f(device, memory, pAllocator); 204 } 205 206 static void vkGetPhysicalDeviceMemoryProperties(PFN_vkGetPhysicalDeviceMemoryProperties f, VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) { 207 f(physicalDevice, pMemoryProperties); 208 } 209 210 static VkResult vkCreateSampler(PFN_vkCreateSampler f,VkDevice device, const VkSamplerCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) { 211 return f(device, pCreateInfo, pAllocator, pSampler); 212 } 213 214 static void vkDestroySampler(PFN_vkDestroySampler f, VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) { 215 f(device, sampler, pAllocator); 216 } 217 218 static VkResult vkCreateBuffer(PFN_vkCreateBuffer f, VkDevice device, const VkBufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) { 219 return f(device, pCreateInfo, pAllocator, pBuffer); 220 } 221 222 static void vkDestroyBuffer(PFN_vkDestroyBuffer f, VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) { 223 f(device, buffer, pAllocator); 224 } 225 226 static void vkGetBufferMemoryRequirements(PFN_vkGetBufferMemoryRequirements f, VkDevice device, VkBuffer buffer, VkMemoryRequirements *pMemoryRequirements) { 227 f(device, buffer, pMemoryRequirements); 228 } 229 230 static VkResult vkBindBufferMemory(PFN_vkBindBufferMemory f, VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset) { 231 return f(device, buffer, memory, memoryOffset); 232 } 233 234 static VkResult vkCreateShaderModule(PFN_vkCreateShaderModule f, VkDevice device, VkShaderModuleCreateInfo pCreateInfo, const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule) { 235 return f(device, &pCreateInfo, pAllocator, pShaderModule); 236 } 237 238 static void vkDestroyShaderModule(PFN_vkDestroyShaderModule f, VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks *pAllocator) { 239 f(device, shaderModule, pAllocator); 240 } 241 242 static VkResult vkCreateGraphicsPipelines(PFN_vkCreateGraphicsPipelines f, VkDevice device, VkPipelineCache pipelineCache, VkGraphicsPipelineCreateInfo pCreateInfo, VkPipelineDynamicStateCreateInfo dynInf, VkPipelineColorBlendStateCreateInfo blendInf, VkPipelineVertexInputStateCreateInfo vertexInf, VkPipelineViewportStateCreateInfo viewportInf, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { 243 pCreateInfo.pDynamicState = &dynInf; 244 pCreateInfo.pViewportState = &viewportInf; 245 pCreateInfo.pColorBlendState = &blendInf; 246 pCreateInfo.pVertexInputState = &vertexInf; 247 return f(device, pipelineCache, 1, &pCreateInfo, pAllocator, pPipelines); 248 } 249 250 static void vkDestroyPipeline(PFN_vkDestroyPipeline f, VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) { 251 f(device, pipeline, pAllocator); 252 } 253 254 static VkResult vkCreatePipelineLayout(PFN_vkCreatePipelineLayout f, VkDevice device, VkPipelineLayoutCreateInfo pCreateInfo, const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout) { 255 return f(device, &pCreateInfo, pAllocator, pPipelineLayout); 256 } 257 258 static void vkDestroyPipelineLayout(PFN_vkDestroyPipelineLayout f, VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks *pAllocator) { 259 f(device, pipelineLayout, pAllocator); 260 } 261 262 static VkResult vkCreateDescriptorSetLayout(PFN_vkCreateDescriptorSetLayout f, VkDevice device, VkDescriptorSetLayoutCreateInfo pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) { 263 return f(device, &pCreateInfo, pAllocator, pSetLayout); 264 } 265 266 static void vkDestroyDescriptorSetLayout(PFN_vkDestroyDescriptorSetLayout f, VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks *pAllocator) { 267 f(device, descriptorSetLayout, pAllocator); 268 } 269 270 static VkResult vkMapMemory(PFN_vkMapMemory f, VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) { 271 return f(device, memory, offset, size, flags, ppData); 272 } 273 274 static void vkUnmapMemory(PFN_vkUnmapMemory f, VkDevice device, VkDeviceMemory memory) { 275 f(device, memory); 276 } 277 278 static VkResult vkResetCommandBuffer(PFN_vkResetCommandBuffer f, VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) { 279 return f(commandBuffer, flags); 280 } 281 282 static VkResult vkCreateDescriptorPool(PFN_vkCreateDescriptorPool f, VkDevice device, VkDescriptorPoolCreateInfo pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool) { 283 return f(device, &pCreateInfo, pAllocator, pDescriptorPool); 284 } 285 286 static void vkDestroyDescriptorPool(PFN_vkDestroyDescriptorPool f, VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) { 287 f(device, descriptorPool, pAllocator); 288 } 289 290 static VkResult vkAllocateDescriptorSets(PFN_vkAllocateDescriptorSets f, VkDevice device, VkDescriptorSetAllocateInfo pAllocateInfo, VkDescriptorSet *pDescriptorSets) { 291 return f(device, &pAllocateInfo, pDescriptorSets); 292 } 293 294 static VkResult vkFreeDescriptorSets(PFN_vkFreeDescriptorSets f, VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) { 295 return f(device, descriptorPool, descriptorSetCount, pDescriptorSets); 296 } 297 298 static void vkUpdateDescriptorSets(PFN_vkUpdateDescriptorSets f, VkDevice device, VkWriteDescriptorSet pDescriptorWrite, uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) { 299 f(device, 1, &pDescriptorWrite, descriptorCopyCount, pDescriptorCopies); 300 } 301 302 static VkResult vkResetDescriptorPool(PFN_vkResetDescriptorPool f, VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags) { 303 return f(device, descriptorPool, flags); 304 } 305 306 static void vkCmdBlitImage(PFN_vkCmdBlitImage f, VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter) { 307 f(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter); 308 } 309 310 static void vkCmdCopyImage(PFN_vkCmdCopyImage f, VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy *pRegions) { 311 f(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); 312 } 313 314 static VkResult vkCreateComputePipelines(PFN_vkCreateComputePipelines f, VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { 315 return f(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 316 } 317 318 static VkResult vkCreateFence(PFN_vkCreateFence f, VkDevice device, const VkFenceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkFence *pFence) { 319 return f(device, pCreateInfo, pAllocator, pFence); 320 } 321 322 static void vkDestroyFence(PFN_vkDestroyFence f, VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) { 323 f(device, fence, pAllocator); 324 } 325 326 static VkResult vkWaitForFences(PFN_vkWaitForFences f, VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, uint64_t timeout) { 327 return f(device, fenceCount, pFences, waitAll, timeout); 328 } 329 330 static VkResult vkResetFences(PFN_vkResetFences f, VkDevice device, uint32_t fenceCount, const VkFence *pFences) { 331 return f(device, fenceCount, pFences); 332 } 333 334 static void vkGetPhysicalDeviceProperties(PFN_vkGetPhysicalDeviceProperties f, VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) { 335 f(physicalDevice, pProperties); 336 } 337 338 static VkResult vkGetPhysicalDeviceSurfaceSupportKHR(PFN_vkGetPhysicalDeviceSurfaceSupportKHR f, VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported) { 339 return f(physicalDevice, queueFamilyIndex, surface, pSupported); 340 } 341 342 static void vkDestroySurfaceKHR(PFN_vkDestroySurfaceKHR f, VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) { 343 f(instance, surface, pAllocator); 344 } 345 346 static VkResult vkGetPhysicalDeviceSurfaceFormatsKHR(PFN_vkGetPhysicalDeviceSurfaceFormatsKHR f, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) { 347 return f(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats); 348 } 349 350 static VkResult vkGetPhysicalDeviceSurfacePresentModesKHR(PFN_vkGetPhysicalDeviceSurfacePresentModesKHR f, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) { 351 return f(physicalDevice, surface, pPresentModeCount, pPresentModes); 352 } 353 354 static VkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR(PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR f, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) { 355 return f(physicalDevice, surface, pSurfaceCapabilities); 356 } 357 358 static VkResult vkCreateSwapchainKHR(PFN_vkCreateSwapchainKHR f, VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) { 359 return f(device, pCreateInfo, pAllocator, pSwapchain); 360 } 361 362 static void vkDestroySwapchainKHR(PFN_vkDestroySwapchainKHR f, VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) { 363 f(device, swapchain, pAllocator); 364 } 365 366 static VkResult vkGetSwapchainImagesKHR(PFN_vkGetSwapchainImagesKHR f, VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) { 367 return f(device, swapchain, pSwapchainImageCount, pSwapchainImages); 368 } 369 370 // indexAndResult holds both an integer and a result returned by value, to 371 // avoid Go heap allocation of the integer with Vulkan's return style. 372 struct intAndResult { 373 uint32_t uint; 374 VkResult res; 375 }; 376 377 static struct intAndResult vkAcquireNextImageKHR(PFN_vkAcquireNextImageKHR f, VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence) { 378 struct intAndResult res; 379 res.res = f(device, swapchain, timeout, semaphore, fence, &res.uint); 380 return res; 381 } 382 383 static VkResult vkQueuePresentKHR(PFN_vkQueuePresentKHR f, VkQueue queue, const VkPresentInfoKHR pPresentInfo) { 384 return f(queue, &pPresentInfo); 385 } 386 */ 387 import "C" 388 import ( 389 "errors" 390 "fmt" 391 "image" 392 "math" 393 "reflect" 394 "runtime" 395 "sync" 396 "unsafe" 397 ) 398 399 type ( 400 AttachmentLoadOp = C.VkAttachmentLoadOp 401 AccessFlags = C.VkAccessFlags 402 BlendFactor = C.VkBlendFactor 403 Buffer = C.VkBuffer 404 BufferImageCopy = C.VkBufferImageCopy 405 BufferMemoryBarrier = C.VkBufferMemoryBarrier 406 BufferUsageFlags = C.VkBufferUsageFlags 407 CommandPool = C.VkCommandPool 408 CommandBuffer = C.VkCommandBuffer 409 DependencyFlags = C.VkDependencyFlags 410 DescriptorPool = C.VkDescriptorPool 411 DescriptorPoolSize = C.VkDescriptorPoolSize 412 DescriptorSet = C.VkDescriptorSet 413 DescriptorSetLayout = C.VkDescriptorSetLayout 414 DescriptorType = C.VkDescriptorType 415 Device = C.VkDevice 416 DeviceMemory = C.VkDeviceMemory 417 DeviceSize = C.VkDeviceSize 418 Fence = C.VkFence 419 Queue = C.VkQueue 420 IndexType = C.VkIndexType 421 Image = C.VkImage 422 ImageBlit = C.VkImageBlit 423 ImageCopy = C.VkImageCopy 424 ImageLayout = C.VkImageLayout 425 ImageMemoryBarrier = C.VkImageMemoryBarrier 426 ImageUsageFlags = C.VkImageUsageFlags 427 ImageView = C.VkImageView 428 Instance = C.VkInstance 429 Filter = C.VkFilter 430 Format = C.VkFormat 431 FormatFeatureFlags = C.VkFormatFeatureFlags 432 Framebuffer = C.VkFramebuffer 433 MemoryBarrier = C.VkMemoryBarrier 434 MemoryPropertyFlags = C.VkMemoryPropertyFlags 435 Pipeline = C.VkPipeline 436 PipelineBindPoint = C.VkPipelineBindPoint 437 PipelineLayout = C.VkPipelineLayout 438 PipelineStageFlags = C.VkPipelineStageFlags 439 PhysicalDevice = C.VkPhysicalDevice 440 PrimitiveTopology = C.VkPrimitiveTopology 441 PushConstantRange = C.VkPushConstantRange 442 QueueFamilyProperties = C.VkQueueFamilyProperties 443 QueueFlags = C.VkQueueFlags 444 RenderPass = C.VkRenderPass 445 Sampler = C.VkSampler 446 SamplerMipmapMode = C.VkSamplerMipmapMode 447 Semaphore = C.VkSemaphore 448 ShaderModule = C.VkShaderModule 449 ShaderStageFlags = C.VkShaderStageFlags 450 SubpassDependency = C.VkSubpassDependency 451 Viewport = C.VkViewport 452 WriteDescriptorSet = C.VkWriteDescriptorSet 453 454 Surface = C.VkSurfaceKHR 455 SurfaceCapabilities = C.VkSurfaceCapabilitiesKHR 456 457 Swapchain = C.VkSwapchainKHR 458 ) 459 460 type VertexInputBindingDescription struct { 461 Binding int 462 Stride int 463 } 464 465 type VertexInputAttributeDescription struct { 466 Location int 467 Binding int 468 Format Format 469 Offset int 470 } 471 472 type DescriptorSetLayoutBinding struct { 473 Binding int 474 DescriptorType DescriptorType 475 StageFlags ShaderStageFlags 476 } 477 478 type Error C.VkResult 479 480 const ( 481 FORMAT_R8G8B8A8_UNORM Format = C.VK_FORMAT_R8G8B8A8_UNORM 482 FORMAT_B8G8R8A8_SRGB Format = C.VK_FORMAT_B8G8R8A8_SRGB 483 FORMAT_R8G8B8A8_SRGB Format = C.VK_FORMAT_R8G8B8A8_SRGB 484 FORMAT_R16_SFLOAT Format = C.VK_FORMAT_R16_SFLOAT 485 FORMAT_R32_SFLOAT Format = C.VK_FORMAT_R32_SFLOAT 486 FORMAT_R32G32_SFLOAT Format = C.VK_FORMAT_R32G32_SFLOAT 487 FORMAT_R32G32B32_SFLOAT Format = C.VK_FORMAT_R32G32B32_SFLOAT 488 FORMAT_R32G32B32A32_SFLOAT Format = C.VK_FORMAT_R32G32B32A32_SFLOAT 489 490 FORMAT_FEATURE_COLOR_ATTACHMENT_BIT FormatFeatureFlags = C.VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT 491 FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT FormatFeatureFlags = C.VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT 492 FORMAT_FEATURE_SAMPLED_IMAGE_BIT FormatFeatureFlags = C.VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT 493 FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT FormatFeatureFlags = C.VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT 494 495 IMAGE_USAGE_SAMPLED_BIT ImageUsageFlags = C.VK_IMAGE_USAGE_SAMPLED_BIT 496 IMAGE_USAGE_COLOR_ATTACHMENT_BIT ImageUsageFlags = C.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT 497 IMAGE_USAGE_STORAGE_BIT ImageUsageFlags = C.VK_IMAGE_USAGE_STORAGE_BIT 498 IMAGE_USAGE_TRANSFER_DST_BIT ImageUsageFlags = C.VK_IMAGE_USAGE_TRANSFER_DST_BIT 499 IMAGE_USAGE_TRANSFER_SRC_BIT ImageUsageFlags = C.VK_IMAGE_USAGE_TRANSFER_SRC_BIT 500 501 FILTER_NEAREST Filter = C.VK_FILTER_NEAREST 502 FILTER_LINEAR Filter = C.VK_FILTER_LINEAR 503 504 ATTACHMENT_LOAD_OP_CLEAR AttachmentLoadOp = C.VK_ATTACHMENT_LOAD_OP_CLEAR 505 ATTACHMENT_LOAD_OP_DONT_CARE AttachmentLoadOp = C.VK_ATTACHMENT_LOAD_OP_DONT_CARE 506 ATTACHMENT_LOAD_OP_LOAD AttachmentLoadOp = C.VK_ATTACHMENT_LOAD_OP_LOAD 507 508 IMAGE_LAYOUT_UNDEFINED ImageLayout = C.VK_IMAGE_LAYOUT_UNDEFINED 509 IMAGE_LAYOUT_PRESENT_SRC_KHR ImageLayout = C.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR 510 IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ImageLayout = C.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 511 IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ImageLayout = C.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 512 IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ImageLayout = C.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 513 IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ImageLayout = C.VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL 514 IMAGE_LAYOUT_GENERAL ImageLayout = C.VK_IMAGE_LAYOUT_GENERAL 515 516 BUFFER_USAGE_TRANSFER_DST_BIT BufferUsageFlags = C.VK_BUFFER_USAGE_TRANSFER_DST_BIT 517 BUFFER_USAGE_TRANSFER_SRC_BIT BufferUsageFlags = C.VK_BUFFER_USAGE_TRANSFER_SRC_BIT 518 BUFFER_USAGE_UNIFORM_BUFFER_BIT BufferUsageFlags = C.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT 519 BUFFER_USAGE_STORAGE_BUFFER_BIT BufferUsageFlags = C.VK_BUFFER_USAGE_STORAGE_BUFFER_BIT 520 BUFFER_USAGE_INDEX_BUFFER_BIT BufferUsageFlags = C.VK_BUFFER_USAGE_INDEX_BUFFER_BIT 521 BUFFER_USAGE_VERTEX_BUFFER_BIT BufferUsageFlags = C.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT 522 523 ERROR_OUT_OF_DATE_KHR = Error(C.VK_ERROR_OUT_OF_DATE_KHR) 524 ERROR_SURFACE_LOST_KHR = Error(C.VK_ERROR_SURFACE_LOST_KHR) 525 ERROR_DEVICE_LOST = Error(C.VK_ERROR_DEVICE_LOST) 526 SUBOPTIMAL_KHR = Error(C.VK_SUBOPTIMAL_KHR) 527 528 FENCE_CREATE_SIGNALED_BIT = 0x00000001 529 530 BLEND_FACTOR_ZERO BlendFactor = C.VK_BLEND_FACTOR_ZERO 531 BLEND_FACTOR_ONE BlendFactor = C.VK_BLEND_FACTOR_ONE 532 BLEND_FACTOR_ONE_MINUS_SRC_ALPHA BlendFactor = C.VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA 533 BLEND_FACTOR_DST_COLOR BlendFactor = C.VK_BLEND_FACTOR_DST_COLOR 534 535 PRIMITIVE_TOPOLOGY_TRIANGLE_LIST PrimitiveTopology = C.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST 536 PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP PrimitiveTopology = C.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP 537 538 SHADER_STAGE_VERTEX_BIT ShaderStageFlags = C.VK_SHADER_STAGE_VERTEX_BIT 539 SHADER_STAGE_FRAGMENT_BIT ShaderStageFlags = C.VK_SHADER_STAGE_FRAGMENT_BIT 540 SHADER_STAGE_COMPUTE_BIT ShaderStageFlags = C.VK_SHADER_STAGE_COMPUTE_BIT 541 542 DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER DescriptorType = C.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER 543 DESCRIPTOR_TYPE_UNIFORM_BUFFER DescriptorType = C.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER 544 DESCRIPTOR_TYPE_STORAGE_BUFFER DescriptorType = C.VK_DESCRIPTOR_TYPE_STORAGE_BUFFER 545 DESCRIPTOR_TYPE_STORAGE_IMAGE DescriptorType = C.VK_DESCRIPTOR_TYPE_STORAGE_IMAGE 546 547 MEMORY_PROPERTY_DEVICE_LOCAL_BIT MemoryPropertyFlags = C.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 548 MEMORY_PROPERTY_HOST_VISIBLE_BIT MemoryPropertyFlags = C.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 549 MEMORY_PROPERTY_HOST_COHERENT_BIT MemoryPropertyFlags = C.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT 550 551 DEPENDENCY_BY_REGION_BIT DependencyFlags = C.VK_DEPENDENCY_BY_REGION_BIT 552 553 PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT PipelineStageFlags = C.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 554 PIPELINE_STAGE_TRANSFER_BIT PipelineStageFlags = C.VK_PIPELINE_STAGE_TRANSFER_BIT 555 PIPELINE_STAGE_FRAGMENT_SHADER_BIT PipelineStageFlags = C.VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 556 PIPELINE_STAGE_COMPUTE_SHADER_BIT PipelineStageFlags = C.VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT 557 PIPELINE_STAGE_TOP_OF_PIPE_BIT PipelineStageFlags = C.VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT 558 PIPELINE_STAGE_HOST_BIT PipelineStageFlags = C.VK_PIPELINE_STAGE_HOST_BIT 559 PIPELINE_STAGE_VERTEX_INPUT_BIT PipelineStageFlags = C.VK_PIPELINE_STAGE_VERTEX_INPUT_BIT 560 PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT PipelineStageFlags = C.VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT 561 562 ACCESS_MEMORY_READ_BIT AccessFlags = C.VK_ACCESS_MEMORY_READ_BIT 563 ACCESS_MEMORY_WRITE_BIT AccessFlags = C.VK_ACCESS_MEMORY_WRITE_BIT 564 ACCESS_TRANSFER_READ_BIT AccessFlags = C.VK_ACCESS_TRANSFER_READ_BIT 565 ACCESS_TRANSFER_WRITE_BIT AccessFlags = C.VK_ACCESS_TRANSFER_WRITE_BIT 566 ACCESS_SHADER_READ_BIT AccessFlags = C.VK_ACCESS_SHADER_READ_BIT 567 ACCESS_SHADER_WRITE_BIT AccessFlags = C.VK_ACCESS_SHADER_WRITE_BIT 568 ACCESS_COLOR_ATTACHMENT_READ_BIT AccessFlags = C.VK_ACCESS_COLOR_ATTACHMENT_READ_BIT 569 ACCESS_COLOR_ATTACHMENT_WRITE_BIT AccessFlags = C.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT 570 ACCESS_HOST_READ_BIT AccessFlags = C.VK_ACCESS_HOST_READ_BIT 571 ACCESS_HOST_WRITE_BIT AccessFlags = C.VK_ACCESS_HOST_WRITE_BIT 572 ACCESS_VERTEX_ATTRIBUTE_READ_BIT AccessFlags = C.VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT 573 ACCESS_INDEX_READ_BIT AccessFlags = C.VK_ACCESS_INDEX_READ_BIT 574 575 PIPELINE_BIND_POINT_COMPUTE PipelineBindPoint = C.VK_PIPELINE_BIND_POINT_COMPUTE 576 PIPELINE_BIND_POINT_GRAPHICS PipelineBindPoint = C.VK_PIPELINE_BIND_POINT_GRAPHICS 577 578 INDEX_TYPE_UINT16 IndexType = C.VK_INDEX_TYPE_UINT16 579 INDEX_TYPE_UINT32 IndexType = C.VK_INDEX_TYPE_UINT32 580 581 QUEUE_GRAPHICS_BIT QueueFlags = C.VK_QUEUE_GRAPHICS_BIT 582 QUEUE_COMPUTE_BIT QueueFlags = C.VK_QUEUE_COMPUTE_BIT 583 584 SAMPLER_MIPMAP_MODE_NEAREST SamplerMipmapMode = C.VK_SAMPLER_MIPMAP_MODE_NEAREST 585 SAMPLER_MIPMAP_MODE_LINEAR SamplerMipmapMode = C.VK_SAMPLER_MIPMAP_MODE_LINEAR 586 587 REMAINING_MIP_LEVELS = -1 588 ) 589 590 var ( 591 once sync.Once 592 loadErr error 593 594 loadFuncs []func(dlopen func(name string) *[0]byte) 595 ) 596 597 var funcs struct { 598 vkCreateInstance C.PFN_vkCreateInstance 599 vkDestroyInstance C.PFN_vkDestroyInstance 600 vkEnumeratePhysicalDevices C.PFN_vkEnumeratePhysicalDevices 601 vkGetPhysicalDeviceQueueFamilyProperties C.PFN_vkGetPhysicalDeviceQueueFamilyProperties 602 vkGetPhysicalDeviceFormatProperties C.PFN_vkGetPhysicalDeviceFormatProperties 603 vkCreateDevice C.PFN_vkCreateDevice 604 vkDestroyDevice C.PFN_vkDestroyDevice 605 vkGetDeviceQueue C.PFN_vkGetDeviceQueue 606 vkCreateImageView C.PFN_vkCreateImageView 607 vkDestroyImageView C.PFN_vkDestroyImageView 608 vkCreateFramebuffer C.PFN_vkCreateFramebuffer 609 vkDestroyFramebuffer C.PFN_vkDestroyFramebuffer 610 vkDeviceWaitIdle C.PFN_vkDeviceWaitIdle 611 vkQueueWaitIdle C.PFN_vkQueueWaitIdle 612 vkCreateSemaphore C.PFN_vkCreateSemaphore 613 vkDestroySemaphore C.PFN_vkDestroySemaphore 614 vkCreateRenderPass C.PFN_vkCreateRenderPass 615 vkDestroyRenderPass C.PFN_vkDestroyRenderPass 616 vkCreateCommandPool C.PFN_vkCreateCommandPool 617 vkDestroyCommandPool C.PFN_vkDestroyCommandPool 618 vkAllocateCommandBuffers C.PFN_vkAllocateCommandBuffers 619 vkFreeCommandBuffers C.PFN_vkFreeCommandBuffers 620 vkBeginCommandBuffer C.PFN_vkBeginCommandBuffer 621 vkEndCommandBuffer C.PFN_vkEndCommandBuffer 622 vkQueueSubmit C.PFN_vkQueueSubmit 623 vkCmdBeginRenderPass C.PFN_vkCmdBeginRenderPass 624 vkCmdEndRenderPass C.PFN_vkCmdEndRenderPass 625 vkCmdCopyBuffer C.PFN_vkCmdCopyBuffer 626 vkCmdCopyBufferToImage C.PFN_vkCmdCopyBufferToImage 627 vkCmdPipelineBarrier C.PFN_vkCmdPipelineBarrier 628 vkCmdPushConstants C.PFN_vkCmdPushConstants 629 vkCmdBindPipeline C.PFN_vkCmdBindPipeline 630 vkCmdBindVertexBuffers C.PFN_vkCmdBindVertexBuffers 631 vkCmdSetViewport C.PFN_vkCmdSetViewport 632 vkCmdBindIndexBuffer C.PFN_vkCmdBindIndexBuffer 633 vkCmdDraw C.PFN_vkCmdDraw 634 vkCmdDrawIndexed C.PFN_vkCmdDrawIndexed 635 vkCmdBindDescriptorSets C.PFN_vkCmdBindDescriptorSets 636 vkCmdCopyImageToBuffer C.PFN_vkCmdCopyImageToBuffer 637 vkCmdDispatch C.PFN_vkCmdDispatch 638 vkCreateImage C.PFN_vkCreateImage 639 vkDestroyImage C.PFN_vkDestroyImage 640 vkGetImageMemoryRequirements C.PFN_vkGetImageMemoryRequirements 641 vkAllocateMemory C.PFN_vkAllocateMemory 642 vkBindImageMemory C.PFN_vkBindImageMemory 643 vkFreeMemory C.PFN_vkFreeMemory 644 vkGetPhysicalDeviceMemoryProperties C.PFN_vkGetPhysicalDeviceMemoryProperties 645 vkCreateSampler C.PFN_vkCreateSampler 646 vkDestroySampler C.PFN_vkDestroySampler 647 vkCreateBuffer C.PFN_vkCreateBuffer 648 vkDestroyBuffer C.PFN_vkDestroyBuffer 649 vkGetBufferMemoryRequirements C.PFN_vkGetBufferMemoryRequirements 650 vkBindBufferMemory C.PFN_vkBindBufferMemory 651 vkCreateShaderModule C.PFN_vkCreateShaderModule 652 vkDestroyShaderModule C.PFN_vkDestroyShaderModule 653 vkCreateGraphicsPipelines C.PFN_vkCreateGraphicsPipelines 654 vkDestroyPipeline C.PFN_vkDestroyPipeline 655 vkCreatePipelineLayout C.PFN_vkCreatePipelineLayout 656 vkDestroyPipelineLayout C.PFN_vkDestroyPipelineLayout 657 vkCreateDescriptorSetLayout C.PFN_vkCreateDescriptorSetLayout 658 vkDestroyDescriptorSetLayout C.PFN_vkDestroyDescriptorSetLayout 659 vkMapMemory C.PFN_vkMapMemory 660 vkUnmapMemory C.PFN_vkUnmapMemory 661 vkResetCommandBuffer C.PFN_vkResetCommandBuffer 662 vkCreateDescriptorPool C.PFN_vkCreateDescriptorPool 663 vkDestroyDescriptorPool C.PFN_vkDestroyDescriptorPool 664 vkAllocateDescriptorSets C.PFN_vkAllocateDescriptorSets 665 vkFreeDescriptorSets C.PFN_vkFreeDescriptorSets 666 vkUpdateDescriptorSets C.PFN_vkUpdateDescriptorSets 667 vkResetDescriptorPool C.PFN_vkResetDescriptorPool 668 vkCmdBlitImage C.PFN_vkCmdBlitImage 669 vkCmdCopyImage C.PFN_vkCmdCopyImage 670 vkCreateComputePipelines C.PFN_vkCreateComputePipelines 671 vkCreateFence C.PFN_vkCreateFence 672 vkDestroyFence C.PFN_vkDestroyFence 673 vkWaitForFences C.PFN_vkWaitForFences 674 vkResetFences C.PFN_vkResetFences 675 vkGetPhysicalDeviceProperties C.PFN_vkGetPhysicalDeviceProperties 676 677 vkGetPhysicalDeviceSurfaceSupportKHR C.PFN_vkGetPhysicalDeviceSurfaceSupportKHR 678 vkDestroySurfaceKHR C.PFN_vkDestroySurfaceKHR 679 vkGetPhysicalDeviceSurfaceFormatsKHR C.PFN_vkGetPhysicalDeviceSurfaceFormatsKHR 680 vkGetPhysicalDeviceSurfacePresentModesKHR C.PFN_vkGetPhysicalDeviceSurfacePresentModesKHR 681 vkGetPhysicalDeviceSurfaceCapabilitiesKHR C.PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR 682 683 vkCreateSwapchainKHR C.PFN_vkCreateSwapchainKHR 684 vkDestroySwapchainKHR C.PFN_vkDestroySwapchainKHR 685 vkGetSwapchainImagesKHR C.PFN_vkGetSwapchainImagesKHR 686 vkAcquireNextImageKHR C.PFN_vkAcquireNextImageKHR 687 vkQueuePresentKHR C.PFN_vkQueuePresentKHR 688 } 689 690 var ( 691 nilSurface C.VkSurfaceKHR 692 nilSwapchain C.VkSwapchainKHR 693 nilSemaphore C.VkSemaphore 694 nilImageView C.VkImageView 695 nilRenderPass C.VkRenderPass 696 nilFramebuffer C.VkFramebuffer 697 nilCommandPool C.VkCommandPool 698 nilImage C.VkImage 699 nilDeviceMemory C.VkDeviceMemory 700 nilSampler C.VkSampler 701 nilBuffer C.VkBuffer 702 nilShaderModule C.VkShaderModule 703 nilPipeline C.VkPipeline 704 nilPipelineCache C.VkPipelineCache 705 nilPipelineLayout C.VkPipelineLayout 706 nilDescriptorSetLayout C.VkDescriptorSetLayout 707 nilDescriptorPool C.VkDescriptorPool 708 nilDescriptorSet C.VkDescriptorSet 709 nilFence C.VkFence 710 ) 711 712 func vkInit() error { 713 once.Do(func() { 714 var libName string 715 switch { 716 case runtime.GOOS == "android": 717 libName = "libvulkan.so" 718 default: 719 libName = "libvulkan.so.1" 720 } 721 lib := dlopen(libName) 722 if lib == nil { 723 loadErr = fmt.Errorf("vulkan: %s", C.GoString(C.dlerror())) 724 return 725 } 726 dlopen := func(name string) *[0]byte { 727 return (*[0]byte)(dlsym(lib, name)) 728 } 729 must := func(name string) *[0]byte { 730 ptr := dlopen(name) 731 if ptr != nil { 732 return ptr 733 } 734 if loadErr == nil { 735 loadErr = fmt.Errorf("vulkan: function %q not found: %s", name, C.GoString(C.dlerror())) 736 } 737 return nil 738 } 739 funcs.vkCreateInstance = must("vkCreateInstance") 740 funcs.vkDestroyInstance = must("vkDestroyInstance") 741 funcs.vkEnumeratePhysicalDevices = must("vkEnumeratePhysicalDevices") 742 funcs.vkGetPhysicalDeviceQueueFamilyProperties = must("vkGetPhysicalDeviceQueueFamilyProperties") 743 funcs.vkGetPhysicalDeviceFormatProperties = must("vkGetPhysicalDeviceFormatProperties") 744 funcs.vkCreateDevice = must("vkCreateDevice") 745 funcs.vkDestroyDevice = must("vkDestroyDevice") 746 funcs.vkGetDeviceQueue = must("vkGetDeviceQueue") 747 funcs.vkCreateImageView = must("vkCreateImageView") 748 funcs.vkDestroyImageView = must("vkDestroyImageView") 749 funcs.vkCreateFramebuffer = must("vkCreateFramebuffer") 750 funcs.vkDestroyFramebuffer = must("vkDestroyFramebuffer") 751 funcs.vkDeviceWaitIdle = must("vkDeviceWaitIdle") 752 funcs.vkQueueWaitIdle = must("vkQueueWaitIdle") 753 funcs.vkCreateSemaphore = must("vkCreateSemaphore") 754 funcs.vkDestroySemaphore = must("vkDestroySemaphore") 755 funcs.vkCreateRenderPass = must("vkCreateRenderPass") 756 funcs.vkDestroyRenderPass = must("vkDestroyRenderPass") 757 funcs.vkCreateCommandPool = must("vkCreateCommandPool") 758 funcs.vkDestroyCommandPool = must("vkDestroyCommandPool") 759 funcs.vkAllocateCommandBuffers = must("vkAllocateCommandBuffers") 760 funcs.vkFreeCommandBuffers = must("vkFreeCommandBuffers") 761 funcs.vkBeginCommandBuffer = must("vkBeginCommandBuffer") 762 funcs.vkEndCommandBuffer = must("vkEndCommandBuffer") 763 funcs.vkQueueSubmit = must("vkQueueSubmit") 764 funcs.vkCmdBeginRenderPass = must("vkCmdBeginRenderPass") 765 funcs.vkCmdEndRenderPass = must("vkCmdEndRenderPass") 766 funcs.vkCmdCopyBuffer = must("vkCmdCopyBuffer") 767 funcs.vkCmdCopyBufferToImage = must("vkCmdCopyBufferToImage") 768 funcs.vkCmdPipelineBarrier = must("vkCmdPipelineBarrier") 769 funcs.vkCmdPushConstants = must("vkCmdPushConstants") 770 funcs.vkCmdBindPipeline = must("vkCmdBindPipeline") 771 funcs.vkCmdBindVertexBuffers = must("vkCmdBindVertexBuffers") 772 funcs.vkCmdSetViewport = must("vkCmdSetViewport") 773 funcs.vkCmdBindIndexBuffer = must("vkCmdBindIndexBuffer") 774 funcs.vkCmdDraw = must("vkCmdDraw") 775 funcs.vkCmdDrawIndexed = must("vkCmdDrawIndexed") 776 funcs.vkCmdBindDescriptorSets = must("vkCmdBindDescriptorSets") 777 funcs.vkCmdCopyImageToBuffer = must("vkCmdCopyImageToBuffer") 778 funcs.vkCmdDispatch = must("vkCmdDispatch") 779 funcs.vkCreateImage = must("vkCreateImage") 780 funcs.vkDestroyImage = must("vkDestroyImage") 781 funcs.vkGetImageMemoryRequirements = must("vkGetImageMemoryRequirements") 782 funcs.vkAllocateMemory = must("vkAllocateMemory") 783 funcs.vkBindImageMemory = must("vkBindImageMemory") 784 funcs.vkFreeMemory = must("vkFreeMemory") 785 funcs.vkGetPhysicalDeviceMemoryProperties = must("vkGetPhysicalDeviceMemoryProperties") 786 funcs.vkCreateSampler = must("vkCreateSampler") 787 funcs.vkDestroySampler = must("vkDestroySampler") 788 funcs.vkCreateBuffer = must("vkCreateBuffer") 789 funcs.vkDestroyBuffer = must("vkDestroyBuffer") 790 funcs.vkGetBufferMemoryRequirements = must("vkGetBufferMemoryRequirements") 791 funcs.vkBindBufferMemory = must("vkBindBufferMemory") 792 funcs.vkCreateShaderModule = must("vkCreateShaderModule") 793 funcs.vkDestroyShaderModule = must("vkDestroyShaderModule") 794 funcs.vkCreateGraphicsPipelines = must("vkCreateGraphicsPipelines") 795 funcs.vkDestroyPipeline = must("vkDestroyPipeline") 796 funcs.vkCreatePipelineLayout = must("vkCreatePipelineLayout") 797 funcs.vkDestroyPipelineLayout = must("vkDestroyPipelineLayout") 798 funcs.vkCreateDescriptorSetLayout = must("vkCreateDescriptorSetLayout") 799 funcs.vkDestroyDescriptorSetLayout = must("vkDestroyDescriptorSetLayout") 800 funcs.vkMapMemory = must("vkMapMemory") 801 funcs.vkUnmapMemory = must("vkUnmapMemory") 802 funcs.vkResetCommandBuffer = must("vkResetCommandBuffer") 803 funcs.vkCreateDescriptorPool = must("vkCreateDescriptorPool") 804 funcs.vkDestroyDescriptorPool = must("vkDestroyDescriptorPool") 805 funcs.vkAllocateDescriptorSets = must("vkAllocateDescriptorSets") 806 funcs.vkFreeDescriptorSets = must("vkFreeDescriptorSets") 807 funcs.vkUpdateDescriptorSets = must("vkUpdateDescriptorSets") 808 funcs.vkResetDescriptorPool = must("vkResetDescriptorPool") 809 funcs.vkCmdBlitImage = must("vkCmdBlitImage") 810 funcs.vkCmdCopyImage = must("vkCmdCopyImage") 811 funcs.vkCreateComputePipelines = must("vkCreateComputePipelines") 812 funcs.vkCreateFence = must("vkCreateFence") 813 funcs.vkDestroyFence = must("vkDestroyFence") 814 funcs.vkWaitForFences = must("vkWaitForFences") 815 funcs.vkResetFences = must("vkResetFences") 816 funcs.vkGetPhysicalDeviceProperties = must("vkGetPhysicalDeviceProperties") 817 818 funcs.vkGetPhysicalDeviceSurfaceSupportKHR = dlopen("vkGetPhysicalDeviceSurfaceSupportKHR") 819 funcs.vkDestroySurfaceKHR = dlopen("vkDestroySurfaceKHR") 820 funcs.vkGetPhysicalDeviceSurfaceFormatsKHR = dlopen("vkGetPhysicalDeviceSurfaceFormatsKHR") 821 funcs.vkGetPhysicalDeviceSurfacePresentModesKHR = dlopen("vkGetPhysicalDeviceSurfacePresentModesKHR") 822 funcs.vkGetPhysicalDeviceSurfaceCapabilitiesKHR = dlopen("vkGetPhysicalDeviceSurfaceCapabilitiesKHR") 823 824 funcs.vkCreateSwapchainKHR = dlopen("vkCreateSwapchainKHR") 825 funcs.vkDestroySwapchainKHR = dlopen("vkDestroySwapchainKHR") 826 funcs.vkGetSwapchainImagesKHR = dlopen("vkGetSwapchainImagesKHR") 827 funcs.vkAcquireNextImageKHR = dlopen("vkAcquireNextImageKHR") 828 funcs.vkQueuePresentKHR = dlopen("vkQueuePresentKHR") 829 830 for _, f := range loadFuncs { 831 f(dlopen) 832 } 833 }) 834 return loadErr 835 } 836 837 func CreateInstance(exts ...string) (Instance, error) { 838 if err := vkInit(); err != nil { 839 return nil, err 840 } 841 // VK_MAKE_API_VERSION macro. 842 makeVer := func(variant, major, minor, patch int) C.uint32_t { 843 return ((((C.uint32_t)(variant)) << 29) | (((C.uint32_t)(major)) << 22) | (((C.uint32_t)(minor)) << 12) | ((C.uint32_t)(patch))) 844 } 845 appInf := C.VkApplicationInfo{ 846 sType: C.VK_STRUCTURE_TYPE_APPLICATION_INFO, 847 apiVersion: makeVer(0, 1, 0, 0), 848 } 849 inf := C.VkInstanceCreateInfo{ 850 sType: C.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 851 // pApplicationInfo may be omitted according to the spec, but the Android 852 // emulator crashes without it. 853 pApplicationInfo: &appInf, 854 } 855 if len(exts) > 0 { 856 cexts := mallocCStringArr(exts) 857 defer freeCStringArr(cexts) 858 inf.enabledExtensionCount = C.uint32_t(len(exts)) 859 inf.ppEnabledExtensionNames = &cexts[0] 860 } 861 var inst Instance 862 if err := vkErr(C.vkCreateInstance(funcs.vkCreateInstance, inf, nil, &inst)); err != nil { 863 return nil, fmt.Errorf("vulkan: vkCreateInstance: %w", err) 864 } 865 return inst, nil 866 } 867 868 func mallocCStringArr(s []string) []*C.char { 869 carr := make([]*C.char, len(s)) 870 for i, ext := range s { 871 carr[i] = C.CString(ext) 872 } 873 return carr 874 } 875 876 func freeCStringArr(s []*C.char) { 877 for i := range s { 878 C.free(unsafe.Pointer(s[i])) 879 s[i] = nil 880 } 881 } 882 883 func DestroyInstance(inst Instance) { 884 C.vkDestroyInstance(funcs.vkDestroyInstance, inst, nil) 885 } 886 887 func GetPhysicalDeviceQueueFamilyProperties(pd PhysicalDevice) []QueueFamilyProperties { 888 var count C.uint32_t 889 C.vkGetPhysicalDeviceQueueFamilyProperties(funcs.vkGetPhysicalDeviceQueueFamilyProperties, pd, &count, nil) 890 if count == 0 { 891 return nil 892 } 893 queues := make([]C.VkQueueFamilyProperties, count) 894 C.vkGetPhysicalDeviceQueueFamilyProperties(funcs.vkGetPhysicalDeviceQueueFamilyProperties, pd, &count, &queues[0]) 895 return queues 896 } 897 898 func EnumeratePhysicalDevices(inst Instance) ([]PhysicalDevice, error) { 899 var count C.uint32_t 900 if err := vkErr(C.vkEnumeratePhysicalDevices(funcs.vkEnumeratePhysicalDevices, inst, &count, nil)); err != nil { 901 return nil, fmt.Errorf("vulkan: vkEnumeratePhysicalDevices: %w", err) 902 } 903 if count == 0 { 904 return nil, nil 905 } 906 devs := make([]C.VkPhysicalDevice, count) 907 if err := vkErr(C.vkEnumeratePhysicalDevices(funcs.vkEnumeratePhysicalDevices, inst, &count, &devs[0])); err != nil { 908 return nil, fmt.Errorf("vulkan: vkEnumeratePhysicalDevices: %w", err) 909 } 910 return devs, nil 911 } 912 913 func ChoosePhysicalDevice(inst Instance, surf Surface) (PhysicalDevice, int, error) { 914 devs, err := EnumeratePhysicalDevices(inst) 915 if err != nil { 916 return nil, 0, err 917 } 918 for _, pd := range devs { 919 var props C.VkPhysicalDeviceProperties 920 C.vkGetPhysicalDeviceProperties(funcs.vkGetPhysicalDeviceProperties, pd, &props) 921 // The lavapipe software implementation doesn't work well rendering to a surface. 922 // See https://gitlab.freedesktop.org/mesa/mesa/-/issues/5473. 923 if surf != 0 && props.deviceType == C.VK_PHYSICAL_DEVICE_TYPE_CPU { 924 continue 925 } 926 const caps = C.VK_QUEUE_GRAPHICS_BIT | C.VK_QUEUE_COMPUTE_BIT 927 queueIdx, ok, err := chooseQueue(pd, surf, caps) 928 if err != nil { 929 return nil, 0, err 930 } 931 if !ok { 932 continue 933 } 934 if surf != nilSurface { 935 _, fmtFound, err := chooseFormat(pd, surf) 936 if err != nil { 937 return nil, 0, err 938 } 939 _, modFound, err := choosePresentMode(pd, surf) 940 if err != nil { 941 return nil, 0, err 942 } 943 if !fmtFound || !modFound { 944 continue 945 } 946 } 947 return pd, queueIdx, nil 948 } 949 return nil, 0, errors.New("vulkan: no suitable device found") 950 } 951 952 func CreateDeviceAndQueue(pd C.VkPhysicalDevice, queueIdx int, exts ...string) (Device, error) { 953 priority := C.float(1.0) 954 qinf := C.VkDeviceQueueCreateInfo{ 955 sType: C.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 956 queueCount: 1, 957 queueFamilyIndex: C.uint32_t(queueIdx), 958 pQueuePriorities: &priority, 959 } 960 inf := C.VkDeviceCreateInfo{ 961 sType: C.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 962 queueCreateInfoCount: 1, 963 enabledExtensionCount: C.uint32_t(len(exts)), 964 } 965 if len(exts) > 0 { 966 cexts := mallocCStringArr(exts) 967 defer freeCStringArr(cexts) 968 inf.ppEnabledExtensionNames = &cexts[0] 969 } 970 var dev Device 971 if err := vkErr(C.vkCreateDevice(funcs.vkCreateDevice, pd, inf, qinf, nil, &dev)); err != nil { 972 return nil, fmt.Errorf("vulkan: vkCreateDevice: %w", err) 973 } 974 return dev, nil 975 } 976 977 func GetDeviceQueue(d Device, queueFamily, queueIndex int) Queue { 978 var queue Queue 979 C.vkGetDeviceQueue(funcs.vkGetDeviceQueue, d, C.uint32_t(queueFamily), C.uint32_t(queueIndex), &queue) 980 return queue 981 } 982 983 func GetPhysicalDeviceSurfaceCapabilities(pd PhysicalDevice, surf Surface) (SurfaceCapabilities, error) { 984 var caps C.VkSurfaceCapabilitiesKHR 985 err := vkErr(C.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(funcs.vkGetPhysicalDeviceSurfaceCapabilitiesKHR, pd, surf, &caps)) 986 if err != nil { 987 return SurfaceCapabilities{}, fmt.Errorf("vulkan: vkGetPhysicalDeviceSurfaceCapabilitiesKHR: %w", err) 988 } 989 return caps, nil 990 } 991 992 func CreateSwapchain(pd PhysicalDevice, d Device, surf Surface, width, height int, old Swapchain) (Swapchain, []Image, Format, error) { 993 caps, err := GetPhysicalDeviceSurfaceCapabilities(pd, surf) 994 if err != nil { 995 return nilSwapchain, nil, 0, err 996 } 997 mode, modeOK, err := choosePresentMode(pd, surf) 998 if err != nil { 999 return nilSwapchain, nil, 0, err 1000 } 1001 format, fmtOK, err := chooseFormat(pd, surf) 1002 if err != nil { 1003 return nilSwapchain, nil, 0, err 1004 } 1005 if !modeOK || !fmtOK { 1006 // This shouldn't happen because CreateDeviceAndQueue found at least 1007 // one valid format and present mode. 1008 return nilSwapchain, nil, 0, errors.New("vulkan: no valid format and present mode found") 1009 } 1010 // Find supported alpha composite mode. It doesn't matter which one, because rendering is 1011 // always opaque. 1012 alphaComp := C.VkCompositeAlphaFlagBitsKHR(1) 1013 for caps.supportedCompositeAlpha&C.VkCompositeAlphaFlagsKHR(alphaComp) == 0 { 1014 alphaComp <<= 1 1015 } 1016 trans := C.VkSurfaceTransformFlagBitsKHR(C.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) 1017 if caps.supportedTransforms&C.VkSurfaceTransformFlagsKHR(trans) == 0 { 1018 return nilSwapchain, nil, 0, errors.New("vulkan: VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR not supported") 1019 } 1020 inf := C.VkSwapchainCreateInfoKHR{ 1021 sType: C.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, 1022 surface: surf, 1023 minImageCount: caps.minImageCount, 1024 imageFormat: format.format, 1025 imageColorSpace: format.colorSpace, 1026 imageExtent: C.VkExtent2D{width: C.uint32_t(width), height: C.uint32_t(height)}, 1027 imageArrayLayers: 1, 1028 imageUsage: C.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1029 imageSharingMode: C.VK_SHARING_MODE_EXCLUSIVE, 1030 preTransform: trans, 1031 presentMode: mode, 1032 compositeAlpha: C.VkCompositeAlphaFlagBitsKHR(alphaComp), 1033 clipped: C.VK_TRUE, 1034 oldSwapchain: old, 1035 } 1036 var swchain Swapchain 1037 if err := vkErr(C.vkCreateSwapchainKHR(funcs.vkCreateSwapchainKHR, d, &inf, nil, &swchain)); err != nil { 1038 return nilSwapchain, nil, 0, fmt.Errorf("vulkan: vkCreateSwapchainKHR: %w", err) 1039 } 1040 var count C.uint32_t 1041 if err := vkErr(C.vkGetSwapchainImagesKHR(funcs.vkGetSwapchainImagesKHR, d, swchain, &count, nil)); err != nil { 1042 DestroySwapchain(d, swchain) 1043 return nilSwapchain, nil, 0, fmt.Errorf("vulkan: vkGetSwapchainImagesKHR: %w", err) 1044 } 1045 if count == 0 { 1046 DestroySwapchain(d, swchain) 1047 return nilSwapchain, nil, 0, errors.New("vulkan: vkGetSwapchainImagesKHR returned no images") 1048 } 1049 imgs := make([]Image, count) 1050 if err := vkErr(C.vkGetSwapchainImagesKHR(funcs.vkGetSwapchainImagesKHR, d, swchain, &count, &imgs[0])); err != nil { 1051 DestroySwapchain(d, swchain) 1052 return nilSwapchain, nil, 0, fmt.Errorf("vulkan: vkGetSwapchainImagesKHR: %w", err) 1053 } 1054 return swchain, imgs, format.format, nil 1055 } 1056 1057 func DestroySwapchain(d Device, swchain Swapchain) { 1058 C.vkDestroySwapchainKHR(funcs.vkDestroySwapchainKHR, d, swchain, nil) 1059 } 1060 1061 func AcquireNextImage(d Device, swchain Swapchain, sem Semaphore, fence Fence) (int, error) { 1062 res := C.vkAcquireNextImageKHR(funcs.vkAcquireNextImageKHR, d, swchain, math.MaxUint64, sem, fence) 1063 if err := vkErr(res.res); err != nil { 1064 return 0, fmt.Errorf("vulkan: vkAcquireNextImageKHR: %w", err) 1065 } 1066 return int(res.uint), nil 1067 } 1068 1069 func PresentQueue(q Queue, swchain Swapchain, sem Semaphore, imgIdx int) error { 1070 cidx := C.uint32_t(imgIdx) 1071 inf := C.VkPresentInfoKHR{ 1072 sType: C.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, 1073 swapchainCount: 1, 1074 pSwapchains: &swchain, 1075 pImageIndices: &cidx, 1076 } 1077 if sem != nilSemaphore { 1078 inf.waitSemaphoreCount = 1 1079 inf.pWaitSemaphores = &sem 1080 } 1081 if err := vkErr(C.vkQueuePresentKHR(funcs.vkQueuePresentKHR, q, inf)); err != nil { 1082 return fmt.Errorf("vulkan: vkQueuePresentKHR: %w", err) 1083 } 1084 return nil 1085 } 1086 1087 func CreateImageView(d Device, img Image, format Format) (ImageView, error) { 1088 inf := C.VkImageViewCreateInfo{ 1089 sType: C.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 1090 image: img, 1091 viewType: C.VK_IMAGE_VIEW_TYPE_2D, 1092 format: format, 1093 subresourceRange: C.VkImageSubresourceRange{ 1094 aspectMask: C.VK_IMAGE_ASPECT_COLOR_BIT, 1095 levelCount: C.VK_REMAINING_MIP_LEVELS, 1096 layerCount: C.VK_REMAINING_ARRAY_LAYERS, 1097 }, 1098 } 1099 var view C.VkImageView 1100 if err := vkErr(C.vkCreateImageView(funcs.vkCreateImageView, d, &inf, nil, &view)); err != nil { 1101 return nilImageView, fmt.Errorf("vulkan: vkCreateImageView: %w", err) 1102 } 1103 return view, nil 1104 } 1105 1106 func DestroyImageView(d Device, view ImageView) { 1107 C.vkDestroyImageView(funcs.vkDestroyImageView, d, view, nil) 1108 } 1109 1110 func CreateRenderPass(d Device, format Format, loadOp AttachmentLoadOp, initialLayout, finalLayout ImageLayout, passDeps []SubpassDependency) (RenderPass, error) { 1111 att := C.VkAttachmentDescription{ 1112 format: format, 1113 samples: C.VK_SAMPLE_COUNT_1_BIT, 1114 loadOp: loadOp, 1115 storeOp: C.VK_ATTACHMENT_STORE_OP_STORE, 1116 stencilLoadOp: C.VK_ATTACHMENT_LOAD_OP_DONT_CARE, 1117 stencilStoreOp: C.VK_ATTACHMENT_STORE_OP_DONT_CARE, 1118 initialLayout: initialLayout, 1119 finalLayout: finalLayout, 1120 } 1121 1122 ref := C.VkAttachmentReference{ 1123 attachment: 0, 1124 layout: C.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1125 } 1126 1127 sub := C.VkSubpassDescription{ 1128 pipelineBindPoint: C.VK_PIPELINE_BIND_POINT_GRAPHICS, 1129 colorAttachmentCount: 1, 1130 pColorAttachments: &ref, 1131 } 1132 1133 inf := C.VkRenderPassCreateInfo{ 1134 sType: C.VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 1135 attachmentCount: 1, 1136 pAttachments: &att, 1137 subpassCount: 1, 1138 } 1139 if n := len(passDeps); n > 0 { 1140 inf.dependencyCount = C.uint32_t(n) 1141 inf.pDependencies = &passDeps[0] 1142 } 1143 1144 var pass RenderPass 1145 if err := vkErr(C.vkCreateRenderPass(funcs.vkCreateRenderPass, d, inf, sub, nil, &pass)); err != nil { 1146 return nilRenderPass, fmt.Errorf("vulkan: vkCreateRenderPass: %w", err) 1147 } 1148 return pass, nil 1149 } 1150 1151 func DestroyRenderPass(d Device, r RenderPass) { 1152 C.vkDestroyRenderPass(funcs.vkDestroyRenderPass, d, r, nil) 1153 } 1154 1155 func CreateFramebuffer(d Device, rp RenderPass, view ImageView, width, height int) (Framebuffer, error) { 1156 inf := C.VkFramebufferCreateInfo{ 1157 sType: C.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 1158 renderPass: rp, 1159 attachmentCount: 1, 1160 pAttachments: &view, 1161 width: C.uint32_t(width), 1162 height: C.uint32_t(height), 1163 layers: 1, 1164 } 1165 var fbo Framebuffer 1166 if err := vkErr(C.vkCreateFramebuffer(funcs.vkCreateFramebuffer, d, inf, nil, &fbo)); err != nil { 1167 return nilFramebuffer, fmt.Errorf("vulkan: vkCreateFramebuffer: %w", err) 1168 } 1169 return fbo, nil 1170 1171 } 1172 1173 func DestroyFramebuffer(d Device, f Framebuffer) { 1174 C.vkDestroyFramebuffer(funcs.vkDestroyFramebuffer, d, f, nil) 1175 } 1176 1177 func DeviceWaitIdle(d Device) error { 1178 if err := vkErr(C.vkDeviceWaitIdle(funcs.vkDeviceWaitIdle, d)); err != nil { 1179 return fmt.Errorf("vulkan: vkDeviceWaitIdle: %w", err) 1180 } 1181 return nil 1182 } 1183 1184 func QueueWaitIdle(q Queue) error { 1185 if err := vkErr(C.vkQueueWaitIdle(funcs.vkQueueWaitIdle, q)); err != nil { 1186 return fmt.Errorf("vulkan: vkQueueWaitIdle: %w", err) 1187 } 1188 return nil 1189 } 1190 1191 func CreateSemaphore(d Device) (Semaphore, error) { 1192 inf := C.VkSemaphoreCreateInfo{ 1193 sType: C.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, 1194 } 1195 var sem Semaphore 1196 err := vkErr(C.vkCreateSemaphore(funcs.vkCreateSemaphore, d, &inf, nil, &sem)) 1197 if err != nil { 1198 return nilSemaphore, fmt.Errorf("vulkan: vkCreateSemaphore: %w", err) 1199 } 1200 return sem, err 1201 } 1202 1203 func DestroySemaphore(d Device, sem Semaphore) { 1204 C.vkDestroySemaphore(funcs.vkDestroySemaphore, d, sem, nil) 1205 } 1206 1207 func DestroyDevice(dev Device) { 1208 C.vkDestroyDevice(funcs.vkDestroyDevice, dev, nil) 1209 } 1210 1211 func DestroySurface(inst Instance, s Surface) { 1212 C.vkDestroySurfaceKHR(funcs.vkDestroySurfaceKHR, inst, s, nil) 1213 } 1214 1215 func CreateCommandPool(d Device, queueIndex int) (CommandPool, error) { 1216 inf := C.VkCommandPoolCreateInfo{ 1217 sType: C.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 1218 queueFamilyIndex: C.uint32_t(queueIndex), 1219 flags: C.VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | C.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, 1220 } 1221 1222 var pool CommandPool 1223 if err := vkErr(C.vkCreateCommandPool(funcs.vkCreateCommandPool, d, &inf, nil, &pool)); err != nil { 1224 return nilCommandPool, fmt.Errorf("vulkan: vkCreateCommandPool: %w", err) 1225 } 1226 return pool, nil 1227 } 1228 1229 func DestroyCommandPool(d Device, pool CommandPool) { 1230 C.vkDestroyCommandPool(funcs.vkDestroyCommandPool, d, pool, nil) 1231 } 1232 1233 func AllocateCommandBuffer(d Device, pool CommandPool) (CommandBuffer, error) { 1234 inf := C.VkCommandBufferAllocateInfo{ 1235 sType: C.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, 1236 commandPool: pool, 1237 level: C.VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1238 commandBufferCount: 1, 1239 } 1240 1241 var buf CommandBuffer 1242 if err := vkErr(C.vkAllocateCommandBuffers(funcs.vkAllocateCommandBuffers, d, &inf, &buf)); err != nil { 1243 return nil, fmt.Errorf("vulkan: vkAllocateCommandBuffers: %w", err) 1244 } 1245 return buf, nil 1246 } 1247 1248 func FreeCommandBuffers(d Device, pool CommandPool, bufs ...CommandBuffer) { 1249 if len(bufs) == 0 { 1250 return 1251 } 1252 C.vkFreeCommandBuffers(funcs.vkFreeCommandBuffers, d, pool, C.uint32_t(len(bufs)), &bufs[0]) 1253 } 1254 1255 func BeginCommandBuffer(buf CommandBuffer) error { 1256 inf := C.VkCommandBufferBeginInfo{ 1257 sType: C.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 1258 flags: C.VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 1259 } 1260 if err := vkErr(C.vkBeginCommandBuffer(funcs.vkBeginCommandBuffer, buf, inf)); err != nil { 1261 return fmt.Errorf("vulkan: vkBeginCommandBuffer: %w", err) 1262 } 1263 return nil 1264 } 1265 1266 func EndCommandBuffer(buf CommandBuffer) error { 1267 if err := vkErr(C.vkEndCommandBuffer(funcs.vkEndCommandBuffer, buf)); err != nil { 1268 return fmt.Errorf("vulkan: vkEndCommandBuffer: %w", err) 1269 } 1270 return nil 1271 } 1272 1273 func QueueSubmit(q Queue, buf CommandBuffer, waitSems []Semaphore, waitStages []PipelineStageFlags, sigSems []Semaphore, fence Fence) error { 1274 inf := C.VkSubmitInfo{ 1275 sType: C.VK_STRUCTURE_TYPE_SUBMIT_INFO, 1276 commandBufferCount: 1, 1277 pCommandBuffers: &buf, 1278 } 1279 if len(waitSems) > 0 { 1280 if len(waitSems) != len(waitStages) { 1281 panic("len(waitSems) != len(waitStages)") 1282 } 1283 inf.waitSemaphoreCount = C.uint32_t(len(waitSems)) 1284 inf.pWaitSemaphores = &waitSems[0] 1285 inf.pWaitDstStageMask = &waitStages[0] 1286 } 1287 if len(sigSems) > 0 { 1288 inf.signalSemaphoreCount = C.uint32_t(len(sigSems)) 1289 inf.pSignalSemaphores = &sigSems[0] 1290 } 1291 if err := vkErr(C.vkQueueSubmit(funcs.vkQueueSubmit, q, inf, fence)); err != nil { 1292 return fmt.Errorf("vulkan: vkQueueSubmit: %w", err) 1293 } 1294 return nil 1295 } 1296 1297 func CmdBeginRenderPass(buf CommandBuffer, rp RenderPass, fbo Framebuffer, width, height int, clearCol [4]float32) { 1298 cclearCol := [4]C.float{C.float(clearCol[0]), C.float(clearCol[1]), C.float(clearCol[2]), C.float(clearCol[3])} 1299 inf := C.VkRenderPassBeginInfo{ 1300 sType: C.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 1301 renderPass: rp, 1302 framebuffer: fbo, 1303 renderArea: C.VkRect2D{extent: C.VkExtent2D{width: C.uint32_t(width), height: C.uint32_t(height)}}, 1304 clearValueCount: 1, 1305 pClearValues: (*C.VkClearValue)(unsafe.Pointer(&cclearCol)), 1306 } 1307 C.vkCmdBeginRenderPass(funcs.vkCmdBeginRenderPass, buf, inf, C.VK_SUBPASS_CONTENTS_INLINE) 1308 } 1309 1310 func CmdEndRenderPass(buf CommandBuffer) { 1311 C.vkCmdEndRenderPass(funcs.vkCmdEndRenderPass, buf) 1312 } 1313 1314 func CmdCopyBuffer(cmdBuf CommandBuffer, src, dst Buffer, srcOff, dstOff, size int) { 1315 C.vkCmdCopyBuffer(funcs.vkCmdCopyBuffer, cmdBuf, src, dst, 1, &C.VkBufferCopy{ 1316 srcOffset: C.VkDeviceSize(srcOff), 1317 dstOffset: C.VkDeviceSize(dstOff), 1318 size: C.VkDeviceSize(size), 1319 }) 1320 } 1321 1322 func CmdCopyBufferToImage(cmdBuf CommandBuffer, src Buffer, dst Image, layout ImageLayout, copy BufferImageCopy) { 1323 C.vkCmdCopyBufferToImage(funcs.vkCmdCopyBufferToImage, cmdBuf, src, dst, layout, 1, ©) 1324 } 1325 1326 func CmdPipelineBarrier(cmdBuf CommandBuffer, srcStage, dstStage PipelineStageFlags, flags DependencyFlags, memBarriers []MemoryBarrier, bufBarriers []BufferMemoryBarrier, imgBarriers []ImageMemoryBarrier) { 1327 var memPtr *MemoryBarrier 1328 if len(memBarriers) > 0 { 1329 memPtr = &memBarriers[0] 1330 } 1331 var bufPtr *BufferMemoryBarrier 1332 if len(bufBarriers) > 0 { 1333 bufPtr = &bufBarriers[0] 1334 } 1335 var imgPtr *ImageMemoryBarrier 1336 if len(imgBarriers) > 0 { 1337 imgPtr = &imgBarriers[0] 1338 } 1339 C.vkCmdPipelineBarrier(funcs.vkCmdPipelineBarrier, cmdBuf, srcStage, dstStage, flags, 1340 C.uint32_t(len(memBarriers)), memPtr, 1341 C.uint32_t(len(bufBarriers)), bufPtr, 1342 C.uint32_t(len(imgBarriers)), imgPtr) 1343 } 1344 1345 func CmdPushConstants(cmdBuf CommandBuffer, layout PipelineLayout, stages ShaderStageFlags, offset int, data []byte) { 1346 if len(data) == 0 { 1347 return 1348 } 1349 C.vkCmdPushConstants(funcs.vkCmdPushConstants, cmdBuf, layout, stages, C.uint32_t(offset), C.uint32_t(len(data)), unsafe.Pointer(&data[0])) 1350 } 1351 1352 func CmdBindPipeline(cmdBuf CommandBuffer, bindPoint PipelineBindPoint, pipe Pipeline) { 1353 C.vkCmdBindPipeline(funcs.vkCmdBindPipeline, cmdBuf, bindPoint, pipe) 1354 } 1355 1356 func CmdBindVertexBuffers(cmdBuf CommandBuffer, first int, buffers []Buffer, sizes []DeviceSize) { 1357 if len(buffers) == 0 { 1358 return 1359 } 1360 C.vkCmdBindVertexBuffers(funcs.vkCmdBindVertexBuffers, cmdBuf, C.uint32_t(first), C.uint32_t(len(buffers)), &buffers[0], &sizes[0]) 1361 } 1362 1363 func CmdSetViewport(cmdBuf CommandBuffer, first int, viewports ...Viewport) { 1364 if len(viewports) == 0 { 1365 return 1366 } 1367 C.vkCmdSetViewport(funcs.vkCmdSetViewport, cmdBuf, C.uint32_t(first), C.uint32_t(len(viewports)), &viewports[0]) 1368 } 1369 1370 func CmdBindIndexBuffer(cmdBuf CommandBuffer, buffer Buffer, offset int, typ IndexType) { 1371 C.vkCmdBindIndexBuffer(funcs.vkCmdBindIndexBuffer, cmdBuf, buffer, C.VkDeviceSize(offset), typ) 1372 } 1373 1374 func CmdDraw(cmdBuf CommandBuffer, vertCount, instCount, firstVert, firstInst int) { 1375 C.vkCmdDraw(funcs.vkCmdDraw, cmdBuf, C.uint32_t(vertCount), C.uint32_t(instCount), C.uint32_t(firstVert), C.uint32_t(firstInst)) 1376 } 1377 1378 func CmdDrawIndexed(cmdBuf CommandBuffer, idxCount, instCount, firstIdx, vertOff, firstInst int) { 1379 C.vkCmdDrawIndexed(funcs.vkCmdDrawIndexed, cmdBuf, C.uint32_t(idxCount), C.uint32_t(instCount), C.uint32_t(firstIdx), C.int32_t(vertOff), C.uint32_t(firstInst)) 1380 } 1381 1382 func GetPhysicalDeviceFormatProperties(physDev PhysicalDevice, format Format) FormatFeatureFlags { 1383 var props C.VkFormatProperties 1384 C.vkGetPhysicalDeviceFormatProperties(funcs.vkGetPhysicalDeviceFormatProperties, physDev, format, &props) 1385 return FormatFeatureFlags(props.optimalTilingFeatures) 1386 } 1387 1388 func CmdBindDescriptorSets(cmdBuf CommandBuffer, point PipelineBindPoint, layout PipelineLayout, firstSet int, sets []DescriptorSet) { 1389 C.vkCmdBindDescriptorSets(funcs.vkCmdBindDescriptorSets, cmdBuf, point, layout, C.uint32_t(firstSet), C.uint32_t(len(sets)), &sets[0], 0, nil) 1390 } 1391 1392 func CmdBlitImage(cmdBuf CommandBuffer, src Image, srcLayout ImageLayout, dst Image, dstLayout ImageLayout, regions []ImageBlit, filter Filter) { 1393 if len(regions) == 0 { 1394 return 1395 } 1396 C.vkCmdBlitImage(funcs.vkCmdBlitImage, cmdBuf, src, srcLayout, dst, dstLayout, C.uint32_t(len(regions)), ®ions[0], filter) 1397 } 1398 1399 func CmdCopyImage(cmdBuf CommandBuffer, src Image, srcLayout ImageLayout, dst Image, dstLayout ImageLayout, regions []ImageCopy) { 1400 if len(regions) == 0 { 1401 return 1402 } 1403 C.vkCmdCopyImage(funcs.vkCmdCopyImage, cmdBuf, src, srcLayout, dst, dstLayout, C.uint32_t(len(regions)), ®ions[0]) 1404 } 1405 1406 func CmdCopyImageToBuffer(cmdBuf CommandBuffer, src Image, srcLayout ImageLayout, dst Buffer, regions []BufferImageCopy) { 1407 if len(regions) == 0 { 1408 return 1409 } 1410 C.vkCmdCopyImageToBuffer(funcs.vkCmdCopyImageToBuffer, cmdBuf, src, srcLayout, dst, C.uint32_t(len(regions)), ®ions[0]) 1411 } 1412 1413 func CmdDispatch(cmdBuf CommandBuffer, x, y, z int) { 1414 C.vkCmdDispatch(funcs.vkCmdDispatch, cmdBuf, C.uint32_t(x), C.uint32_t(y), C.uint32_t(z)) 1415 } 1416 1417 func CreateImage(pd PhysicalDevice, d Device, format Format, width, height, mipmaps int, usage ImageUsageFlags) (Image, DeviceMemory, error) { 1418 inf := C.VkImageCreateInfo{ 1419 sType: C.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 1420 imageType: C.VK_IMAGE_TYPE_2D, 1421 format: format, 1422 extent: C.VkExtent3D{ 1423 width: C.uint32_t(width), 1424 height: C.uint32_t(height), 1425 depth: 1, 1426 }, 1427 mipLevels: C.uint32_t(mipmaps), 1428 arrayLayers: 1, 1429 samples: C.VK_SAMPLE_COUNT_1_BIT, 1430 tiling: C.VK_IMAGE_TILING_OPTIMAL, 1431 usage: usage, 1432 initialLayout: C.VK_IMAGE_LAYOUT_UNDEFINED, 1433 } 1434 var img C.VkImage 1435 if err := vkErr(C.vkCreateImage(funcs.vkCreateImage, d, &inf, nil, &img)); err != nil { 1436 return nilImage, nilDeviceMemory, fmt.Errorf("vulkan: vkCreateImage: %w", err) 1437 } 1438 var memReqs C.VkMemoryRequirements 1439 C.vkGetImageMemoryRequirements(funcs.vkGetImageMemoryRequirements, d, img, &memReqs) 1440 1441 memIdx, found := findMemoryTypeIndex(pd, memReqs.memoryTypeBits, C.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) 1442 if !found { 1443 DestroyImage(d, img) 1444 return nilImage, nilDeviceMemory, errors.New("vulkan: no memory type suitable for images found") 1445 } 1446 1447 memInf := C.VkMemoryAllocateInfo{ 1448 sType: C.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 1449 allocationSize: memReqs.size, 1450 memoryTypeIndex: C.uint32_t(memIdx), 1451 } 1452 var imgMem C.VkDeviceMemory 1453 if err := vkErr(C.vkAllocateMemory(funcs.vkAllocateMemory, d, &memInf, nil, &imgMem)); err != nil { 1454 DestroyImage(d, img) 1455 return nilImage, nilDeviceMemory, fmt.Errorf("vulkan: vkAllocateMemory: %w", err) 1456 } 1457 1458 if err := vkErr(C.vkBindImageMemory(funcs.vkBindImageMemory, d, img, imgMem, 0)); err != nil { 1459 FreeMemory(d, imgMem) 1460 DestroyImage(d, img) 1461 return nilImage, nilDeviceMemory, fmt.Errorf("vulkan: vkBindImageMemory: %w", err) 1462 } 1463 return img, imgMem, nil 1464 } 1465 1466 func DestroyImage(d Device, img Image) { 1467 C.vkDestroyImage(funcs.vkDestroyImage, d, img, nil) 1468 } 1469 1470 func FreeMemory(d Device, mem DeviceMemory) { 1471 C.vkFreeMemory(funcs.vkFreeMemory, d, mem, nil) 1472 } 1473 1474 func CreateSampler(d Device, minFilter, magFilter Filter, mipmapMode SamplerMipmapMode) (Sampler, error) { 1475 inf := C.VkSamplerCreateInfo{ 1476 sType: C.VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, 1477 minFilter: minFilter, 1478 magFilter: magFilter, 1479 mipmapMode: mipmapMode, 1480 maxLod: C.VK_LOD_CLAMP_NONE, 1481 addressModeU: C.VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, 1482 addressModeV: C.VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, 1483 } 1484 var s C.VkSampler 1485 if err := vkErr(C.vkCreateSampler(funcs.vkCreateSampler, d, &inf, nil, &s)); err != nil { 1486 return nilSampler, fmt.Errorf("vulkan: vkCreateSampler: %w", err) 1487 } 1488 return s, nil 1489 } 1490 1491 func DestroySampler(d Device, sampler Sampler) { 1492 C.vkDestroySampler(funcs.vkDestroySampler, d, sampler, nil) 1493 } 1494 1495 func CreateBuffer(pd PhysicalDevice, d Device, size int, usage BufferUsageFlags, props MemoryPropertyFlags) (Buffer, DeviceMemory, error) { 1496 inf := C.VkBufferCreateInfo{ 1497 sType: C.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 1498 size: C.VkDeviceSize(size), 1499 usage: usage, 1500 } 1501 var buf C.VkBuffer 1502 if err := vkErr(C.vkCreateBuffer(funcs.vkCreateBuffer, d, &inf, nil, &buf)); err != nil { 1503 return nilBuffer, nilDeviceMemory, fmt.Errorf("vulkan: vkCreateBuffer: %w", err) 1504 } 1505 1506 var memReqs C.VkMemoryRequirements 1507 C.vkGetBufferMemoryRequirements(funcs.vkGetBufferMemoryRequirements, d, buf, &memReqs) 1508 1509 memIdx, found := findMemoryTypeIndex(pd, memReqs.memoryTypeBits, props) 1510 if !found { 1511 DestroyBuffer(d, buf) 1512 return nilBuffer, nilDeviceMemory, errors.New("vulkan: no memory suitable for buffers found") 1513 } 1514 memInf := C.VkMemoryAllocateInfo{ 1515 sType: C.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 1516 allocationSize: memReqs.size, 1517 memoryTypeIndex: C.uint32_t(memIdx), 1518 } 1519 1520 var mem C.VkDeviceMemory 1521 if err := vkErr(C.vkAllocateMemory(funcs.vkAllocateMemory, d, &memInf, nil, &mem)); err != nil { 1522 DestroyBuffer(d, buf) 1523 return nilBuffer, nilDeviceMemory, fmt.Errorf("vulkan: vkAllocateMemory: %w", err) 1524 } 1525 1526 if err := vkErr(C.vkBindBufferMemory(funcs.vkBindBufferMemory, d, buf, mem, 0)); err != nil { 1527 FreeMemory(d, mem) 1528 DestroyBuffer(d, buf) 1529 return nilBuffer, nilDeviceMemory, fmt.Errorf("vulkan: vkBindBufferMemory: %w", err) 1530 } 1531 return buf, mem, nil 1532 } 1533 1534 func DestroyBuffer(d Device, buf Buffer) { 1535 C.vkDestroyBuffer(funcs.vkDestroyBuffer, d, buf, nil) 1536 } 1537 1538 func CreateShaderModule(d Device, spirv string) (ShaderModule, error) { 1539 ptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&spirv)).Data) 1540 inf := C.VkShaderModuleCreateInfo{ 1541 sType: C.VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, 1542 codeSize: C.size_t(len(spirv)), 1543 pCode: (*C.uint32_t)(ptr), 1544 } 1545 1546 var mod C.VkShaderModule 1547 if err := vkErr(C.vkCreateShaderModule(funcs.vkCreateShaderModule, d, inf, nil, &mod)); err != nil { 1548 return nilShaderModule, fmt.Errorf("vulkan: vkCreateShaderModule: %w", err) 1549 } 1550 return mod, nil 1551 } 1552 1553 func DestroyShaderModule(d Device, mod ShaderModule) { 1554 C.vkDestroyShaderModule(funcs.vkDestroyShaderModule, d, mod, nil) 1555 } 1556 1557 func CreateGraphicsPipeline(d Device, pass RenderPass, vmod, fmod ShaderModule, blend bool, srcFactor, dstFactor BlendFactor, topology PrimitiveTopology, bindings []VertexInputBindingDescription, attrs []VertexInputAttributeDescription, layout PipelineLayout) (Pipeline, error) { 1558 main := C.CString("main") 1559 defer C.free(unsafe.Pointer(main)) 1560 stages := []C.VkPipelineShaderStageCreateInfo{ 1561 { 1562 sType: C.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1563 stage: C.VK_SHADER_STAGE_VERTEX_BIT, 1564 module: vmod, 1565 pName: main, 1566 }, 1567 { 1568 sType: C.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1569 stage: C.VK_SHADER_STAGE_FRAGMENT_BIT, 1570 module: fmod, 1571 pName: main, 1572 }, 1573 } 1574 dynStates := []C.VkDynamicState{C.VK_DYNAMIC_STATE_VIEWPORT} 1575 dynInf := C.VkPipelineDynamicStateCreateInfo{ 1576 sType: C.VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 1577 dynamicStateCount: C.uint32_t(len(dynStates)), 1578 pDynamicStates: &dynStates[0], 1579 } 1580 const maxDim = 0x7fffffff 1581 scissors := []C.VkRect2D{{extent: C.VkExtent2D{width: maxDim, height: maxDim}}} 1582 viewportInf := C.VkPipelineViewportStateCreateInfo{ 1583 sType: C.VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 1584 viewportCount: 1, 1585 scissorCount: C.uint32_t(len(scissors)), 1586 pScissors: &scissors[0], 1587 } 1588 enable := C.VkBool32(0) 1589 if blend { 1590 enable = 1 1591 } 1592 attBlendInf := C.VkPipelineColorBlendAttachmentState{ 1593 blendEnable: enable, 1594 srcColorBlendFactor: srcFactor, 1595 srcAlphaBlendFactor: srcFactor, 1596 dstColorBlendFactor: dstFactor, 1597 dstAlphaBlendFactor: dstFactor, 1598 colorBlendOp: C.VK_BLEND_OP_ADD, 1599 alphaBlendOp: C.VK_BLEND_OP_ADD, 1600 colorWriteMask: C.VK_COLOR_COMPONENT_R_BIT | C.VK_COLOR_COMPONENT_G_BIT | C.VK_COLOR_COMPONENT_B_BIT | C.VK_COLOR_COMPONENT_A_BIT, 1601 } 1602 blendInf := C.VkPipelineColorBlendStateCreateInfo{ 1603 sType: C.VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 1604 attachmentCount: 1, 1605 pAttachments: &attBlendInf, 1606 } 1607 var vkBinds []C.VkVertexInputBindingDescription 1608 var vkAttrs []C.VkVertexInputAttributeDescription 1609 for _, b := range bindings { 1610 vkBinds = append(vkBinds, C.VkVertexInputBindingDescription{ 1611 binding: C.uint32_t(b.Binding), 1612 stride: C.uint32_t(b.Stride), 1613 }) 1614 } 1615 for _, a := range attrs { 1616 vkAttrs = append(vkAttrs, C.VkVertexInputAttributeDescription{ 1617 location: C.uint32_t(a.Location), 1618 binding: C.uint32_t(a.Binding), 1619 format: a.Format, 1620 offset: C.uint32_t(a.Offset), 1621 }) 1622 } 1623 vertexInf := C.VkPipelineVertexInputStateCreateInfo{ 1624 sType: C.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 1625 } 1626 if n := len(vkBinds); n > 0 { 1627 vertexInf.vertexBindingDescriptionCount = C.uint32_t(n) 1628 vertexInf.pVertexBindingDescriptions = &vkBinds[0] 1629 } 1630 if n := len(vkAttrs); n > 0 { 1631 vertexInf.vertexAttributeDescriptionCount = C.uint32_t(n) 1632 vertexInf.pVertexAttributeDescriptions = &vkAttrs[0] 1633 } 1634 inf := C.VkGraphicsPipelineCreateInfo{ 1635 sType: C.VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 1636 stageCount: C.uint32_t(len(stages)), 1637 pStages: &stages[0], 1638 renderPass: pass, 1639 layout: layout, 1640 pRasterizationState: &C.VkPipelineRasterizationStateCreateInfo{ 1641 sType: C.VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 1642 lineWidth: 1.0, 1643 }, 1644 pMultisampleState: &C.VkPipelineMultisampleStateCreateInfo{ 1645 sType: C.VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 1646 rasterizationSamples: C.VK_SAMPLE_COUNT_1_BIT, 1647 }, 1648 pInputAssemblyState: &C.VkPipelineInputAssemblyStateCreateInfo{ 1649 sType: C.VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 1650 topology: topology, 1651 }, 1652 } 1653 1654 var pipe C.VkPipeline 1655 if err := vkErr(C.vkCreateGraphicsPipelines(funcs.vkCreateGraphicsPipelines, d, nilPipelineCache, inf, dynInf, blendInf, vertexInf, viewportInf, nil, &pipe)); err != nil { 1656 return nilPipeline, fmt.Errorf("vulkan: vkCreateGraphicsPipelines: %w", err) 1657 } 1658 return pipe, nil 1659 } 1660 1661 func DestroyPipeline(d Device, p Pipeline) { 1662 C.vkDestroyPipeline(funcs.vkDestroyPipeline, d, p, nil) 1663 } 1664 1665 func CreatePipelineLayout(d Device, pushRanges []PushConstantRange, sets []DescriptorSetLayout) (PipelineLayout, error) { 1666 inf := C.VkPipelineLayoutCreateInfo{ 1667 sType: C.VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 1668 } 1669 if n := len(sets); n > 0 { 1670 inf.setLayoutCount = C.uint32_t(n) 1671 inf.pSetLayouts = &sets[0] 1672 } 1673 if n := len(pushRanges); n > 0 { 1674 inf.pushConstantRangeCount = C.uint32_t(n) 1675 inf.pPushConstantRanges = &pushRanges[0] 1676 } 1677 var l C.VkPipelineLayout 1678 if err := vkErr(C.vkCreatePipelineLayout(funcs.vkCreatePipelineLayout, d, inf, nil, &l)); err != nil { 1679 return nilPipelineLayout, fmt.Errorf("vulkan: vkCreatePipelineLayout: %w", err) 1680 } 1681 return l, nil 1682 } 1683 1684 func DestroyPipelineLayout(d Device, l PipelineLayout) { 1685 C.vkDestroyPipelineLayout(funcs.vkDestroyPipelineLayout, d, l, nil) 1686 } 1687 1688 func CreateDescriptorSetLayout(d Device, bindings []DescriptorSetLayoutBinding) (DescriptorSetLayout, error) { 1689 var vkbinds []C.VkDescriptorSetLayoutBinding 1690 for _, b := range bindings { 1691 vkbinds = append(vkbinds, C.VkDescriptorSetLayoutBinding{ 1692 binding: C.uint32_t(b.Binding), 1693 descriptorType: b.DescriptorType, 1694 descriptorCount: 1, 1695 stageFlags: b.StageFlags, 1696 }) 1697 } 1698 inf := C.VkDescriptorSetLayoutCreateInfo{ 1699 sType: C.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 1700 } 1701 if n := len(vkbinds); n > 0 { 1702 inf.bindingCount = C.uint32_t(len(vkbinds)) 1703 inf.pBindings = &vkbinds[0] 1704 } 1705 var l C.VkDescriptorSetLayout 1706 if err := vkErr(C.vkCreateDescriptorSetLayout(funcs.vkCreateDescriptorSetLayout, d, inf, nil, &l)); err != nil { 1707 return nilDescriptorSetLayout, fmt.Errorf("vulkan: vkCreateDescriptorSetLayout: %w", err) 1708 } 1709 return l, nil 1710 } 1711 1712 func DestroyDescriptorSetLayout(d Device, l DescriptorSetLayout) { 1713 C.vkDestroyDescriptorSetLayout(funcs.vkDestroyDescriptorSetLayout, d, l, nil) 1714 } 1715 1716 func MapMemory(d Device, mem DeviceMemory, offset, size int) ([]byte, error) { 1717 var ptr unsafe.Pointer 1718 if err := vkErr(C.vkMapMemory(funcs.vkMapMemory, d, mem, C.VkDeviceSize(offset), C.VkDeviceSize(size), 0, &ptr)); err != nil { 1719 return nil, fmt.Errorf("vulkan: vkMapMemory: %w", err) 1720 } 1721 return ((*[1 << 30]byte)(ptr))[:size:size], nil 1722 } 1723 1724 func UnmapMemory(d Device, mem DeviceMemory) { 1725 C.vkUnmapMemory(funcs.vkUnmapMemory, d, mem) 1726 } 1727 1728 func ResetCommandBuffer(buf CommandBuffer) error { 1729 if err := vkErr(C.vkResetCommandBuffer(funcs.vkResetCommandBuffer, buf, 0)); err != nil { 1730 return fmt.Errorf("vulkan: vkResetCommandBuffer. %w", err) 1731 } 1732 return nil 1733 } 1734 1735 func CreateDescriptorPool(d Device, maxSets int, sizes []DescriptorPoolSize) (DescriptorPool, error) { 1736 inf := C.VkDescriptorPoolCreateInfo{ 1737 sType: C.VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 1738 maxSets: C.uint32_t(maxSets), 1739 poolSizeCount: C.uint32_t(len(sizes)), 1740 pPoolSizes: &sizes[0], 1741 } 1742 var pool C.VkDescriptorPool 1743 if err := vkErr(C.vkCreateDescriptorPool(funcs.vkCreateDescriptorPool, d, inf, nil, &pool)); err != nil { 1744 return nilDescriptorPool, fmt.Errorf("vulkan: vkCreateDescriptorPool: %w", err) 1745 } 1746 return pool, nil 1747 } 1748 1749 func DestroyDescriptorPool(d Device, pool DescriptorPool) { 1750 C.vkDestroyDescriptorPool(funcs.vkDestroyDescriptorPool, d, pool, nil) 1751 } 1752 1753 func ResetDescriptorPool(d Device, pool DescriptorPool) error { 1754 if err := vkErr(C.vkResetDescriptorPool(funcs.vkResetDescriptorPool, d, pool, 0)); err != nil { 1755 return fmt.Errorf("vulkan: vkResetDescriptorPool: %w", err) 1756 } 1757 return nil 1758 } 1759 1760 func UpdateDescriptorSet(d Device, write WriteDescriptorSet) { 1761 C.vkUpdateDescriptorSets(funcs.vkUpdateDescriptorSets, d, write, 0, nil) 1762 } 1763 1764 func AllocateDescriptorSets(d Device, pool DescriptorPool, layout DescriptorSetLayout, count int) ([]DescriptorSet, error) { 1765 layouts := make([]DescriptorSetLayout, count) 1766 for i := range layouts { 1767 layouts[i] = layout 1768 } 1769 inf := C.VkDescriptorSetAllocateInfo{ 1770 sType: C.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1771 descriptorPool: pool, 1772 descriptorSetCount: C.uint32_t(count), 1773 pSetLayouts: &layouts[0], 1774 } 1775 sets := make([]DescriptorSet, count) 1776 if err := vkErr(C.vkAllocateDescriptorSets(funcs.vkAllocateDescriptorSets, d, inf, &sets[0])); err != nil { 1777 return nil, fmt.Errorf("vulkan: vkAllocateDescriptorSets: %w", err) 1778 } 1779 return sets, nil 1780 } 1781 1782 func CreateComputePipeline(d Device, mod ShaderModule, layout PipelineLayout) (Pipeline, error) { 1783 main := C.CString("main") 1784 defer C.free(unsafe.Pointer(main)) 1785 inf := C.VkComputePipelineCreateInfo{ 1786 sType: C.VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 1787 stage: C.VkPipelineShaderStageCreateInfo{ 1788 sType: C.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1789 stage: C.VK_SHADER_STAGE_COMPUTE_BIT, 1790 module: mod, 1791 pName: main, 1792 }, 1793 layout: layout, 1794 } 1795 var pipe C.VkPipeline 1796 if err := vkErr(C.vkCreateComputePipelines(funcs.vkCreateComputePipelines, d, nilPipelineCache, 1, &inf, nil, &pipe)); err != nil { 1797 return nilPipeline, fmt.Errorf("vulkan: vkCreateComputePipelines: %w", err) 1798 } 1799 return pipe, nil 1800 } 1801 1802 func CreateFence(d Device, flags int) (Fence, error) { 1803 inf := C.VkFenceCreateInfo{ 1804 sType: C.VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 1805 flags: C.VkFenceCreateFlags(flags), 1806 } 1807 var f C.VkFence 1808 if err := vkErr(C.vkCreateFence(funcs.vkCreateFence, d, &inf, nil, &f)); err != nil { 1809 return nilFence, fmt.Errorf("vulkan: vkCreateFence: %w", err) 1810 } 1811 return f, nil 1812 } 1813 1814 func DestroyFence(d Device, f Fence) { 1815 C.vkDestroyFence(funcs.vkDestroyFence, d, f, nil) 1816 } 1817 1818 func WaitForFences(d Device, fences ...Fence) error { 1819 if len(fences) == 0 { 1820 return nil 1821 } 1822 err := vkErr(C.vkWaitForFences(funcs.vkWaitForFences, d, C.uint32_t(len(fences)), &fences[0], C.VK_TRUE, 0xffffffffffffffff)) 1823 if err != nil { 1824 return fmt.Errorf("vulkan: vkWaitForFences: %w", err) 1825 } 1826 return nil 1827 } 1828 1829 func ResetFences(d Device, fences ...Fence) error { 1830 if len(fences) == 0 { 1831 return nil 1832 } 1833 err := vkErr(C.vkResetFences(funcs.vkResetFences, d, C.uint32_t(len(fences)), &fences[0])) 1834 if err != nil { 1835 return fmt.Errorf("vulkan: vkResetFences: %w", err) 1836 } 1837 return nil 1838 } 1839 1840 func BuildSubpassDependency(srcStage, dstStage PipelineStageFlags, srcMask, dstMask AccessFlags, flags DependencyFlags) SubpassDependency { 1841 return C.VkSubpassDependency{ 1842 srcSubpass: C.VK_SUBPASS_EXTERNAL, 1843 srcStageMask: srcStage, 1844 srcAccessMask: srcMask, 1845 dstSubpass: 0, 1846 dstStageMask: dstStage, 1847 dstAccessMask: dstMask, 1848 dependencyFlags: flags, 1849 } 1850 } 1851 1852 func BuildPushConstantRange(stages ShaderStageFlags, offset, size int) PushConstantRange { 1853 return C.VkPushConstantRange{ 1854 stageFlags: stages, 1855 offset: C.uint32_t(offset), 1856 size: C.uint32_t(size), 1857 } 1858 } 1859 1860 func BuildDescriptorPoolSize(typ DescriptorType, count int) DescriptorPoolSize { 1861 return C.VkDescriptorPoolSize{ 1862 _type: typ, 1863 descriptorCount: C.uint32_t(count), 1864 } 1865 } 1866 1867 func BuildWriteDescriptorSetImage(set DescriptorSet, binding int, typ DescriptorType, sampler Sampler, view ImageView, layout ImageLayout) WriteDescriptorSet { 1868 return C.VkWriteDescriptorSet{ 1869 sType: C.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 1870 dstSet: set, 1871 dstBinding: C.uint32_t(binding), 1872 descriptorCount: 1, 1873 descriptorType: typ, 1874 pImageInfo: &C.VkDescriptorImageInfo{ 1875 sampler: sampler, 1876 imageView: view, 1877 imageLayout: layout, 1878 }, 1879 } 1880 } 1881 1882 func BuildWriteDescriptorSetBuffer(set DescriptorSet, binding int, typ DescriptorType, buf Buffer) WriteDescriptorSet { 1883 return C.VkWriteDescriptorSet{ 1884 sType: C.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 1885 dstSet: set, 1886 dstBinding: C.uint32_t(binding), 1887 descriptorCount: 1, 1888 descriptorType: typ, 1889 pBufferInfo: &C.VkDescriptorBufferInfo{ 1890 buffer: buf, 1891 _range: C.VK_WHOLE_SIZE, 1892 }, 1893 } 1894 } 1895 1896 func (r PushConstantRange) StageFlags() ShaderStageFlags { 1897 return r.stageFlags 1898 } 1899 1900 func (r PushConstantRange) Offset() int { 1901 return int(r.offset) 1902 } 1903 1904 func (r PushConstantRange) Size() int { 1905 return int(r.size) 1906 } 1907 1908 func (p QueueFamilyProperties) Flags() QueueFlags { 1909 return p.queueFlags 1910 } 1911 1912 func (c SurfaceCapabilities) MinExtent() image.Point { 1913 return image.Pt(int(c.minImageExtent.width), int(c.minImageExtent.height)) 1914 } 1915 1916 func (c SurfaceCapabilities) MaxExtent() image.Point { 1917 return image.Pt(int(c.maxImageExtent.width), int(c.maxImageExtent.height)) 1918 } 1919 1920 func BuildViewport(x, y, width, height float32) Viewport { 1921 return C.VkViewport{ 1922 x: C.float(x), 1923 y: C.float(y), 1924 width: C.float(width), 1925 height: C.float(height), 1926 maxDepth: 1.0, 1927 } 1928 } 1929 1930 func BuildImageMemoryBarrier(img Image, srcMask, dstMask AccessFlags, oldLayout, newLayout ImageLayout, baseMip, numMips int) ImageMemoryBarrier { 1931 return C.VkImageMemoryBarrier{ 1932 sType: C.VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 1933 srcAccessMask: srcMask, 1934 dstAccessMask: dstMask, 1935 oldLayout: oldLayout, 1936 newLayout: newLayout, 1937 image: img, 1938 subresourceRange: C.VkImageSubresourceRange{ 1939 aspectMask: C.VK_IMAGE_ASPECT_COLOR_BIT, 1940 baseMipLevel: C.uint32_t(baseMip), 1941 levelCount: C.uint32_t(numMips), 1942 layerCount: C.VK_REMAINING_ARRAY_LAYERS, 1943 }, 1944 } 1945 } 1946 1947 func BuildBufferMemoryBarrier(buf Buffer, srcMask, dstMask AccessFlags) BufferMemoryBarrier { 1948 return C.VkBufferMemoryBarrier{ 1949 sType: C.VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 1950 srcAccessMask: srcMask, 1951 dstAccessMask: dstMask, 1952 buffer: buf, 1953 size: C.VK_WHOLE_SIZE, 1954 } 1955 } 1956 1957 func BuildMemoryBarrier(srcMask, dstMask AccessFlags) MemoryBarrier { 1958 return C.VkMemoryBarrier{ 1959 sType: C.VK_STRUCTURE_TYPE_MEMORY_BARRIER, 1960 srcAccessMask: srcMask, 1961 dstAccessMask: dstMask, 1962 } 1963 } 1964 1965 func BuildBufferImageCopy(bufOff, bufStride, x, y, width, height int) BufferImageCopy { 1966 return C.VkBufferImageCopy{ 1967 bufferOffset: C.VkDeviceSize(bufOff), 1968 bufferRowLength: C.uint32_t(bufStride), 1969 imageSubresource: C.VkImageSubresourceLayers{ 1970 aspectMask: C.VK_IMAGE_ASPECT_COLOR_BIT, 1971 layerCount: 1, 1972 }, 1973 imageOffset: C.VkOffset3D{ 1974 x: C.int32_t(x), y: C.int32_t(y), z: 0, 1975 }, 1976 imageExtent: C.VkExtent3D{ 1977 width: C.uint32_t(width), height: C.uint32_t(height), depth: 1, 1978 }, 1979 } 1980 } 1981 1982 func BuildImageCopy(srcX, srcY, dstX, dstY, width, height int) ImageCopy { 1983 return C.VkImageCopy{ 1984 srcSubresource: C.VkImageSubresourceLayers{ 1985 aspectMask: C.VK_IMAGE_ASPECT_COLOR_BIT, 1986 layerCount: 1, 1987 }, 1988 srcOffset: C.VkOffset3D{ 1989 x: C.int32_t(srcX), 1990 y: C.int32_t(srcY), 1991 }, 1992 dstSubresource: C.VkImageSubresourceLayers{ 1993 aspectMask: C.VK_IMAGE_ASPECT_COLOR_BIT, 1994 layerCount: 1, 1995 }, 1996 dstOffset: C.VkOffset3D{ 1997 x: C.int32_t(dstX), 1998 y: C.int32_t(dstY), 1999 }, 2000 extent: C.VkExtent3D{ 2001 width: C.uint32_t(width), 2002 height: C.uint32_t(height), 2003 depth: 1, 2004 }, 2005 } 2006 } 2007 2008 func BuildImageBlit(srcX, srcY, dstX, dstY, srcWidth, srcHeight, dstWidth, dstHeight, srcMip, dstMip int) ImageBlit { 2009 return C.VkImageBlit{ 2010 srcOffsets: [2]C.VkOffset3D{ 2011 {C.int32_t(srcX), C.int32_t(srcY), 0}, 2012 {C.int32_t(srcWidth), C.int32_t(srcHeight), 1}, 2013 }, 2014 srcSubresource: C.VkImageSubresourceLayers{ 2015 aspectMask: C.VK_IMAGE_ASPECT_COLOR_BIT, 2016 layerCount: 1, 2017 mipLevel: C.uint32_t(srcMip), 2018 }, 2019 dstOffsets: [2]C.VkOffset3D{ 2020 {C.int32_t(dstX), C.int32_t(dstY), 0}, 2021 {C.int32_t(dstWidth), C.int32_t(dstHeight), 1}, 2022 }, 2023 dstSubresource: C.VkImageSubresourceLayers{ 2024 aspectMask: C.VK_IMAGE_ASPECT_COLOR_BIT, 2025 layerCount: 1, 2026 mipLevel: C.uint32_t(dstMip), 2027 }, 2028 } 2029 } 2030 2031 func findMemoryTypeIndex(pd C.VkPhysicalDevice, constraints C.uint32_t, wantProps C.VkMemoryPropertyFlags) (int, bool) { 2032 var memProps C.VkPhysicalDeviceMemoryProperties 2033 C.vkGetPhysicalDeviceMemoryProperties(funcs.vkGetPhysicalDeviceMemoryProperties, pd, &memProps) 2034 2035 for i := 0; i < int(memProps.memoryTypeCount); i++ { 2036 if (constraints & (1 << i)) == 0 { 2037 continue 2038 } 2039 if (memProps.memoryTypes[i].propertyFlags & wantProps) != wantProps { 2040 continue 2041 } 2042 return i, true 2043 } 2044 2045 return 0, false 2046 } 2047 2048 func choosePresentMode(pd C.VkPhysicalDevice, surf Surface) (C.VkPresentModeKHR, bool, error) { 2049 var count C.uint32_t 2050 err := vkErr(C.vkGetPhysicalDeviceSurfacePresentModesKHR(funcs.vkGetPhysicalDeviceSurfacePresentModesKHR, pd, surf, &count, nil)) 2051 if err != nil { 2052 return 0, false, fmt.Errorf("vulkan: vkGetPhysicalDeviceSurfacePresentModesKHR: %w", err) 2053 } 2054 if count == 0 { 2055 return 0, false, nil 2056 } 2057 modes := make([]C.VkPresentModeKHR, count) 2058 err = vkErr(C.vkGetPhysicalDeviceSurfacePresentModesKHR(funcs.vkGetPhysicalDeviceSurfacePresentModesKHR, pd, surf, &count, &modes[0])) 2059 if err != nil { 2060 return 0, false, fmt.Errorf("vulkan: kGetPhysicalDeviceSurfacePresentModesKHR: %w", err) 2061 } 2062 for _, m := range modes { 2063 if m == C.VK_PRESENT_MODE_MAILBOX_KHR || m == C.VK_PRESENT_MODE_FIFO_KHR { 2064 return m, true, nil 2065 } 2066 } 2067 return 0, false, nil 2068 } 2069 2070 func chooseFormat(pd C.VkPhysicalDevice, surf Surface) (C.VkSurfaceFormatKHR, bool, error) { 2071 var count C.uint32_t 2072 err := vkErr(C.vkGetPhysicalDeviceSurfaceFormatsKHR(funcs.vkGetPhysicalDeviceSurfaceFormatsKHR, pd, surf, &count, nil)) 2073 if err != nil { 2074 return C.VkSurfaceFormatKHR{}, false, fmt.Errorf("vulkan: vkGetPhysicalDeviceSurfaceFormatsKHR: %w", err) 2075 } 2076 if count == 0 { 2077 return C.VkSurfaceFormatKHR{}, false, nil 2078 } 2079 formats := make([]C.VkSurfaceFormatKHR, count) 2080 err = vkErr(C.vkGetPhysicalDeviceSurfaceFormatsKHR(funcs.vkGetPhysicalDeviceSurfaceFormatsKHR, pd, surf, &count, &formats[0])) 2081 if err != nil { 2082 return C.VkSurfaceFormatKHR{}, false, fmt.Errorf("vulkan: vkGetPhysicalDeviceSurfaceFormatsKHR: %w", err) 2083 } 2084 // Query for format with sRGB support. 2085 // TODO: Support devices without sRGB. 2086 for _, f := range formats { 2087 if f.colorSpace != C.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR { 2088 continue 2089 } 2090 switch f.format { 2091 case C.VK_FORMAT_B8G8R8A8_SRGB, C.VK_FORMAT_R8G8B8A8_SRGB: 2092 return f, true, nil 2093 } 2094 } 2095 return C.VkSurfaceFormatKHR{}, false, nil 2096 } 2097 2098 func chooseQueue(pd C.VkPhysicalDevice, surf Surface, flags C.VkQueueFlags) (int, bool, error) { 2099 queues := GetPhysicalDeviceQueueFamilyProperties(pd) 2100 for i, q := range queues { 2101 // Check for presentation and feature support. 2102 if q.queueFlags&flags != flags { 2103 continue 2104 } 2105 if surf != nilSurface { 2106 // Check for presentation support. It is possible that a device has no 2107 // queue with both rendering and presentation support, but not in reality. 2108 // See https://github.com/KhronosGroup/Vulkan-Docs/issues/1234. 2109 var support C.VkBool32 2110 if err := vkErr(C.vkGetPhysicalDeviceSurfaceSupportKHR(funcs.vkGetPhysicalDeviceSurfaceSupportKHR, pd, C.uint32_t(i), surf, &support)); err != nil { 2111 return 0, false, fmt.Errorf("vulkan: vkGetPhysicalDeviceSurfaceSupportKHR: %w", err) 2112 } 2113 if support != C.VK_TRUE { 2114 continue 2115 } 2116 } 2117 return i, true, nil 2118 } 2119 return 0, false, nil 2120 } 2121 2122 func dlsym(handle unsafe.Pointer, s string) unsafe.Pointer { 2123 cs := C.CString(s) 2124 defer C.free(unsafe.Pointer(cs)) 2125 return C.dlsym(handle, cs) 2126 } 2127 2128 func dlopen(lib string) unsafe.Pointer { 2129 clib := C.CString(lib) 2130 defer C.free(unsafe.Pointer(clib)) 2131 return C.dlopen(clib, C.RTLD_NOW|C.RTLD_LOCAL) 2132 } 2133 2134 func vkErr(res C.VkResult) error { 2135 switch res { 2136 case C.VK_SUCCESS: 2137 return nil 2138 default: 2139 return Error(res) 2140 } 2141 } 2142 2143 func (e Error) Error() string { 2144 return fmt.Sprintf("error %d", e) 2145 }