#include "app.h"
#include "vk.h"
+struct swapchain {
+ int fb;
+ VkImageView img;
+ VkSemaphore sem_getimg;
+ VkFence imgfence;
+};
+
int win_width, win_height;
-static int rpass, pipeln, *fb, num_swap_img;
-static VkSemaphore sem_getimg, sem_draw;
+static int rpass, pipeln, num_swap_img;
+static struct swapchain *swapchain;
+static VkSemaphore sem_draw;
static VkQueue queue;
int app_init(void)
if((num_swap_img = vk_num_swap_images()) <= 0) {
return -1;
}
- if(!(fb = malloc(num_swap_img * sizeof *fb))) {
+ if(!(swapchain = malloc(num_swap_img * sizeof *swapchain))) {
return -1;
}
rpass = vk_create_rpass();
for(i=0; i<num_swap_img; i++) {
- fb[i] = vk_create_fb();
- vk_fb_size(fb[i], win_width, win_height);
- vk_fb_rpass(fb[i], rpass);
- vk_fb_images(fb[i], 1, vk_swap_image(i));
+ swapchain[i].img = vk_swap_image(i);
+ swapchain[i].fb = vk_create_fb();
+ vk_fb_size(swapchain[i].fb, win_width, win_height);
+ vk_fb_rpass(swapchain[i].fb, rpass);
+ vk_fb_images(swapchain[i].fb, 1, swapchain[i].img);
+
+ swapchain[i].sem_getimg = vk_create_sem();
+ swapchain[i].imgfence = vk_create_fence();
}
pipeln = vk_create_pipeln();
vk_pipeln_rpass(pipeln, vk_rpass(rpass));
vk_pipeln_viewport(pipeln, 0, 0, win_width, win_height);
- sem_getimg = vk_create_sem();
sem_draw = vk_create_sem();
return 0;
}
void app_cleanup(void)
{
- vk_free_sem(sem_getimg);
+ int i;
+ for(i=0; i<num_swap_img; i++) {
+ vk_free_fence(swapchain[i].imgfence);
+ vk_free_sem(swapchain[i].sem_getimg);
+ }
vk_free_sem(sem_draw);
vk_cleanup();
}
void app_display(void)
{
+ static int semid = -1;
int imgid;
VkCommandBuffer cmdbuf;
/* get the next image from the swap chain */
- imgid = vk_next_swap_image(sem_getimg);
+ semid = (semid + 1) % num_swap_img;
+ imgid = vk_next_swap_image(swapchain[semid].sem_getimg);
cmdbuf = vk_get_cmdbuf(imgid);
{
rpbegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rpbegin.renderPass = vk_rpass(rpass);
- rpbegin.framebuffer = vk_fb(fb[imgid]);
+ rpbegin.framebuffer = vk_fb(swapchain[imgid].fb);
vk_rect(&rpbegin.renderArea, 0, 0, win_width, win_height);
rpbegin.pClearValues = clear;
rpbegin.clearValueCount = 1;
}
/* submit the command buffer, wait for one semaphore, signal another */
- vk_submit(queue, cmdbuf, sem_getimg, sem_draw);
+ vk_submit(queue, cmdbuf, swapchain[semid].sem_getimg, sem_draw);
/* swap buffers after drawing is finished */
vk_present(queue, imgid, sem_draw);
{
int i;
- return; /* XXX */
-
if(vk_reshape(x, y) == -1) {
abort();
}
for(i=0; i<vk_num_swap_images(); i++) {
- vk_fb_size(fb[i], x, y);
- vk_fb_images(fb[i], 1, vk_swap_image(i));
+ vk_fb_size(swapchain[i].fb, x, y);
+ vk_fb_images(swapchain[i].fb, 1, vk_swap_image(i));
}
}
int vk_next_swap_image(VkSemaphore sem)
{
uint32_t idx;
- if(vkAcquireNextImageKHR(vkdev, vksc, UINT64_MAX, sem, 0, &idx) != 0) {
- return -1;
+ VkResult res = vkAcquireNextImageKHR(vkdev, vksc, UINT64_MAX, sem, 0, &idx);
+ if(res == VK_SUCCESS || res == VK_SUBOPTIMAL_KHR) {
+ return (int)idx;
}
- return (int)idx;
+ return -1;
}
int vk_submit(VkQueue q, VkCommandBuffer cmdbuf, VkSemaphore semwait, VkSemaphore semsig)
vkDestroySemaphore(vkdev, sem, 0);
}
+VkFence vk_create_fence(void)
+{
+ VkFence fence;
+ VkFenceCreateInfo finf = {0};
+
+ finf.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+ if(vkCreateFence(vkdev, &finf, 0, &fence) != 0) {
+ return 0;
+ }
+ return fence;
+}
+
+void vk_free_fence(VkFence fence)
+{
+ vkDestroyFence(vkdev, fence, 0);
+}
void vk_rect(VkRect2D *r, int x, int y, int w, int h)
{