int win_width, win_height;
-static int rpass, pipeln, fb;
+static int rpass, pipeln, *fb, num_swap_img;
static VkSemaphore sem_getimg, sem_draw;
static VkQueue queue;
int app_init(void)
{
+ int i;
unsigned int flags;
if(vk_init(VKINIT_DEPTH, &flags) == -1) {
return -1;
}
+ /* force swapchain creation, to find out how many framebuffers to create */
+ vk_reshape(win_width, win_height);
+ if((num_swap_img = vk_num_swap_images()) <= 0) {
+ return -1;
+ }
+ if(!(fb = malloc(num_swap_img * sizeof *fb))) {
+ return -1;
+ }
+
rpass = vk_create_rpass();
- fb = vk_create_fb();
- vk_fb_size(fb, win_width, win_height);
- vk_fb_rpass(fb, 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));
+ }
pipeln = vk_create_pipeln();
- vk_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();
VkCommandBuffer cmdbuf;
/* get the next image from the swap chain */
- imgid = vk_next_image(sem_getimg);
+ imgid = vk_next_swap_image(sem_getimg);
cmdbuf = vk_get_cmdbuf(imgid);
{
VkCommandBufferBeginInfo cmdbegin = {0};
VkRenderPassBeginInfo rpbegin = {0};
- VkClearValue clear;
+ VkClearValue clear[2];
cmdbegin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdbegin.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
abort();
}
- clear.color.float32[0] = 0.5f;
- clear.color.float32[1] = 0.1f;
- clear.color.float32[2] = 0.2f;
- clear.color.float32[3] = 1.0f;
+ clear[0].color.float32[0] = 0.5f;
+ clear[0].color.float32[1] = 0.1f;
+ clear[0].color.float32[2] = 0.2f;
+ clear[0].color.float32[3] = 1.0f;
+ clear[1].depthStencil.depth = 1.0f;
+ clear[1].depthStencil.stencil = 0;
rpbegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
- rpbegin.renderPass =
+ rpbegin.renderPass = vk_rpass(rpass);
+ rpbegin.framebuffer = vk_fb(fb[imgid]);
+ vk_rect(&rpbegin.renderArea, 0, 0, win_width, win_height);
+ rpbegin.pClearValues = clear;
+ rpbegin.clearValueCount = 2;
+
+ vkCmdBeginRenderPass(cmdbuf, &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
+
+ /* ... */
+
+ vkCmdEndRenderPass(cmdbuf);
+ vkEndCommandBuffer(cmdbuf);
}
/* submit the command buffer, wait for one semaphore, signal another */
void app_reshape(int x, int y)
{
+ int i;
+
if(vk_reshape(x, y) == -1) {
abort();
}
+
+ for(i=0; i<vk_num_swap_images(); i++) {
+ vk_fb_size(fb[i], x, y);
+ }
}
void app_keyboard(int key, int press)
return 0;
}
-int vk_next_image(VkSemaphore sem)
+int vk_num_swap_images(void)
+{
+ return vksc_numimg;
+}
+
+VkImageView vk_swap_image(int idx)
+{
+ return vksc_view[idx];
+}
+
+int vk_next_swap_image(VkSemaphore sem)
{
uint32_t idx;
if(vkAcquireNextImageKHR(vkdev, vksc, UINT64_MAX, sem, 0, &idx) != 0) {
void vk_fb_size(int fb, int x, int y)
{
- framebufs[fb].width = x;
- framebufs[fb].height = y;
- framebufs[fb].vkobj_valid = 0;
+ if(x != framebufs[fb].width || y != framebufs[fb].height) {
+ framebufs[fb].width = x;
+ framebufs[fb].height = y;
+ framebufs[fb].vkobj_valid = 0;
+ }
}
void vk_fb_rpass(int fb, int rpass)
vkDestroySemaphore(vkdev, sem, 0);
}
+
+void vk_rect(VkRect2D *r, int x, int y, int w, int h)
+{
+ r->offset.x = x;
+ r->offset.y = y;
+ r->extent.width = w;
+ r->extent.height = h;
+}
+
+
#define ARRSZ(arr) (sizeof arr / sizeof *arr)
static const char *known_layer_list[] = {
"VK_LAYER_GOOGLE_threading",
int vk_reshape(int xsz, int ysz);
+/* returns the number of swapchain images */
+int vk_num_swap_images(void);
+VkImageView vk_swap_image(int idx);
/* returns the image index, or -1 on failure. Pass optional semaphore to signal */
-int vk_next_image(VkSemaphore sem);
+int vk_next_swap_image(VkSemaphore sem);
int vk_submit(VkQueue q, VkCommandBuffer cmdbuf, VkSemaphore semwait, VkSemaphore semsig);
int vk_present(VkQueue q, int imgid, VkSemaphore semwait);
VkSemaphore vk_create_sem(void);
void vk_free_sem(VkSemaphore sem);
+/* random helpers */
+void vk_rect(VkRect2D *r, int x, int y, int w, int h);
#endif /* VK_H_ */