foo
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 10 Jan 2023 11:50:31 +0000 (13:50 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 10 Jan 2023 11:50:31 +0000 (13:50 +0200)
src/app.c
src/vk.c
src/vk.h

index 044a885..9a72309 100644 (file)
--- a/src/app.c
+++ b/src/app.c
@@ -3,6 +3,8 @@
 #include "app.h"
 #include "vk.h"
 
+static VkSemaphore sem_getimg;
+
 int app_init(void)
 {
        unsigned int flags;
@@ -10,17 +12,36 @@ int app_init(void)
        if(vk_init(VKINIT_DEPTH, &flags) == -1) {
                return -1;
        }
+
+       sem_getimg = vk_create_sem();
+       sem_draw = vk_create_sem();
        return 0;
 }
 
 void app_cleanup(void)
 {
+       vk_free_sem(sem_getimg);
+       vk_free_sem(sem_draw);
        vk_cleanup();
 }
 
 
 void app_display(void)
 {
+       int imgid;
+       VkCommandBuffer cmdbuf;
+
+       /* get the next image from the swap chain */
+       imgid = vk_next_image(sem_getimg);
+       cmdbuf = vk_get_cmdbuf(imgid);
+
+       /* TODO record */
+
+       /* submit the command buffer, wait for one semaphore, signal another */
+       vk_submit(cmdbuf, sem_getimg, sem_draw);
+
+       /* swap buffers after drawing is finished */
+       vk_present(sem_draw);
 }
 
 void app_reshape(int x, int y)
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)
 {
index f4187d3..cc58948 100644 (file)
--- a/src/vk.h
+++ b/src/vk.h
@@ -57,6 +57,9 @@ void vk_cleanup(void);
 
 int vk_reshape(int xsz, int ysz);
 
+/* returns the image index, or -1 on failure. Pass optional semaphore to signal */
+int vk_next_image(VkSemaphore sem);
+
 int vk_find_qfamily(unsigned int flags);
 VkQueue vk_getq_fam(int fam, int n);
 VkQueue vk_getq(unsigned int flags, int n);
@@ -103,4 +106,11 @@ void vk_pipeln_blend(int pp, int enable);
 void vk_pipeln_blendfunc(int pp, int src, int dst);
 VkPipeline vk_pipeln(int pp);
 
+VkShaderModule vk_load_shader(const char *fname);
+void vk_free_shader(VkShaderModule sdr);
+
+VkSemaphore vk_create_sem(void);
+void vk_free_sem(VkSemaphore sem);
+
+
 #endif /* VK_H_ */