foo
[vktest3] / src / vk.c
index 8b12108..ebc31ae 100644 (file)
--- a/src/vk.c
+++ b/src/vk.c
@@ -2,6 +2,8 @@
 #include <string.h>
 #include <stdint.h>
 #include <stdarg.h>
+#include <errno.h>
+#include <assert.h>
 #include <vulkan/vulkan.h>
 #include "vk.h"
 #include "util.h"
@@ -81,6 +83,7 @@ static int create_surface(void);
 static int choose_phys_dev(void);
 static int create_device(void);
 static int create_swapchain(void);
+static int create_default_cmdbuf(void);
 
 static int choose_pixfmt(void);
 static int eval_pdev_score(VkPhysicalDevice dev);
@@ -113,6 +116,7 @@ static int vksc_numimg;
 static VkImage *vksc_img;
 static VkExtent2D vksc_extent;
 static VkImageView *vksc_view;
+static VkCommandBuffer *vksc_cmdbuf;   /* default command buffers (vksc_numimg) */
 
 static VkLayerProperties *inst_layers;
 static VkExtensionProperties *inst_ext, *dev_ext;
@@ -232,10 +236,23 @@ int vk_reshape(int xsz, int ysz)
 
        if(create_swapchain() == -1) return -1;
 
+       if(!vksc_cmdbuf) {
+               if(create_default_cmdbuf() == -1) return -1;
+       }
+
        /* TODO create depth/stencil buffers as needed (initflags) */
        return 0;
 }
 
+int vk_next_image(VkSemaphore sem)
+{
+       uint32_t idx;
+       if(vkAcquireNextImageKHR(vkdev, vksc, UINT64_MAX, sem, 0, &idx) != 0) {
+               return -1;
+       }
+       return (int)idx;
+}
+
 int vk_find_qfamily(unsigned int flags)
 {
        int i, famidx = -1;
@@ -931,6 +948,64 @@ VkPipeline vk_pipeln(int pp)
 }
 
 
+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);
+}
+
 #define ARRSZ(arr)     (sizeof arr / sizeof *arr)
 static const char *known_layer_list[] = {
        "VK_LAYER_GOOGLE_threading",
@@ -1244,6 +1319,38 @@ static int create_swapchain(void)
        return 0;
 }
 
+static int create_default_cmdbuf(void)
+{
+       int i, qfam;
+       VkCommandPool cmdpool;
+       VkCommandBufferAllocateInfo cbinf = {0};
+
+       assert(!vksc_cmdbuf);
+
+       if((qfam = vk_find_qfamily(VKQ_GFX | VKQ_PRESENT)) == -1) {
+               fprintf(stderr, "failed to find a gfx|present capable queue family\n");
+               return -1;
+       }
+       if(!(cmdpool = find_cmdpool(qfam))) {
+               fprintf(stderr, "failed to find usable command pool for default command buffers\n");
+               return -1;
+       }
+       if(!(vksc_cmdbuf = malloc(vksc_numimg * sizeof *vksc_cmdbuf))) {
+               fprintf(stderr, "failed to allocate %d command buffers for the swap-chain\n", vksc_numimg);
+               return -1;
+       }
+
+       cbinf.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+       cbinf.commandPool = cmdpool;
+       cbinf.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+       cbinf.commandBufferCount = vksc_numimg;
+
+       if(vkAllocateCommandBuffers(vkdev, &cbinf, vksc_cmdbuf) != 0) {
+               fprintf(stderr, "failed to create %d command buffers for the swap-chain\n", vksc_numimg);
+               return -1;
+       }
+       return 0;
+}
 
 static int eval_pdev_score(VkPhysicalDevice dev)
 {