diff --git a/include/QF/Vulkan/render.h b/include/QF/Vulkan/render.h index b5c590c1c..9cfecdafe 100644 --- a/include/QF/Vulkan/render.h +++ b/include/QF/Vulkan/render.h @@ -89,6 +89,7 @@ typedef struct qfv_attachmentinfo_s { VkImageLayout initialLayout; VkImageLayout finalLayout; VkClearValue clearValue; + qfv_reference_t view; } qfv_attachmentinfo_t; typedef struct qfv_taskinfo_s { @@ -257,6 +258,8 @@ typedef struct qfv_renderctx_s { void QFV_RunRenderPass (qfv_renderpass_t_ *rp, struct vulkan_ctx_s *ctx); void QFV_LoadRenderInfo (struct vulkan_ctx_s *ctx); void QFV_BuildRender (struct vulkan_ctx_s *ctx); +void QFV_CreateFramebuffer (struct vulkan_ctx_s *ctx); +void QFV_DestroyFramebuffer (struct vulkan_ctx_s *ctx); void QFV_Render_Init (struct vulkan_ctx_s *ctx); void QFV_Render_Shutdown (struct vulkan_ctx_s *ctx); void QFV_Render_AddTasks (struct vulkan_ctx_s *ctx, exprsym_t *task_sys); diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index 25ada2b43..419636f46 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -118,6 +118,7 @@ vulkan_R_Init (void) QFV_LoadRenderInfo (vulkan_ctx); QFV_BuildRender (vulkan_ctx); + QFV_CreateFramebuffer (vulkan_ctx); Skin_Init (); diff --git a/libs/video/renderer/vulkan/render.c b/libs/video/renderer/vulkan/render.c index cb7936ce7..8bb8fe073 100644 --- a/libs/video/renderer/vulkan/render.c +++ b/libs/video/renderer/vulkan/render.c @@ -837,6 +837,80 @@ QFV_BuildRender (vulkan_ctx_t *ctx) create_renderpasses (ctx, &counts); } +static VkImageView +find_view (qfv_reference_t *ref, qfv_renderctx_t *rctx) +{ + __auto_type rinfo = rctx->renderinfo; + __auto_type render = rctx->render; + const char *name = ref->name; + + if (strncmp (name, "$views.", 7) == 0) { + name += 7; + } + + for (uint32_t i = 0; i < rinfo->num_views; i++) { + __auto_type vi = &rinfo->views[i]; + __auto_type vo = &render->image_views[i]; + if (strcmp (name, vi->name) == 0) { + return vo->image_view.view; + } + } + Sys_Error ("%d:invalid view: %s", ref->line, ref->name); +} + +void +QFV_DestroyFramebuffer (vulkan_ctx_t *ctx) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + __auto_type rctx = ctx->render_context; + __auto_type render = rctx->render; + __auto_type rp = &render->renderpasses[0]; + + if (rp->beginInfo.framebuffer) { + VkFramebuffer framebuffer = rp->beginInfo.framebuffer; + rp->beginInfo.framebuffer = 0; + dfunc->vkDestroyFramebuffer (device->dev, framebuffer, 0); + } +} + +void +QFV_CreateFramebuffer (vulkan_ctx_t *ctx) +{ + __auto_type rctx = ctx->render_context; + __auto_type rinfo = rctx->renderinfo; + __auto_type render = rctx->render; + __auto_type rpInfo = &rinfo->renderpasses[0]; + __auto_type rp = &render->renderpasses[0]; + + VkImageView attachments[rpInfo->num_attachments]; + VkFramebufferCreateInfo cInfo = { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .attachmentCount = rpInfo->num_attachments, + .pAttachments = attachments, + .renderPass = rp->beginInfo.renderPass, + .width = rpInfo->framebuffer.width, + .height = rpInfo->framebuffer.height, + .layers = rpInfo->framebuffer.layers, + }; + for (uint32_t i = 0; i < rpInfo->num_attachments; i++) { + attachments[i] = find_view (&rpInfo->attachments[i].view, rctx); + } + + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + VkFramebuffer framebuffer; + dfunc->vkCreateFramebuffer (device->dev, &cInfo, 0, &framebuffer); + QFV_duSetObjectName (device, VK_OBJECT_TYPE_FRAMEBUFFER, framebuffer, + va (ctx->va_ctx, "framebuffer:%s", rpInfo->name)); + + rp->beginInfo.framebuffer = framebuffer; + for (uint32_t i = 0; i < rp->subpass_count; i++) { + __auto_type sp = &rp->subpasses[i]; + sp->inherit.framebuffer = framebuffer; + } +} + void QFV_Render_Init (vulkan_ctx_t *ctx) { @@ -857,6 +931,7 @@ QFV_Render_Shutdown (vulkan_ctx_t *ctx) qfv_devfuncs_t *dfunc = device->funcs; __auto_type rctx = ctx->render_context; if (rctx->render) { + QFV_DestroyFramebuffer (ctx); //FIXME do properly __auto_type r = rctx->render; if (r->resources) { QFV_DestroyResource (ctx->device, r->resources); diff --git a/libs/video/renderer/vulkan/rp_main_def.plist b/libs/video/renderer/vulkan/rp_main_def.plist index 426360d1a..73b6be1b5 100644 --- a/libs/video/renderer/vulkan/rp_main_def.plist +++ b/libs/video/renderer/vulkan/rp_main_def.plist @@ -773,28 +773,34 @@ renderpasses = { loadOp = clear; finalLayout = depth_stencil_attachment_optimal; clearValue = { depthStencil = { depth = 1; stencil = 0; }; }; + view = $views.depth; }; color = { @inherit = $attachment_base; format = $images.color.format; loadOp = clear; + view = $views.color; }; emission = { @inherit = $attachment_base; format = $images.emission.format; loadOp = clear; + view = $views.emission; }; normal = { @inherit = $attachment_base; format = $images.normal.format; + view = $views.normal; }; position = { @inherit = $attachment_base; format = $images.position.format; + view = $views.position; }; opaque = { @inherit = $attachment_base; format = $images.opaque.format; + view = $views.opaque; }; output = { @inherit = $attachment_base; @@ -802,11 +808,10 @@ renderpasses = { loadOp = clear; storeOp = store; finalLayout = $output.finalLayout; + view = $views.output; }; }; framebuffer = { - attachments = (depth, color, emission, normal, position, opaque, - $output.view); width = $output.extent.width; height = $output.extent.height; layers = 1; diff --git a/libs/video/renderer/vulkan/vkparse.plist b/libs/video/renderer/vulkan/vkparse.plist index 346305bf1..6fbcfa3dc 100644 --- a/libs/video/renderer/vulkan/vkparse.plist +++ b/libs/video/renderer/vulkan/vkparse.plist @@ -580,11 +580,6 @@ }; qfv_framebufferinfo_s = { .name = qfv_framebufferinfo_t; - attachments = { - type = (array, qfv_reference_t); - size = num_attachments; - values = attachments; - }; width = auto; height = auto; layers = auto;