#include "app.h"
#include "vk.h"
+static VkSemaphore sem_getimg;
+
int app_init(void)
{
unsigned int flags;
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)
#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"
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);
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;
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;
}
+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",
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)
{
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);
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_ */