From 296b4bf2b7c4fcc7d9c19381840c62e8b891934f Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sun, 14 Aug 2022 07:34:51 +0300 Subject: [PATCH] framebuffers --- src/vk.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/vk.h | 8 +++ 2 files changed, 168 insertions(+), 14 deletions(-) diff --git a/src/vk.c b/src/vk.c index 0749f07..ca03b35 100644 --- a/src/vk.c +++ b/src/vk.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "vk.h" #include "util.h" @@ -14,6 +15,39 @@ #include #endif +struct rpass { + int used; + int fmt; + int zfmt; + int num_colbuf; + int num_samples; + int clear; + + int vkobj_valid; + VkRenderPass vkobj; +}; + +#define MAX_FB_IMGV 8 +struct framebuf { + int used; + int width, height; + + /* if rpasses[rpidx].vkobj != vkrpass, the framebuf is invalid */ + int rpidx; + VkRenderPass vkrpass; + + VkImageView imgv[MAX_FB_IMGV]; + int num_imgv; + + int vkobj_valid; + VkFramebuffer vkobj; +}; + + +static struct rpass *rpasses; +static struct framebuf *framebufs; + + static int create_instance(void); static int create_surface(void); static int choose_phys_dev(void); @@ -142,20 +176,6 @@ int vk_reshape(int xsz, int ysz) return 0; } -struct rpass { - int used; - int fmt; - int zfmt; - int num_colbuf; - int num_samples; - /* TODO: stuff about depth-stencil */ - int clear; - - int vkobj_valid; - VkRenderPass vkobj; -}; - -static struct rpass *rpasses; int vk_create_rpass(void) { @@ -212,11 +232,13 @@ void vk_rpass_colorbuf(int rp, int fmt, int n) void vk_rpass_msaa(int rp, int nsamp) { rpasses[rp].num_samples = nsamp; + rpasses[rp].vkobj_valid = 0; } void vk_rpass_clear(int rp, int clear) { rpasses[rp].clear = clear; + rpasses[rp].vkobj_valid = 0; } VkRenderPass vk_rpass(int rp) @@ -231,6 +253,11 @@ VkRenderPass vk_rpass(int rp) r = rpasses + rp; if(!r->vkobj_valid) { + if(r->vkobj) { + vkDestroyRenderPass(vkdev, r->vkobj, 0); + r->vkobj = 0; + } + zidx = r->num_colbuf; memset(att, 0, sizeof att); for(i=0; inum_colbuf; i++) { @@ -282,6 +309,125 @@ VkRenderPass vk_rpass(int rp) return r->vkobj; } + +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; iused = 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; irpidx))) { + 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; +} + + #define ARRSZ(arr) (sizeof arr / sizeof *arr) static const char *known_layer_list[] = { "VK_LAYER_GOOGLE_threading", diff --git a/src/vk.h b/src/vk.h index 3322f14..470f757 100644 --- a/src/vk.h +++ b/src/vk.h @@ -24,5 +24,13 @@ void vk_rpass_msaa(int rp, int nsamp); void vk_rpass_clear(int rp, int clear); VkRenderPass vk_rpass(int rp); +int vk_create_fb(void); +void vk_free_fb(int fb); +void vk_fb_size(int fb, int x, int y); +void vk_fb_rpass(int fb, int rpass); +void vk_fb_images(int fb, int n, ...); +VkFramebuffer vk_fb(int fb); + + #endif /* VK_H_ */ -- 1.7.10.4