+VkShaderModule vk_load_shader(const char *fname)
+{
+ FILE *fp;
+ long sz;
+ void *buf;
+ VkShaderModuleCreateInfo sinf;
+ VkShaderModule sdr;
+
+ if(!(fp = fopen(fname, "rb"))) {
+ fprintf(stderr, "failed to open shader: %s: %s\n", fname, strerror(errno));
+ return 0;
+ }
+ fseek(fp, 0, SEEK_END);
+ sz = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ buf = alloca(sz);
+ if(fread(buf, 1, sz, fp) < sz) {
+ fprintf(stderr, "unexpected EOF while reading shader: %s\n", fname);
+ fclose(fp);
+ return 0;
+ }
+ fclose(fp);
+
+ memset(&sinf, 0, sizeof sinf);
+ sinf.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+ sinf.codeSize = sz;
+ sinf.pCode = buf;
+
+ if(vkCreateShaderModule(vkdev, &sinf, 0, &sdr) != 0) {
+ fprintf(stderr, "failed to create shader from %s\n", fname);
+ return 0;
+ }
+ return sdr;
+}
+
+void vk_free_shader(VkShaderModule sdr)
+{
+ vkDestroyShaderModule(vkdev, sdr, 0);
+}
+
+VkSemaphore vk_create_sem(void)
+{
+ VkSemaphore sem;
+ VkSemaphoreCreateInfo sinf = {0};
+
+ sinf.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+ if(vkCreateSemaphore(vkdev, &sinf, 0, &sem) != 0) {
+ return 0;
+ }
+ return sem;
+}
+
+void vk_free_sem(VkSemaphore sem)
+{
+ vkDestroySemaphore(vkdev, sem, 0);
+}
+