diff --git a/include/QF/Vulkan/qf_output.h b/include/QF/Vulkan/qf_output.h index 7ddfaddbb..eecd2c6b2 100644 --- a/include/QF/Vulkan/qf_output.h +++ b/include/QF/Vulkan/qf_output.h @@ -33,6 +33,7 @@ #include "QF/darray.h" #include "QF/Vulkan/qf_vid.h" #include "QF/Vulkan/command.h" +#include "QF/Vulkan/render.h" typedef struct outputframe_s { VkImageView input; @@ -47,6 +48,7 @@ typedef struct outputctx_s { VkSampler sampler; VkImageView input; VkFramebuffer *framebuffers; // one per swapchain image + qfv_attachmentinfo_t swapchain_info; } outputctx_t; struct vulkan_ctx_s; diff --git a/include/QF/Vulkan/render.h b/include/QF/Vulkan/render.h index f941da97c..120224320 100644 --- a/include/QF/Vulkan/render.h +++ b/include/QF/Vulkan/render.h @@ -421,10 +421,13 @@ typedef struct qfv_renderframe_s { typedef struct qfv_renderframeset_s DARRAY_TYPE (qfv_renderframe_t) qfv_renderframeset_t; +typedef struct qfv_attachmentinfoset_s + DARRAY_TYPE (qfv_attachmentinfo_t *) qfv_attachmentinfoset_t; typedef struct qfv_renderctx_s { struct hashctx_s *hashctx; exprtab_t task_functions; + qfv_attachmentinfoset_t external_attachments; qfv_jobinfo_t *jobinfo; qfv_samplerinfo_t *samplerinfo; qfv_job_t *job; @@ -451,6 +454,9 @@ void QFV_BuildRender (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); +void QFV_Render_AddAttachments (struct vulkan_ctx_s *ctx, + uint32_t num_attachments, + qfv_attachmentinfo_t **attachments); void QFV_DestroyFramebuffer (struct vulkan_ctx_s *ctx, qfv_renderpass_t *rp); void QFV_CreateFramebuffer (struct vulkan_ctx_s *ctx, qfv_renderpass_t *rp, diff --git a/libs/video/renderer/vulkan/render.c b/libs/video/renderer/vulkan/render.c index e35b38e60..de2232898 100644 --- a/libs/video/renderer/vulkan/render.c +++ b/libs/video/renderer/vulkan/render.c @@ -478,6 +478,9 @@ QFV_Render_Init (vulkan_ctx_t *ctx) cexpr_init_symtab (&rctx->task_functions, &ectx); rctx->task_functions.symbols = 0; + rctx->external_attachments = + (qfv_attachmentinfoset_t) DARRAY_STATIC_INIT (4); + QFV_Render_AddTasks (ctx, render_task_syms); auto device = ctx->device; @@ -560,6 +563,7 @@ QFV_Render_Shutdown (vulkan_ctx_t *ctx) if (rctx->task_functions.tab) { Hash_DelTable (rctx->task_functions.tab); } + DARRAY_CLEAR (&rctx->external_attachments); if (rctx->samplerinfo) { auto si = rctx->samplerinfo; for (uint32_t i = 0; i < si->num_samplers; i++) { @@ -593,6 +597,18 @@ QFV_Render_AddTasks (vulkan_ctx_t *ctx, exprsym_t *task_syms) } } +void +QFV_Render_AddAttachments (vulkan_ctx_t *ctx, uint32_t num_attachments, + qfv_attachmentinfo_t **attachments) +{ + auto rctx = ctx->render_context; + size_t base = rctx->external_attachments.size; + DARRAY_RESIZE (&rctx->external_attachments, base + num_attachments); + for (size_t i = 0; i < num_attachments; i++) { + rctx->external_attachments.a[base + i] = attachments[i]; + } +} + qfv_step_t * QFV_FindStep (const char *name, qfv_job_t *job) { diff --git a/libs/video/renderer/vulkan/render_load.c b/libs/video/renderer/vulkan/render_load.c index 2adf7b6b3..b64cd6314 100644 --- a/libs/video/renderer/vulkan/render_load.c +++ b/libs/video/renderer/vulkan/render_load.c @@ -699,22 +699,33 @@ init_spCreate (uint32_t index, qfv_subpassinfo_t *sub, objstate_t *s) static void init_atCreate (uint32_t index, qfv_attachmentinfo_t *attachments, objstate_t *s) { - __auto_type ati = &attachments[index]; - __auto_type atc = &s->ptr.attach[s->inds.num_attachments]; - __auto_type cvc = &s->ptr.clear[s->inds.num_attachments]; + auto rctx = s->ctx->render_context; + auto ati = &attachments[index]; + auto atc = &s->ptr.attach[s->inds.num_attachments]; + auto cvc = &s->ptr.clear[s->inds.num_attachments]; if (ati->external) { - if (!strcmp (ati->external, "$swapchain")) { - *atc = (VkAttachmentDescription) { - .format = s->ctx->swapchain->format, - .samples = 1, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - }; + bool found = false; + for (size_t i = 0; i < rctx->external_attachments.size; i++) { + auto ext = rctx->external_attachments.a[i]; + if (!strcmp (ati->external, ext->name)) { + found = true; + *atc = (VkAttachmentDescription) { + .flags = ext->flags, + .format = ext->format, + .samples = ext->samples, + .loadOp = ext->loadOp, + .storeOp = ext->storeOp, + .stencilLoadOp = ext->stencilLoadOp, + .stencilStoreOp = ext->stencilStoreOp, + .initialLayout = ext->initialLayout, + .finalLayout = ext->finalLayout, + }; + } + } + if (!found) { + Sys_Error ("%d:%s: invalid external attachment: %s", + ati->line, ati->name, ati->external); } } else { *atc = (VkAttachmentDescription) { diff --git a/libs/video/renderer/vulkan/vulkan_output.c b/libs/video/renderer/vulkan/vulkan_output.c index 668100944..bd6873d39 100644 --- a/libs/video/renderer/vulkan/vulkan_output.c +++ b/libs/video/renderer/vulkan/vulkan_output.c @@ -316,7 +316,23 @@ Vulkan_Output_Init (vulkan_ctx_t *ctx) outputctx_t *octx = calloc (1, sizeof (outputctx_t)); ctx->output_context = octx; + octx->swapchain_info = (qfv_attachmentinfo_t) { + .name = "$swapchain", + .format = ctx->swapchain->format, + .samples = 1, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + }; + QFV_Render_AddTasks (ctx, output_task_syms); + qfv_attachmentinfo_t *attachments[] = { + &octx->swapchain_info, + }; + QFV_Render_AddAttachments (ctx, 1, attachments); } void