vulkan.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. #define HL_NAME(n) sdl_##n
  2. #include <hl.h>
  3. #define VK_USE_PLATFORM_WIN32_KHR
  4. #include <vulkan/vulkan.h>
  5. #include <shaderc/shaderc.h>
  6. static VkInstance instance = NULL;
  7. VkInstance vk_get_instance() {
  8. return instance;
  9. }
  10. HL_PRIM bool HL_NAME(vk_init)( bool enable_validation ) {
  11. if( instance )
  12. return true;
  13. VkApplicationInfo appInfo = {
  14. .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
  15. .pApplicationName = "HashLink Vulkan",
  16. .applicationVersion = VK_MAKE_VERSION(1, 0, 0),
  17. .pEngineName = "Heaps.io",
  18. .engineVersion = VK_MAKE_VERSION(1, 0, 0),
  19. .apiVersion = VK_API_VERSION_1_0,
  20. };
  21. VkInstanceCreateInfo info = {
  22. .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
  23. .pApplicationInfo = &appInfo,
  24. .enabledLayerCount = enable_validation ? 1 : 0,
  25. .enabledExtensionCount = enable_validation ? 3 : 2,
  26. .ppEnabledLayerNames = (const char* const[]) { "VK_LAYER_KHRONOS_validation" },
  27. .ppEnabledExtensionNames = (const char* const[]) { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME },
  28. };
  29. return vkCreateInstance(&info, NULL, &instance) == VK_SUCCESS;
  30. }
  31. vbyte *HL_NAME(vk_make_ref)( vdynamic *v ) {
  32. if( v->t->kind != HSTRUCT ) hl_error("assert");
  33. return v->v.ptr;
  34. }
  35. vbyte *HL_NAME(vk_make_array)( varray *a ) {
  36. if( a->size == 0 )
  37. return NULL;
  38. if( a->at->kind == HABSTRACT )
  39. return hl_copy_bytes(hl_aptr(a,vbyte), a->size * sizeof(void*));
  40. if( a->at->kind == HI32 )
  41. return hl_copy_bytes(hl_aptr(a,vbyte), a->size * sizeof(int));
  42. #ifdef HL_DEBUG
  43. if( a->at->kind != HSTRUCT ) hl_error("assert");
  44. #endif
  45. int size = a->at->obj->rt->size;
  46. vbyte *ptr = hl_alloc_bytes(size * a->size);
  47. int i;
  48. for(i=0;i<a->size;i++)
  49. memcpy(ptr + i * size, hl_aptr(a,vbyte*)[i], size);
  50. return ptr;
  51. }
  52. // ------------------------------------------ CONTEXT INIT --------------------------------------------
  53. typedef struct _VkContext {
  54. VkSurfaceKHR surface;
  55. VkPhysicalDevice pdevice;
  56. VkPhysicalDeviceMemoryProperties memProps;
  57. VkDevice device;
  58. VkQueue queue;
  59. VkSwapchainKHR swapchain;
  60. } *VkContext;
  61. VkContext HL_NAME(vk_init_context)( VkSurfaceKHR surface, int *outQueue ) {
  62. VkContext ctx = (VkContext)malloc(sizeof(struct _VkContext));
  63. memset(ctx,0,sizeof(struct _VkContext));
  64. ctx->surface = surface;
  65. int queueFamily = 0;
  66. int physicalDeviceCount;
  67. # define MAX_DEVICE_COUNT 16
  68. # define MAX_QUEUE_COUNT 16
  69. VkPhysicalDevice deviceHandles[MAX_DEVICE_COUNT];
  70. VkQueueFamilyProperties queueFamilyProperties[MAX_QUEUE_COUNT];
  71. VkPhysicalDeviceProperties deviceProperties;
  72. VkPhysicalDeviceFeatures deviceFeatures;
  73. vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, 0);
  74. physicalDeviceCount = physicalDeviceCount > MAX_DEVICE_COUNT ? MAX_DEVICE_COUNT : physicalDeviceCount;
  75. vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, deviceHandles);
  76. for(int i=0; i<physicalDeviceCount; i++) {
  77. int queueFamilyCount = 0;
  78. vkGetPhysicalDeviceQueueFamilyProperties(deviceHandles[i], &queueFamilyCount, NULL);
  79. queueFamilyCount = queueFamilyCount > MAX_QUEUE_COUNT ? MAX_QUEUE_COUNT : queueFamilyCount;
  80. vkGetPhysicalDeviceQueueFamilyProperties(deviceHandles[i], &queueFamilyCount, queueFamilyProperties);
  81. vkGetPhysicalDeviceProperties(deviceHandles[i], &deviceProperties);
  82. vkGetPhysicalDeviceFeatures(deviceHandles[i], &deviceFeatures);
  83. for(int j=0; j<queueFamilyCount; j++) {
  84. VkBool32 supportsPresent = VK_FALSE;
  85. vkGetPhysicalDeviceSurfaceSupportKHR(deviceHandles[i], j, ctx->surface, &supportsPresent);
  86. if (supportsPresent && (queueFamilyProperties[j].queueFlags & VK_QUEUE_GRAPHICS_BIT)) {
  87. queueFamily = j;
  88. ctx->pdevice = deviceHandles[i];
  89. break;
  90. }
  91. }
  92. if( ctx->pdevice ) break;
  93. }
  94. VkDeviceQueueCreateInfo qinf = {
  95. .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
  96. .queueFamilyIndex = queueFamily,
  97. .queueCount = 1,
  98. .pQueuePriorities = (const float[]) { 1.0f }
  99. };
  100. VkDeviceCreateInfo dinf = {
  101. .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
  102. .queueCreateInfoCount = 1,
  103. .pQueueCreateInfos = 0,
  104. .enabledLayerCount = 0,
  105. .ppEnabledLayerNames = 0,
  106. .enabledExtensionCount = 1,
  107. .ppEnabledExtensionNames = (const char* const[]) { VK_KHR_SWAPCHAIN_EXTENSION_NAME },
  108. .pEnabledFeatures = 0,
  109. .pQueueCreateInfos = &qinf,
  110. };
  111. if( vkCreateDevice(ctx->pdevice, &dinf, NULL, &ctx->device) != VK_SUCCESS )
  112. return NULL;
  113. vkGetDeviceQueue(ctx->device, queueFamily, 0, &ctx->queue);
  114. vkGetPhysicalDeviceMemoryProperties(ctx->pdevice, &ctx->memProps);
  115. *outQueue = queueFamily;
  116. return ctx;
  117. }
  118. vbyte *HL_NAME(vk_get_device_name)( VkContext ctx ) {
  119. VkPhysicalDeviceProperties props;
  120. vkGetPhysicalDeviceProperties(ctx->pdevice, &props);
  121. return hl_copy_bytes(props.deviceName, (int)strlen(props.deviceName)+1);
  122. }
  123. VkPhysicalDeviceLimits *HL_NAME(vk_get_limits)( VkContext ctx ) {
  124. VkPhysicalDeviceProperties props;
  125. vkGetPhysicalDeviceProperties(ctx->pdevice, &props);
  126. return (VkPhysicalDeviceLimits*)hl_copy_bytes((vbyte*)&props.limits, sizeof(VkPhysicalDeviceLimits));
  127. }
  128. int HL_NAME(vk_find_memory_type)( VkContext ctx, int allowed, int req ) {
  129. unsigned int i;
  130. for(i=0;i<ctx->memProps.memoryTypeCount;i++) {
  131. if( (allowed & (1<< i)) && (ctx->memProps.memoryTypes[i].propertyFlags & req) == req )
  132. return i;
  133. }
  134. return -1;
  135. }
  136. void HL_NAME(vk_get_pdevice_format_props)( VkContext ctx, VkFormat format, VkFormatProperties *props ) {
  137. vkGetPhysicalDeviceFormatProperties(ctx->pdevice, format, props);
  138. }
  139. bool HL_NAME(vk_init_swapchain)( VkContext ctx, int width, int height, varray *outImages, VkFormat *outFormat ) {
  140. vkDeviceWaitIdle(ctx->device);
  141. if( ctx->swapchain ) {
  142. vkDestroySwapchainKHR(ctx->device, ctx->swapchain, NULL);
  143. ctx->swapchain = NULL;
  144. }
  145. int formatCount = 1;
  146. VkSurfaceFormatKHR format;
  147. vkGetPhysicalDeviceSurfaceFormatsKHR(ctx->pdevice, ctx->surface, &formatCount, 0);
  148. formatCount = 1;
  149. vkGetPhysicalDeviceSurfaceFormatsKHR(ctx->pdevice, ctx->surface, &formatCount, &format);
  150. format.format = format.format == VK_FORMAT_UNDEFINED ? VK_FORMAT_B8G8R8A8_UNORM : format.format;
  151. int modeCount = 0;
  152. # define MAX_PRESENT_MODE_COUNT 16
  153. VkPresentModeKHR modes[MAX_PRESENT_MODE_COUNT];
  154. vkGetPhysicalDeviceSurfacePresentModesKHR(ctx->pdevice, ctx->surface, &modeCount, NULL);
  155. modeCount = modeCount > MAX_PRESENT_MODE_COUNT ? MAX_PRESENT_MODE_COUNT : modeCount;
  156. vkGetPhysicalDeviceSurfacePresentModesKHR(ctx->pdevice, ctx->surface, &modeCount, modes);
  157. VkSurfaceCapabilitiesKHR scaps;
  158. vkGetPhysicalDeviceSurfaceCapabilitiesKHR(ctx->pdevice, ctx->surface, &scaps);
  159. VkExtent2D swapchainExtent = scaps.currentExtent;
  160. # define clamp(v,min,max) ( ((v) < (min)) ? (min) : ((v) < (max)) ? (max) : (v) )
  161. if( swapchainExtent.width == UINT32_MAX ) {
  162. swapchainExtent.width = clamp((unsigned)width, scaps.minImageExtent.width, scaps.maxImageExtent.width);
  163. swapchainExtent.height = clamp((unsigned)height, scaps.minImageExtent.height, scaps.maxImageExtent.height);
  164. }
  165. VkSwapchainCreateInfoKHR swapInfo = {
  166. .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
  167. .surface = ctx->surface,
  168. .minImageCount = outImages->size,
  169. .imageFormat = format.format,
  170. .imageColorSpace = format.colorSpace,
  171. .imageExtent = swapchainExtent,
  172. .imageArrayLayers = 1,
  173. .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
  174. .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
  175. .preTransform = scaps.currentTransform,
  176. .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
  177. .presentMode = VK_PRESENT_MODE_FIFO_KHR, // always supported
  178. .clipped = VK_TRUE,
  179. };
  180. if( vkCreateSwapchainKHR(ctx->device, &swapInfo, 0, &ctx->swapchain) != VK_SUCCESS )
  181. return false;
  182. vkGetSwapchainImagesKHR(ctx->device, ctx->swapchain, &outImages->size, NULL);
  183. vkGetSwapchainImagesKHR(ctx->device, ctx->swapchain, &outImages->size, hl_aptr(outImages,void));
  184. *outFormat = format.format;
  185. return true;
  186. }
  187. VkShaderModule HL_NAME(vk_create_shader_module)( VkContext ctx, vbyte *data, int len ) {
  188. VkShaderModule module = NULL;
  189. VkShaderModuleCreateInfo inf = {
  190. .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
  191. .codeSize = len,
  192. .pCode = (const uint32_t*)data,
  193. };
  194. vkCreateShaderModule(ctx->device,&inf,NULL,&module);
  195. return module;
  196. }
  197. VkPipelineLayout HL_NAME(vk_create_pipeline_layout)( VkContext ctx, VkPipelineLayoutCreateInfo *info ) {
  198. VkPipelineLayout p = NULL;
  199. vkCreatePipelineLayout(ctx->device, info, NULL, &p);
  200. return p;
  201. }
  202. VkPipeline HL_NAME(vk_create_graphics_pipeline)( VkContext ctx, VkGraphicsPipelineCreateInfo *info ) {
  203. VkPipeline p = NULL;
  204. vkCreateGraphicsPipelines(ctx->device, NULL, 1, info, NULL, &p);
  205. return p;
  206. }
  207. VkRenderPass HL_NAME(vk_create_render_pass)( VkContext ctx, VkRenderPassCreateInfo *info ) {
  208. VkRenderPass p = NULL;
  209. vkCreateRenderPass(ctx->device, info, NULL, &p);
  210. return p;
  211. }
  212. VkImageView HL_NAME(vk_create_image_view)( VkContext ctx, VkImageViewCreateInfo *info ) {
  213. VkImageView i = NULL;
  214. vkCreateImageView(ctx->device, info, NULL, &i);
  215. return i;
  216. }
  217. VkFramebuffer HL_NAME(vk_create_framebuffer)( VkContext ctx, VkFramebufferCreateInfo *info ) {
  218. VkFramebuffer b = NULL;
  219. vkCreateFramebuffer(ctx->device, info, NULL, &b);
  220. return b;
  221. }
  222. VkDescriptorSetLayout HL_NAME(vk_create_descriptor_set_layout)( VkContext ctx, VkDescriptorSetLayoutCreateInfo *info ) {
  223. VkDescriptorSetLayout p = NULL;
  224. vkCreateDescriptorSetLayout(ctx->device, info, NULL, &p);
  225. return p;
  226. }
  227. VkBuffer HL_NAME(vk_create_buffer)( VkContext ctx, VkBufferCreateInfo *info ) {
  228. VkBuffer b = NULL;
  229. vkCreateBuffer(ctx->device, info, NULL, &b);
  230. return b;
  231. }
  232. void HL_NAME(vk_get_buffer_memory_requirements)( VkContext ctx, VkBuffer buf, VkMemoryRequirements *info ) {
  233. vkGetBufferMemoryRequirements(ctx->device,buf,info);
  234. }
  235. VkDeviceMemory HL_NAME(vk_allocate_memory)( VkContext ctx, VkMemoryAllocateInfo *inf ) {
  236. VkDeviceMemory m = NULL;
  237. vkAllocateMemory(ctx->device, inf, NULL, &m);
  238. return m;
  239. }
  240. vbyte *HL_NAME(vk_map_memory)( VkContext ctx, VkDeviceMemory mem, int offset, int size, int flags ) {
  241. void *ptr = NULL;
  242. vkMapMemory(ctx->device, mem, offset, size, flags, &ptr);
  243. return ptr;
  244. }
  245. void HL_NAME(vk_unmap_memory)( VkContext ctx, VkDeviceMemory mem ) {
  246. vkUnmapMemory(ctx->device, mem);
  247. }
  248. bool HL_NAME(vk_bind_buffer_memory)( VkContext ctx, VkBuffer buf, VkDeviceMemory mem, int offset ) {
  249. return vkBindBufferMemory(ctx->device, buf, mem, offset) == VK_SUCCESS;
  250. }
  251. VkImage HL_NAME(vk_create_image)( VkContext ctx, VkImageCreateInfo *info ) {
  252. VkImage i = NULL;
  253. vkCreateImage(ctx->device, info, NULL, &i);
  254. return i;
  255. }
  256. void HL_NAME(vk_get_image_memory_requirements)( VkContext ctx, VkImage img, VkMemoryRequirements *info ) {
  257. vkGetImageMemoryRequirements(ctx->device,img,info);
  258. }
  259. bool HL_NAME(vk_bind_image_memory)( VkContext ctx, VkImage img, VkDeviceMemory mem, int offset ) {
  260. return vkBindImageMemory(ctx->device, img, mem, offset) == VK_SUCCESS;
  261. }
  262. VkCommandPool HL_NAME(vk_create_command_pool)( VkContext ctx, VkCommandPoolCreateInfo *inf ) {
  263. VkCommandPool pool = NULL;
  264. vkCreateCommandPool(ctx->device,inf,NULL,&pool);
  265. return pool;
  266. }
  267. bool HL_NAME(vk_allocate_command_buffers)( VkContext ctx, VkCommandBufferAllocateInfo *inf, varray *buffers ) {
  268. return vkAllocateCommandBuffers(ctx->device, inf, hl_aptr(buffers,VkCommandBuffer)) == VK_SUCCESS;
  269. }
  270. VkDescriptorPool HL_NAME(vk_create_descriptor_pool)( VkContext ctx, VkDescriptorPoolCreateInfo *inf ) {
  271. VkDescriptorPool pool = NULL;
  272. vkCreateDescriptorPool(ctx->device,inf,NULL,&pool);
  273. return pool;
  274. }
  275. bool HL_NAME(vk_allocate_descriptor_sets)( VkContext ctx, VkDescriptorSetAllocateInfo *inf, varray *sets ) {
  276. return vkAllocateDescriptorSets(ctx->device, inf, hl_aptr(sets,VkDescriptorSet)) == VK_SUCCESS;
  277. }
  278. void HL_NAME(vk_update_descriptor_sets)( VkContext ctx, int writeCount, VkWriteDescriptorSet *write, int copyCount, VkCopyDescriptorSet *copy ) {
  279. vkUpdateDescriptorSets(ctx->device, writeCount, write, copyCount, copy);
  280. }
  281. VkSampler HL_NAME(vk_create_sampler)( VkContext ctx, VkSamplerCreateInfo *inf ) {
  282. VkSampler sampler = NULL;
  283. vkCreateSampler(ctx->device, inf, NULL, &sampler);
  284. return sampler;
  285. }
  286. VkFence HL_NAME(vk_create_fence)( VkContext ctx, VkFenceCreateInfo *inf ) {
  287. VkFence fence = NULL;
  288. vkCreateFence(ctx->device,inf,NULL,&fence);
  289. return fence;
  290. }
  291. VkSemaphore HL_NAME(vk_create_semaphore)( VkContext ctx, VkSemaphoreCreateInfo *inf ) {
  292. VkSemaphore s = NULL;
  293. vkCreateSemaphore(ctx->device,inf,NULL,&s);
  294. return s;
  295. }
  296. void HL_NAME(vk_reset_fence)( VkContext ctx, VkFence f ) {
  297. vkResetFences(ctx->device,1,&f);
  298. }
  299. bool HL_NAME(vk_wait_for_fence)( VkContext ctx, VkFence f, double timeout ) {
  300. uint64_t t = (uint64_t)timeout;
  301. return vkWaitForFences(ctx->device, 1, &f, TRUE, t) == VK_SUCCESS;
  302. }
  303. int HL_NAME(vk_get_next_image_index)( VkContext ctx, VkSemaphore lock ) {
  304. int image = -1;
  305. if( vkAcquireNextImageKHR(ctx->device, ctx->swapchain, UINT64_MAX, lock, VK_NULL_HANDLE, &image) != VK_SUCCESS )
  306. return -1;
  307. return image;
  308. }
  309. void HL_NAME(vk_queue_submit)( VkContext ctx, VkSubmitInfo *inf, VkFence fence ) {
  310. vkQueueSubmit(ctx->queue, 1, inf, fence);
  311. }
  312. void HL_NAME(vk_queue_wait_idle)( VkContext ctx ) {
  313. vkQueueWaitIdle(ctx->queue);
  314. }
  315. void HL_NAME(vk_present)( VkContext ctx, VkSemaphore sem, int image ) {
  316. VkPresentInfoKHR presentInfo = {
  317. .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
  318. .waitSemaphoreCount = 1,
  319. .pWaitSemaphores = &sem,
  320. .swapchainCount = 1,
  321. .pSwapchains = &ctx->swapchain,
  322. .pImageIndices = &image,
  323. };
  324. vkQueuePresentKHR(ctx->queue, &presentInfo);
  325. }
  326. void HL_NAME(vk_destroy_buffer)( VkContext ctx, VkBuffer buf ) {
  327. vkDestroyBuffer(ctx->device, buf, NULL);
  328. }
  329. void HL_NAME(vk_destroy_image)( VkContext ctx, VkImage img ) {
  330. vkDestroyImage(ctx->device, img, NULL);
  331. }
  332. void HL_NAME(vk_destroy_image_view)( VkContext ctx, VkImageView view ) {
  333. vkDestroyImageView(ctx->device, view, NULL);
  334. }
  335. void HL_NAME(vk_free_memory)( VkContext ctx, VkDeviceMemory mem ) {
  336. vkFreeMemory(ctx->device, mem, NULL);
  337. }
  338. void HL_NAME(vk_destroy_fence)( VkContext ctx, VkFence fence ) {
  339. vkDestroyFence(ctx->device, fence, NULL);
  340. }
  341. void HL_NAME(vk_destroy_semaphore)( VkContext ctx, VkSemaphore sem ) {
  342. vkDestroySemaphore(ctx->device, sem, NULL);
  343. }
  344. void HL_NAME(vk_destroy_command_pool)( VkContext ctx, VkCommandPool pool ) {
  345. vkDestroyCommandPool(ctx->device, pool, NULL);
  346. }
  347. void HL_NAME(vk_free_command_buffers)( VkContext ctx, VkCommandPool pool, varray *cmd ) {
  348. vkFreeCommandBuffers(ctx->device, pool, cmd->size, hl_aptr(cmd,VkCommandBuffer));
  349. }
  350. void HL_NAME(vk_destroy_framebuffer)( VkContext ctx, VkFramebuffer fb ) {
  351. vkDestroyFramebuffer(ctx->device, fb, NULL);
  352. }
  353. void HL_NAME(vk_destroy_descriptor_pool)( VkContext ctx, VkDescriptorPool pool ) {
  354. vkDestroyDescriptorPool(ctx->device, pool, NULL);
  355. }
  356. void HL_NAME(vk_destroy_sampler)( VkContext ctx, VkSampler sampler ) {
  357. vkDestroySampler(ctx->device, sampler, NULL);
  358. }
  359. #define _VCTX _ABSTRACT(vk_context)
  360. #define _SHADER_MODULE _ABSTRACT(vk_shader_module)
  361. #define _GPIPELINE _ABSTRACT(vk_gpipeline)
  362. #define _PIPELAYOUT _ABSTRACT(vk_pipeline_layout)
  363. #define _RENDERPASS _ABSTRACT(vk_render_pass)
  364. #define _IMAGE _ABSTRACT(vk_image)
  365. #define _IMAGE_VIEW _ABSTRACT(vk_image_view)
  366. #define _FRAMEBUFFER _ABSTRACT(vk_framebuffer)
  367. #define _DLAYOUT _ABSTRACT(vk_descriptor_layout)
  368. #define _BUFFER _ABSTRACT(vk_buffer)
  369. #define _MEMORY _ABSTRACT(vk_device_memory)
  370. #define _CMD _ABSTRACT(vk_command_buffer)
  371. #define _CMD_POOL _ABSTRACT(vk_command_pool)
  372. #define _FENCE _ABSTRACT(vk_fence)
  373. #define _SEMAPHORE _ABSTRACT(vk_semaphore)
  374. #define _DPOOL _ABSTRACT(vk_descriptor_pool)
  375. #define _DSET _ABSTRACT(vk_descriptor_set)
  376. #define _SAMPLER _ABSTRACT(vk_sampler)
  377. DEFINE_PRIM(_BOOL, vk_init, _BOOL);
  378. DEFINE_PRIM(_VCTX, vk_init_context, _BYTES _REF(_I32));
  379. DEFINE_PRIM(_BOOL, vk_init_swapchain, _VCTX _I32 _I32 _ARR _REF(_I32));
  380. DEFINE_PRIM(_BYTES, vk_make_array, _ARR);
  381. DEFINE_PRIM(_BYTES, vk_make_ref, _DYN);
  382. DEFINE_PRIM(_STRUCT, vk_get_limits, _VCTX);
  383. DEFINE_PRIM(_BYTES, vk_get_device_name, _VCTX);
  384. DEFINE_PRIM(_I32, vk_find_memory_type, _VCTX _I32 _I32);
  385. DEFINE_PRIM(_SHADER_MODULE, vk_create_shader_module, _VCTX _BYTES _I32 );
  386. DEFINE_PRIM(_GPIPELINE, vk_create_graphics_pipeline, _VCTX _STRUCT);
  387. DEFINE_PRIM(_PIPELAYOUT, vk_create_pipeline_layout, _VCTX _STRUCT);
  388. DEFINE_PRIM(_RENDERPASS, vk_create_render_pass, _VCTX _STRUCT);
  389. DEFINE_PRIM(_IMAGE_VIEW, vk_create_image_view, _VCTX _STRUCT);
  390. DEFINE_PRIM(_FENCE, vk_create_fence, _VCTX _STRUCT);
  391. DEFINE_PRIM(_BOOL, vk_wait_for_fence, _VCTX _FENCE _F64);
  392. DEFINE_PRIM(_VOID, vk_reset_fence, _VCTX _FENCE);
  393. DEFINE_PRIM(_CMD_POOL, vk_create_command_pool, _VCTX _STRUCT);
  394. DEFINE_PRIM(_BOOL, vk_allocate_command_buffers, _VCTX _STRUCT _ARR);
  395. DEFINE_PRIM(_FRAMEBUFFER, vk_create_framebuffer, _VCTX _STRUCT);
  396. DEFINE_PRIM(_DLAYOUT, vk_create_descriptor_set_layout, _VCTX _STRUCT);
  397. DEFINE_PRIM(_SAMPLER, vk_create_sampler, _VCTX _STRUCT);
  398. DEFINE_PRIM(_BUFFER, vk_create_buffer, _VCTX _STRUCT);
  399. DEFINE_PRIM(_VOID, vk_get_buffer_memory_requirements, _VCTX _BUFFER _STRUCT);
  400. DEFINE_PRIM(_IMAGE, vk_create_image, _VCTX _STRUCT);
  401. DEFINE_PRIM(_VOID, vk_get_image_memory_requirements, _VCTX _IMAGE _STRUCT);
  402. DEFINE_PRIM(_BOOL, vk_bind_image_memory, _VCTX _IMAGE _MEMORY _I32);
  403. DEFINE_PRIM(_MEMORY, vk_allocate_memory, _VCTX _STRUCT);
  404. DEFINE_PRIM(_BYTES, vk_map_memory, _VCTX _MEMORY _I32 _I32 _I32);
  405. DEFINE_PRIM(_VOID, vk_unmap_memory, _VCTX _MEMORY);
  406. DEFINE_PRIM(_BOOL, vk_bind_buffer_memory, _VCTX _BUFFER _MEMORY _I32);
  407. DEFINE_PRIM(_SEMAPHORE, vk_create_semaphore, _VCTX _STRUCT);
  408. DEFINE_PRIM(_I32, vk_get_next_image_index, _VCTX _SEMAPHORE);
  409. DEFINE_PRIM(_VOID, vk_queue_submit, _VCTX _STRUCT _FENCE);
  410. DEFINE_PRIM(_VOID, vk_queue_wait_idle, _VCTX);
  411. DEFINE_PRIM(_VOID, vk_present, _VCTX _SEMAPHORE _I32);
  412. DEFINE_PRIM(_VOID, vk_get_pdevice_format_props, _VCTX _I32 _STRUCT);
  413. DEFINE_PRIM(_DPOOL, vk_create_descriptor_pool, _VCTX _STRUCT);
  414. DEFINE_PRIM(_BOOL, vk_allocate_descriptor_sets, _VCTX _STRUCT _ARR);
  415. DEFINE_PRIM(_VOID, vk_update_descriptor_sets, _VCTX _I32 _BYTES _I32 _BYTES);
  416. DEFINE_PRIM(_VOID, vk_destroy_image, _VCTX _IMAGE);
  417. DEFINE_PRIM(_VOID, vk_destroy_image_view, _VCTX _IMAGE_VIEW);
  418. DEFINE_PRIM(_VOID, vk_destroy_framebuffer, _VCTX _FRAMEBUFFER);
  419. DEFINE_PRIM(_VOID, vk_free_command_buffers, _VCTX _CMD_POOL _ARR);
  420. DEFINE_PRIM(_VOID, vk_destroy_command_pool, _VCTX _CMD_POOL);
  421. DEFINE_PRIM(_VOID, vk_destroy_buffer, _VCTX _BUFFER);
  422. DEFINE_PRIM(_VOID, vk_destroy_fence, _VCTX _FENCE);
  423. DEFINE_PRIM(_VOID, vk_destroy_semaphore, _VCTX _SEMAPHORE);
  424. DEFINE_PRIM(_VOID, vk_free_memory, _VCTX _MEMORY);
  425. DEFINE_PRIM(_VOID, vk_destroy_descriptor_pool, _VCTX _DPOOL);
  426. DEFINE_PRIM(_VOID, vk_destroy_sampler, _VCTX _SAMPLER);
  427. // ------ COMMAND BUFFER OPERATIONS -----------------------
  428. HL_PRIM void HL_NAME(vk_command_begin)( VkCommandBuffer out, VkCommandBufferBeginInfo *inf ) {
  429. vkBeginCommandBuffer(out,inf);
  430. }
  431. HL_PRIM void HL_NAME(vk_command_end)( VkCommandBuffer out ) {
  432. vkEndCommandBuffer(out);
  433. }
  434. HL_PRIM void HL_NAME(vk_clear_color_image)( VkCommandBuffer out, VkImage img, VkImageLayout layout, VkClearColorValue *colors, int count, VkImageSubresourceRange *range) {
  435. vkCmdClearColorImage(out, img, layout, colors, count, range);
  436. }
  437. HL_PRIM void HL_NAME(vk_clear_attachments)( VkCommandBuffer out, int count, VkClearAttachment *attachs, int rectCount, VkClearRect *rects ) {
  438. vkCmdClearAttachments(out, count, attachs, rectCount, rects);
  439. }
  440. HL_PRIM void HL_NAME(vk_clear_depth_stencil_image)( VkCommandBuffer out, VkImage img, VkImageLayout layout, VkClearDepthStencilValue *values, int count, VkImageSubresourceRange *range) {
  441. vkCmdClearDepthStencilImage(out, img, layout, values, count, range);
  442. }
  443. HL_PRIM void HL_NAME(vk_draw_indexed)( VkCommandBuffer out, int indexCount, int instanceCount, int firstIndex, int vertexOffset, int firstInstance ) {
  444. vkCmdDrawIndexed(out,indexCount,instanceCount,firstIndex,vertexOffset,firstInstance);
  445. }
  446. HL_PRIM void HL_NAME(vk_bind_pipeline)( VkCommandBuffer out, int bindPoint, VkPipeline pipeline ) {
  447. vkCmdBindPipeline(out, (VkPipelineBindPoint)bindPoint, pipeline);
  448. }
  449. HL_PRIM void HL_NAME(vk_begin_render_pass)( VkCommandBuffer out, VkRenderPassBeginInfo *info, int contents ) {
  450. vkCmdBeginRenderPass(out, info, (VkSubpassContents)contents);
  451. }
  452. HL_PRIM void HL_NAME(vk_bind_index_buffer)( VkCommandBuffer out, VkBuffer buf, int offset, int type ) {
  453. vkCmdBindIndexBuffer(out, buf, offset, type);
  454. }
  455. HL_PRIM void HL_NAME(vk_bind_vertex_buffers)( VkCommandBuffer out, int first, int count, VkBuffer *buffers, VkDeviceSize *sizes ) {
  456. vkCmdBindVertexBuffers(out, first, count, buffers, sizes);
  457. }
  458. HL_PRIM void HL_NAME(vk_end_render_pass)( VkCommandBuffer out ) {
  459. vkCmdEndRenderPass(out);
  460. }
  461. HL_PRIM void HL_NAME(vk_push_constants)( VkCommandBuffer out, VkPipelineLayout layout, VkShaderStageFlags flags, int offset, int size, vbyte *data ) {
  462. vkCmdPushConstants(out, layout, flags, offset, size, data);
  463. }
  464. HL_PRIM void HL_NAME(vk_copy_buffer_to_image)( VkCommandBuffer out, VkBuffer buf, VkImage img, VkImageLayout layout, int count, VkBufferImageCopy *regions ) {
  465. vkCmdCopyBufferToImage(out, buf, img, layout, count, regions);
  466. }
  467. HL_PRIM void HL_NAME(vk_pipeline_barrier)( VkCommandBuffer out, VkPipelineStageFlags srcMask, VkPipelineStageFlags dstMask, VkDependencyFlags flags, int memCount, VkMemoryBarrier *memBarriers, int bufferCount, VkBufferMemoryBarrier *bufBarriers, int imageCount, VkImageMemoryBarrier *imgBarriers ) {
  468. vkCmdPipelineBarrier(out, srcMask, dstMask, flags, memCount, memBarriers, bufferCount, bufBarriers, imageCount, imgBarriers);
  469. }
  470. HL_PRIM void HL_NAME(vk_bind_descriptor_sets)( VkCommandBuffer out, VkPipelineBindPoint bind, VkPipelineLayout layout, int first, int count, VkDescriptorSet *sets, int offsetCount, int *offsets ) {
  471. vkCmdBindDescriptorSets(out, bind, layout, first, count, sets, offsetCount, offsets);
  472. }
  473. DEFINE_PRIM(_VOID, vk_command_begin, _CMD _STRUCT);
  474. DEFINE_PRIM(_VOID, vk_command_end, _CMD);
  475. DEFINE_PRIM(_VOID, vk_clear_color_image, _CMD _IMAGE _I32 _BYTES _I32 _STRUCT);
  476. DEFINE_PRIM(_VOID, vk_clear_depth_stencil_image, _CMD _IMAGE _I32 _BYTES _I32 _STRUCT);
  477. DEFINE_PRIM(_VOID, vk_clear_attachments, _CMD _I32 _BYTES _I32 _BYTES);
  478. DEFINE_PRIM(_VOID, vk_draw_indexed, _CMD _I32 _I32 _I32 _I32 _I32);
  479. DEFINE_PRIM(_VOID, vk_bind_pipeline, _CMD _I32 _GPIPELINE);
  480. DEFINE_PRIM(_VOID, vk_begin_render_pass, _CMD _STRUCT _I32);
  481. DEFINE_PRIM(_VOID, vk_bind_index_buffer, _CMD _BUFFER _I32 _I32);
  482. DEFINE_PRIM(_VOID, vk_bind_vertex_buffers, _CMD _I32 _I32 _BYTES _BYTES);
  483. DEFINE_PRIM(_VOID, vk_push_constants, _CMD _PIPELAYOUT _I32 _I32 _I32 _BYTES);
  484. DEFINE_PRIM(_VOID, vk_end_render_pass, _CMD);
  485. DEFINE_PRIM(_VOID, vk_copy_buffer_to_image, _CMD _BUFFER _IMAGE _I32 _I32 _BYTES);
  486. DEFINE_PRIM(_VOID, vk_pipeline_barrier, _CMD _I32 _I32 _I32 _I32 _BYTES _I32 _BYTES _I32 _BYTES);
  487. DEFINE_PRIM(_VOID, vk_bind_descriptor_sets, _CMD _I32 _PIPELAYOUT _I32 _I32 _BYTES _I32 _BYTES);
  488. // ------ SHADER COMPILATION ------------------------------
  489. HL_PRIM vbyte *HL_NAME(vk_compile_shader)( vbyte *source, vbyte *shaderFile, vbyte *mainFunction, int shaderKind, int *outSize ) {
  490. shaderc_compiler_t compiler = shaderc_compiler_initialize();
  491. shaderc_compile_options_t opts = shaderc_compile_options_initialize();
  492. shaderc_compile_options_set_optimization_level(opts, shaderc_optimization_level_size);
  493. shaderc_compilation_result_t result = shaderc_compile_into_spv(compiler, source, strlen(source), shaderKind, shaderFile, mainFunction, opts);
  494. shaderc_compiler_release(compiler);
  495. shaderc_compile_options_release(opts);
  496. if( shaderc_result_get_compilation_status(result) != shaderc_compilation_status_success ) {
  497. const char *str = shaderc_result_get_error_message(result);
  498. vbyte *error = hl_copy_bytes(str, (int)strlen(str)+1);
  499. shaderc_result_release(result);
  500. *outSize = -1;
  501. return error;
  502. }
  503. int size = (int)shaderc_result_get_length(result);
  504. vbyte *data = hl_alloc_bytes(size);
  505. memcpy(data, shaderc_result_get_bytes(result), size);
  506. shaderc_result_release(result);
  507. *outSize = size;
  508. return data;
  509. }
  510. DEFINE_PRIM(_BYTES, vk_compile_shader, _BYTES _BYTES _BYTES _I32 _REF(_I32));