+
+int vk_create_fb(void)
+{
+ int i;
+ struct framebuf framebuf = {0}, *fb = &framebuf;
+
+ if(!framebufs) {
+ framebufs = darr_alloc(0, sizeof *framebufs);
+ darr_push(framebufs, &framebuf); /* add dummy rpass */
+ }
+
+ for(i=1; i<darr_size(framebufs); i++) {
+ if(!framebufs[i].used) {
+ fb = framebufs + i;
+ }
+ }
+
+ /* init framebuffer defaults */
+ memset(fb, 0, sizeof &fb);
+ fb->used = 1;
+
+ if(fb == &framebuf) {
+ darr_push(framebufs, fb);
+ return darr_size(framebufs) - 1;
+ }
+ return fb - framebufs;
+}
+
+void vk_free_fb(int fb)
+{
+ if(!framebufs || fb < 1 || fb >= darr_size(framebufs)) {
+ return;
+ }
+
+ if(framebufs[fb].used && framebufs[fb].vkobj) {
+ vkDestroyFramebuffer(vkdev, framebufs[fb].vkobj, 0);
+ }
+ framebufs[fb].used = 0;
+}
+
+void vk_fb_size(int fb, int x, int y)
+{
+ framebufs[fb].width = x;
+ framebufs[fb].height = y;
+ framebufs[fb].vkobj_valid = 0;
+}
+
+void vk_fb_rpass(int fb, int rpass)
+{
+ if(rpass < 0 || rpass >= darr_size(rpasses) || !rpasses[rpass].used) {
+ fprintf(stderr, "vk_fb_rpass: %d is not a valid renderpass\n", rpass);
+ return;
+ }
+
+ framebufs[fb].rpidx = rpass;
+ if(rpasses[rpass].vkobj_valid) {
+ framebufs[fb].vkrpass = rpasses[rpass].vkobj;
+ } else {
+ framebufs[fb].vkrpass = 0;
+ }
+ framebufs[fb].vkobj_valid = 0;
+}
+
+void vk_fb_images(int fb, int n, ...)
+{
+ int i;
+ va_list ap;
+
+ if(n > MAX_FB_IMGV) {
+ fprintf(stderr, "vk_fb_images: %d is too many images\n", n);
+ n = MAX_FB_IMGV;
+ }
+
+ va_start(ap, n);
+ for(i=0; i<n; i++) {
+ framebufs[fb].imgv[i] = va_arg(ap, VkImageView);
+ }
+ va_end(ap);
+ framebufs[fb].num_imgv = n;
+ framebufs[fb].vkobj_valid = 0;
+}
+
+VkFramebuffer vk_fb(int fb)
+{
+ VkFramebufferCreateInfo fbinf;
+ VkRenderPass rpass;
+ struct framebuf *f;
+
+ f = framebufs + fb;
+
+ if(!(rpass = vk_rpass(f->rpidx))) {
+ return 0;
+ }
+
+ if(rpass != f->vkrpass || !f->vkobj_valid) {
+ f->vkrpass = rpass;
+ if(f->vkobj) {
+ vkDestroyFramebuffer(vkdev, f->vkobj, 0);
+ f->vkobj = 0;
+ }
+
+ memset(&fbinf, 0, sizeof fbinf);
+ fbinf.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+ fbinf.renderPass = rpass;
+ fbinf.attachmentCount = f->num_imgv;
+ fbinf.pAttachments = f->imgv;
+ fbinf.width = f->width;
+ fbinf.height = f->height;
+
+ if(vkCreateFramebuffer(vkdev, &fbinf, 0, &f->vkobj) != 0) {
+ fprintf(stderr, "vk_fb: failed to create framebuffer\n");
+ return 0;
+ }
+ f->vkobj_valid = 1;
+ }
+ return f->vkobj;
+}
+
+