diff --git a/include/QF/Vulkan/qf_alias.h b/include/QF/Vulkan/qf_alias.h index 4d8f7958a..5d414f175 100644 --- a/include/QF/Vulkan/qf_alias.h +++ b/include/QF/Vulkan/qf_alias.h @@ -92,8 +92,10 @@ typedef struct aliasctx_s { } aliasctx_t; struct vulkan_ctx_s; +struct qfv_renderframe_s; struct entity_s; struct mod_alias_ctx_s; + void *Vulkan_Mod_LoadSkin (struct mod_alias_ctx_s *alias_ctx, byte *skin, int skinsize, int snum, int gnum, qboolean group, maliasskindesc_t *skindesc, @@ -106,13 +108,13 @@ void Vulkan_Mod_MakeAliasModelDisplayLists (struct mod_alias_ctx_s *alias_ctx, void *_m, int _s, int extra, struct vulkan_ctx_s *ctx); -void Vulkan_AliasBegin (struct vulkan_ctx_s *ctx); -void Vulkan_DrawAlias (struct entity_s *ent, struct vulkan_ctx_s *ctx); -void Vulkan_AliasEnd (struct vulkan_ctx_s *ctx); +void Vulkan_AliasBegin (struct qfv_renderframe_s *rFrame); +void Vulkan_DrawAlias (struct entity_s *ent, struct qfv_renderframe_s *rFrame); +void Vulkan_AliasEnd (struct qfv_renderframe_s *rFrame); void Vulkan_Alias_Init (struct vulkan_ctx_s *ctx); void Vulkan_Alias_Shutdown (struct vulkan_ctx_s *ctx); -void Vulkan_AliasDepthRange (struct vulkan_ctx_s *ctx, float n, float f); +void Vulkan_AliasDepthRange (struct qfv_renderframe_s *rFrame, float n, float f); #endif//__QF_Vulkan_qf_alias_h diff --git a/include/QF/Vulkan/qf_bsp.h b/include/QF/Vulkan/qf_bsp.h index 19e317ded..3618d8680 100644 --- a/include/QF/Vulkan/qf_bsp.h +++ b/include/QF/Vulkan/qf_bsp.h @@ -176,9 +176,11 @@ typedef struct bspctx_s { } bspctx_t; struct vulkan_ctx_s; +struct qfv_renderframe_s; void Vulkan_ClearElements (struct vulkan_ctx_s *ctx); -void Vulkan_DrawWorld (struct vulkan_ctx_s *ctx); -void Vulkan_DrawSky (struct vulkan_ctx_s *ctx); +void Vulkan_DrawWorld (struct qfv_renderframe_s *rFrame); +void Vulkan_DrawSky (struct qfv_renderframe_s *rFrame); +void Vulkan_DrawWaterSurfaces (struct qfv_renderframe_s *rFrame); void Vulkan_LoadSkys (const char *sky, struct vulkan_ctx_s *ctx); void Vulkan_RegisterTextures (model_t **models, int num_models, struct vulkan_ctx_s *ctx); @@ -186,6 +188,5 @@ void Vulkan_BuildDisplayLists (model_t **models, int num_models, struct vulkan_ctx_s *ctx); void Vulkan_Bsp_Init (struct vulkan_ctx_s *ctx); void Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx); -void Vulkan_DrawWaterSurfaces (struct vulkan_ctx_s *ctx); #endif//__QF_Vulkan_qf_bsp_h diff --git a/include/QF/Vulkan/qf_compose.h b/include/QF/Vulkan/qf_compose.h index f8fd497a1..b8942dba7 100644 --- a/include/QF/Vulkan/qf_compose.h +++ b/include/QF/Vulkan/qf_compose.h @@ -54,9 +54,10 @@ typedef struct composectx_s { } composectx_t; struct vulkan_ctx_s; +struct qfv_renderframe_s; void Vulkan_Compose_Init (struct vulkan_ctx_s *ctx); void Vulkan_Compose_Shutdown (struct vulkan_ctx_s *ctx); -void Vulkan_Compose_Draw (struct vulkan_ctx_s *ctx); +void Vulkan_Compose_Draw (struct qfv_renderframe_s *fFrame); #endif//__QF_Vulkan_qf_compose_h diff --git a/include/QF/Vulkan/qf_draw.h b/include/QF/Vulkan/qf_draw.h index c9e8b20ad..26f9d2a28 100644 --- a/include/QF/Vulkan/qf_draw.h +++ b/include/QF/Vulkan/qf_draw.h @@ -29,6 +29,8 @@ #define __QF_Vulkan_qf_draw_h struct vulkan_ctx_s; +struct qfv_renderframe_s; +struct qpic_s; void Vulkan_Draw_Init (struct vulkan_ctx_s *ctx); void Vulkan_Draw_Shutdown (struct vulkan_ctx_s *ctx); @@ -52,16 +54,19 @@ void Vulkan_Draw_TextBox (int x, int y, int width, int lines, byte alpha, struct vulkan_ctx_s *ctx); void Vulkan_Draw_FadeScreen (struct vulkan_ctx_s *ctx); void Vulkan_Draw_BlendScreen (quat_t color, struct vulkan_ctx_s *ctx); -qpic_t *Vulkan_Draw_CachePic (const char *path, qboolean alpha, - struct vulkan_ctx_s *ctx); +struct qpic_s *Vulkan_Draw_CachePic (const char *path, qboolean alpha, + struct vulkan_ctx_s *ctx); void Vulkan_Draw_UncachePic (const char *path, struct vulkan_ctx_s *ctx); -qpic_t *Vulkan_Draw_MakePic (int width, int height, const byte *data, - struct vulkan_ctx_s *ctx); -void Vulkan_Draw_DestroyPic (qpic_t *pic, struct vulkan_ctx_s *ctx); -qpic_t *Vulkan_Draw_PicFromWad (const char *name, struct vulkan_ctx_s *ctx); -void Vulkan_Draw_Pic (int x, int y, qpic_t *pic, struct vulkan_ctx_s *ctx); -void Vulkan_Draw_Picf (float x, float y, qpic_t *pic, struct vulkan_ctx_s *ctx); -void Vulkan_Draw_SubPic(int x, int y, qpic_t *pic, +struct qpic_s *Vulkan_Draw_MakePic (int width, int height, const byte *data, + struct vulkan_ctx_s *ctx); +void Vulkan_Draw_DestroyPic (struct qpic_s *pic, struct vulkan_ctx_s *ctx); +struct qpic_s *Vulkan_Draw_PicFromWad (const char *name, + struct vulkan_ctx_s *ctx); +void Vulkan_Draw_Pic (int x, int y, struct qpic_s *pic, + struct vulkan_ctx_s *ctx); +void Vulkan_Draw_Picf (float x, float y, struct qpic_s *pic, + struct vulkan_ctx_s *ctx); +void Vulkan_Draw_SubPic(int x, int y, struct qpic_s *pic, int srcx, int srcy, int width, int height, struct vulkan_ctx_s *ctx); @@ -69,6 +74,6 @@ void Vulkan_Set2D (struct vulkan_ctx_s *ctx); void Vulkan_Set2DScaled (struct vulkan_ctx_s *ctx); void Vulkan_End2D (struct vulkan_ctx_s *ctx); void Vulkan_DrawReset (struct vulkan_ctx_s *ctx); -void Vulkan_FlushText (struct vulkan_ctx_s *ctx); +void Vulkan_FlushText (struct qfv_renderframe_s *rFrame); #endif//__QF_Vulkan_qf_draw_h diff --git a/include/QF/Vulkan/qf_lighting.h b/include/QF/Vulkan/qf_lighting.h index e7940d847..c96c08f0e 100644 --- a/include/QF/Vulkan/qf_lighting.h +++ b/include/QF/Vulkan/qf_lighting.h @@ -128,10 +128,11 @@ typedef struct lightingctx_s { } lightingctx_t; struct vulkan_ctx_s; +struct qfv_renderframe_s;; void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx); void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx); -void Vulkan_Lighting_Draw (struct vulkan_ctx_s *ctx); +void Vulkan_Lighting_Draw (struct qfv_renderframe_s *fFrame); void Vulkan_LoadLights (model_t *model, const char *entity_data, struct vulkan_ctx_s *ctx); diff --git a/include/QF/Vulkan/qf_main.h b/include/QF/Vulkan/qf_main.h index 4b487da5e..23a02e11d 100644 --- a/include/QF/Vulkan/qf_main.h +++ b/include/QF/Vulkan/qf_main.h @@ -29,9 +29,10 @@ #define __QF_Vulkan_qf_main_h struct vulkan_ctx_s; +struct qfv_renderframe_s; void Vulkan_NewMap (model_t *worldmodel, struct model_s **models, int num_models, struct vulkan_ctx_s *ctx); -void Vulkan_RenderView (struct vulkan_ctx_s *ctx); +void Vulkan_RenderView (struct qfv_renderframe_s *rFrame); #endif//__QF_Vulkan_qf_main_h diff --git a/include/QF/Vulkan/qf_vid.h b/include/QF/Vulkan/qf_vid.h index 8b94b2408..db37faa59 100644 --- a/include/QF/Vulkan/qf_vid.h +++ b/include/QF/Vulkan/qf_vid.h @@ -61,10 +61,8 @@ struct vulkan_ctx_s; void Vulkan_DestroyFrames (struct vulkan_ctx_s *ctx); void Vulkan_CreateFrames (struct vulkan_ctx_s *ctx); void Vulkan_CreateCapture (struct vulkan_ctx_s *ctx); -void Vulkan_CreateFramebuffers (struct vulkan_ctx_s *ctx); -void Vulkan_DestroyFramebuffers (struct vulkan_ctx_s *ctx); void Vulkan_CreateRenderPass (struct vulkan_ctx_s *ctx); -void Vulkan_DestroyRenderPass (struct vulkan_ctx_s *ctx); +void Vulkan_DestroyRenderPasses (struct vulkan_ctx_s *ctx); void Vulkan_CreateMatrices (struct vulkan_ctx_s *ctx); void Vulkan_DestroyMatrices (struct vulkan_ctx_s *ctx); void Vulkan_CalcProjectionMatrices (struct vulkan_ctx_s *ctx); diff --git a/include/QF/Vulkan/renderpass.h b/include/QF/Vulkan/renderpass.h index a584d476d..31ea607ca 100644 --- a/include/QF/Vulkan/renderpass.h +++ b/include/QF/Vulkan/renderpass.h @@ -47,4 +47,33 @@ QFV_CreateFramebuffer (struct qfv_device_s *device, struct qfv_imageviewset_s *attachments, VkExtent2D, uint32_t layers); +typedef struct qfv_renderframe_s { + struct vulkan_ctx_s *vulkan_ctx; + struct qfv_renderpass_s *renderpass; + VkSubpassContents subpassContents; + int subpassCount; + struct qfv_cmdbufferset_s *subpassCmdSets; +} qfv_renderframe_t; + +typedef struct qfv_renderframeset_s + DARRAY_TYPE (qfv_renderframe_t) qfv_renderframeset_t; + +typedef struct clearvalueset_s + DARRAY_TYPE (VkClearValue) clearvalueset_t; + +typedef struct qfv_renderpass_s { + struct plitem_s *renderpassDef; + VkRenderPass renderpass; + clearvalueset_t *clearValues; + struct qfv_imageset_s *attachment_images; + struct qfv_imageviewset_s *attachment_views; + VkDeviceMemory attachmentMemory; + + qfv_framebufferset_t *framebuffers; + + qfv_renderframeset_t frames; + + void (*draw) (qfv_renderframe_t *rFrame); +} qfv_renderpass_t; + #endif//__QF_Vulkan_renderpass_h diff --git a/include/vid_vulkan.h b/include/vid_vulkan.h index 55841b1d0..584502b9c 100644 --- a/include/vid_vulkan.h +++ b/include/vid_vulkan.h @@ -15,9 +15,6 @@ typedef struct vulkan_frame_s { VkSemaphore imageAvailableSemaphore; VkSemaphore renderDoneSemaphore; VkCommandBuffer cmdBuffer; - - int cmdSetCount; - struct qfv_cmdbufferset_s *cmdSets; } vulkan_frame_t; typedef struct vulkan_matrices_s { @@ -33,8 +30,8 @@ typedef struct vulkan_matrices_s { typedef struct vulkan_frameset_s DARRAY_TYPE (vulkan_frame_t) vulkan_frameset_t; -typedef struct clearvalueset_s - DARRAY_TYPE (VkClearValue) clearvalueset_t; +typedef struct qfv_renderpassset_s + DARRAY_TYPE (struct qfv_renderpass_s *) qfv_renderpassset_t; typedef struct vulkan_ctx_s { void (*load_vulkan) (struct vulkan_ctx_s *ctx); @@ -58,15 +55,7 @@ typedef struct vulkan_ctx_s { VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain struct plitem_s *pipelineDef; - struct plitem_s *renderpassDef; - VkRenderPass renderpass; - clearvalueset_t *clearValues; - struct qfv_imageset_s *attachment_images; - struct qfv_imageviewset_s *attachment_views; - VkDeviceMemory attachmentMemory; - uint32_t swapImageIndex; - struct qfv_framebufferset_s *framebuffers; struct hashtab_s *shaderModules; struct hashtab_s *setLayouts; @@ -92,6 +81,7 @@ typedef struct vulkan_ctx_s { struct qfv_stagebuf_s *staging; size_t curFrame; vulkan_frameset_t frames; + qfv_renderpassset_t renderPasses; struct qfv_capture_s *capture; void (*capture_callback) (const byte *data, int width, int height); diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index 2495d7c8d..718d22464 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -98,14 +98,15 @@ vulkan_R_Init (void) Vulkan_CreateFrames (vulkan_ctx); Vulkan_CreateCapture (vulkan_ctx); Vulkan_CreateRenderPass (vulkan_ctx); - Vulkan_CreateFramebuffers (vulkan_ctx); Vulkan_Texture_Init (vulkan_ctx); + Vulkan_Alias_Init (vulkan_ctx); Vulkan_Bsp_Init (vulkan_ctx); Vulkan_Draw_Init (vulkan_ctx); Vulkan_Particles_Init (vulkan_ctx); Vulkan_Lighting_Init (vulkan_ctx); Vulkan_Compose_Init (vulkan_ctx); + Skin_Init (); SCR_Init (); @@ -114,8 +115,6 @@ vulkan_R_Init (void) static void vulkan_R_RenderFrame (SCR_Func *scr_funcs) { - const VkSubpassContents subpassContents - = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; uint32_t imageIndex = 0; qfv_device_t *device = vulkan_ctx->device; qfv_devfuncs_t *dfunc = device->funcs; @@ -130,52 +129,61 @@ vulkan_R_RenderFrame (SCR_Func *scr_funcs) 0, &imageIndex); vulkan_ctx->swapImageIndex = imageIndex; - frame->framebuffer = vulkan_ctx->framebuffers->a[imageIndex]; - view_draw (vr_data.scr_view); while (*scr_funcs) { (*scr_funcs) (); scr_funcs++; } - Vulkan_RenderView (vulkan_ctx); - Vulkan_FlushText (vulkan_ctx); - - Vulkan_Lighting_Draw (vulkan_ctx); - Vulkan_Compose_Draw (vulkan_ctx); + for (size_t i = 0; i < vulkan_ctx->renderPasses.size; i++) { + __auto_type rp = vulkan_ctx->renderPasses.a[i]; + __auto_type rpFrame = &rp->frames.a[vulkan_ctx->curFrame]; + rp->draw (rpFrame); + } VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + VkRenderPassBeginInfo renderPassInfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 0, - vulkan_ctx->renderpass, 0, - { {0, 0}, vulkan_ctx->swapchain->extent }, - vulkan_ctx->clearValues->size, vulkan_ctx->clearValues->a + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderArea = { {0, 0}, vulkan_ctx->swapchain->extent }, }; dfunc->vkBeginCommandBuffer (frame->cmdBuffer, &beginInfo); - renderPassInfo.framebuffer = frame->framebuffer; - dfunc->vkCmdBeginRenderPass (frame->cmdBuffer, &renderPassInfo, - subpassContents); + for (size_t i = 0; i < vulkan_ctx->renderPasses.size; i++) { + __auto_type rp = vulkan_ctx->renderPasses.a[i]; + __auto_type rpFrame = &rp->frames.a[vulkan_ctx->curFrame]; - for (int i = 0; i < frame->cmdSetCount; i++) { - if (frame->cmdSets[i].size) { - dfunc->vkCmdExecuteCommands (frame->cmdBuffer, - frame->cmdSets[i].size, - frame->cmdSets[i].a); - } - // reset for next time around - frame->cmdSets[i].size = 0; - //Regardless of whether any commands were submitted for this subpass, - //must step through each and every subpass, otherwise the attachments - //won't be transitioned correctly. - if (i < frame->cmdSetCount - 1) { - dfunc->vkCmdNextSubpass (frame->cmdBuffer, subpassContents); + frame->framebuffer = rp->framebuffers->a[imageIndex]; + renderPassInfo.framebuffer = frame->framebuffer, + renderPassInfo.renderPass = rp->renderpass; + renderPassInfo.clearValueCount = rp->clearValues->size; + renderPassInfo.pClearValues = rp->clearValues->a; + + dfunc->vkCmdBeginRenderPass (frame->cmdBuffer, &renderPassInfo, + rpFrame->subpassContents); + + for (int j = 0; j < rpFrame->subpassCount; j++) { + __auto_type cmdSet = &rpFrame->subpassCmdSets[j]; + if (cmdSet->size) { + dfunc->vkCmdExecuteCommands (frame->cmdBuffer, + cmdSet->size, cmdSet->a); + } + // reset for next time around + cmdSet->size = 0; + + //Regardless of whether any commands were submitted for this + //subpass, must step through each and every subpass, otherwise + //the attachments won't be transitioned correctly. + if (j < rpFrame->subpassCount - 1) { + dfunc->vkCmdNextSubpass (frame->cmdBuffer, + rpFrame->subpassContents); + } } + dfunc->vkCmdEndRenderPass (frame->cmdBuffer); } - dfunc->vkCmdEndRenderPass (frame->cmdBuffer); if (vulkan_ctx->capture_callback) { VkImage srcImage = vulkan_ctx->swapchain->images->a[imageIndex]; VkCommandBuffer cmd = QFV_CaptureImage (vulkan_ctx->capture, srcImage, @@ -615,15 +623,16 @@ vulkan_vid_render_shutdown (void) QFV_DeviceWaitIdle (device); df->vkDestroyFence (dev, vulkan_ctx->fence, 0); df->vkDestroyCommandPool (dev, vulkan_ctx->cmdpool, 0); + Vulkan_Compose_Shutdown (vulkan_ctx); Vulkan_Lighting_Shutdown (vulkan_ctx); Vulkan_Draw_Shutdown (vulkan_ctx); Vulkan_Bsp_Shutdown (vulkan_ctx); Vulkan_Alias_Shutdown (vulkan_ctx); + Mod_ClearAll (); Vulkan_Texture_Shutdown (vulkan_ctx); - Vulkan_DestroyFramebuffers (vulkan_ctx); - Vulkan_DestroyRenderPass (vulkan_ctx); + Vulkan_DestroyRenderPasses (vulkan_ctx); Vulkan_Shutdown_Common (vulkan_ctx); } diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 31e14ad7f..3bbbb7b46 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -595,7 +595,7 @@ dynamicState = ( viewport, scissor ); }; layout = quakebsp_layout; - //renderPass = renderpass; + renderPass = renderpass; }; alias_depth = { subpass = 0; @@ -629,7 +629,7 @@ dynamicState = ( viewport, scissor ); }; layout = alias_layout; - //renderPass = renderpass; + renderPass = renderpass; }; alias_gbuf = { subpass = 2; @@ -670,7 +670,7 @@ dynamicState = ( viewport, scissor, blend_constants ); }; layout = alias_layout; - //renderPass = renderpass; + renderPass = renderpass; }; bsp_depth = { subpass = 0; @@ -699,7 +699,7 @@ dynamicState = ( viewport, scissor ); }; layout = quakebsp_layout; - //renderPass = renderpass; + renderPass = renderpass; }; bsp_gbuf = { subpass = 2; @@ -748,7 +748,7 @@ dynamicState = ( viewport, scissor, blend_constants ); }; layout = quakebsp_layout; - //renderPass = renderpass; + renderPass = renderpass; }; bsp_skybox = { subpass = 1; @@ -785,7 +785,7 @@ dynamicState = ( viewport, scissor ); }; layout = quakebsp_layout; - //renderPass = renderpass; + renderPass = renderpass; }; bsp_skysheet = { subpass = 1; @@ -822,7 +822,7 @@ dynamicState = ( viewport, scissor ); }; layout = quakebsp_layout; - //renderPass = renderpass; + renderPass = renderpass; }; bsp_turb = { subpass = 1; @@ -859,7 +859,7 @@ dynamicState = ( viewport, scissor ); }; layout = quakebsp_layout; - //renderPass = renderpass; + renderPass = renderpass; }; twod = { subpass = 1; @@ -889,7 +889,7 @@ dynamicState = ( viewport, scissor ); }; layout = twod_layout; - //renderPass = renderpass; + renderPass = renderpass; }; lighting = { subpass = 3; @@ -916,7 +916,7 @@ dynamicState = ( viewport, scissor ); }; layout = lighting_layout; - //renderPass = renderpass; + renderPass = renderpass; }; compose = { subpass = 4; @@ -943,7 +943,7 @@ dynamicState = ( viewport, scissor ); }; layout = compose_layout; - //renderPass = renderpass; + renderPass = renderpass; }; }; } diff --git a/libs/video/renderer/vulkan/vkparse.c b/libs/video/renderer/vulkan/vkparse.c index 1be4facf8..3a5431db4 100644 --- a/libs/video/renderer/vulkan/vkparse.c +++ b/libs/video/renderer/vulkan/vkparse.c @@ -938,11 +938,11 @@ exprtype_t vulkan_frameset_t_type = { &vulkan_frameset_t_symtab, }; -typedef struct qfv_renderpass_s { +typedef struct { qfv_attachmentdescription_t *attachments; qfv_subpassparametersset_t *subpasses; qfv_subpassdependency_t *dependencies; -} qfv_renderpass_t; +} vkparse_renderpass_t; static plelement_t parse_qfv_renderpass_attachments_data = { QFDictionary, @@ -969,11 +969,11 @@ static plelement_t parse_qfv_renderpass_dependencies_data = { }; static plfield_t renderpass_fields[] = { - { "attachments", field_offset (qfv_renderpass_t, attachments), QFArray, + { "attachments", field_offset(vkparse_renderpass_t,attachments), QFArray, PL_ParseArray, &parse_qfv_renderpass_attachments_data }, - { "subpasses", field_offset (qfv_renderpass_t, subpasses), QFArray, + { "subpasses", field_offset(vkparse_renderpass_t,subpasses), QFArray, PL_ParseArray, &parse_qfv_renderpass_subpasses_data }, - { "dependencies", field_offset (qfv_renderpass_t, dependencies), QFArray, + { "dependencies", field_offset(vkparse_renderpass_t,dependencies), QFArray, PL_ParseArray, &parse_qfv_renderpass_dependencies_data }, {} }; @@ -1073,7 +1073,7 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties) memsuper_t *memsuper = new_memsuper (); qfv_device_t *device = ctx->device; - qfv_renderpass_t renderpass_data = {}; + vkparse_renderpass_t renderpass_data = {}; if (!parse_object (ctx, memsuper, plist, parse_qfv_renderpass, &renderpass_data, properties)) { @@ -1108,8 +1108,9 @@ QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties) return 0; } - cInfo->a[0].renderPass = ctx->renderpass; - qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParsePipeline: %d", PL_Line (plist))); + qfvPushDebug (ctx, va (ctx->va_ctx, + "QFV_ParsePipeline: %d", PL_Line (plist))); + __auto_type plSet = QFV_CreateGraphicsPipelines (device, 0, cInfo); qfvPopDebug (ctx); VkPipeline pipeline = plSet->a[0]; @@ -1462,22 +1463,18 @@ parse_clearvalueset (const plfield_t *field, const plitem_t *item, void *data, return 1; } -int +clearvalueset_t * QFV_ParseClearValues (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties) { - int ret = 0; + clearvalueset_t *cv = 0; memsuper_t *memsuper = new_memsuper (); clearvalueset_t *clearValues = 0; - ctx->clearValues = 0; if (parse_object (ctx, memsuper, plist, parse_clearvalueset, &clearValues, properties)) { - ret = 1; - ctx->clearValues = DARRAY_ALLOCFIXED (clearvalueset_t, - clearValues->size, malloc); - memcpy (ctx->clearValues->a, clearValues->a, - clearValues->size * sizeof (clearValues->a[0])); + cv = DARRAY_ALLOCFIXED (clearvalueset_t, clearValues->size, malloc); + memcpy (cv->a, clearValues->a, cv->size * sizeof (cv->a[0])); } delete_memsuper (memsuper); - return ret; + return cv; } diff --git a/libs/video/renderer/vulkan/vkparse.h b/libs/video/renderer/vulkan/vkparse.h index 4f258a96f..6e2ef92b2 100644 --- a/libs/video/renderer/vulkan/vkparse.h +++ b/libs/video/renderer/vulkan/vkparse.h @@ -58,8 +58,9 @@ struct qfv_imageviewset_s *QFV_ParseImageViewSet (vulkan_ctx_t *ctx, plitem_t *properties); VkFramebuffer QFV_ParseFramebuffer (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties); -int QFV_ParseClearValues (vulkan_ctx_t *ctx, plitem_t *plist, - plitem_t *properties); +struct clearvalueset_s *QFV_ParseClearValues (vulkan_ctx_t *ctx, + plitem_t *plist, + plitem_t *properties); #endif//__vkparse_h diff --git a/libs/video/renderer/vulkan/vkparse.plist b/libs/video/renderer/vulkan/vkparse.plist index dad5e4169..415e31d0a 100644 --- a/libs/video/renderer/vulkan/vkparse.plist +++ b/libs/video/renderer/vulkan/vkparse.plist @@ -282,6 +282,10 @@ type = (custom, QFString, parse_VkPipelineLayout); fields = (layout); }; + renderPass = { + type = (custom, QFString, parse_VkRenderPass); + fields = (renderPass); + }; subpass = auto; basePipelineHandle = { type = (custom, QFString, parse_BasePipeline); diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index 810bc14ef..50aacfe4a 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -60,6 +60,7 @@ #include "QF/Vulkan/debug.h" #include "QF/Vulkan/descriptor.h" #include "QF/Vulkan/device.h" +#include "QF/Vulkan/renderpass.h" #include "r_internal.h" #include "vid_vulkan.h" @@ -81,8 +82,9 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2, qfv_alias_skin_t *skin, void *vert_constants, int vert_size, void *frag_constants, int frag_size, - aliashdr_t *hdr, vulkan_ctx_t *ctx) + aliashdr_t *hdr, qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; aliasctx_t *actx = ctx->alias_context; @@ -123,8 +125,9 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2, } void -Vulkan_DrawAlias (entity_t *ent, vulkan_ctx_t *ctx) +Vulkan_DrawAlias (entity_t *ent, qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; aliasctx_t *actx = ctx->alias_context; aliasframe_t *aframe = &actx->frames.a[ctx->curFrame]; model_t *model = ent->renderer.model; @@ -159,18 +162,19 @@ Vulkan_DrawAlias (entity_t *ent, vulkan_ctx_t *ctx) ent->animation.pose1, ent->animation.pose2, 0, &vertex_constants, 17 * sizeof (float), fragment_constants, sizeof (fragment_constants), - hdr, ctx); + hdr, rFrame); emit_commands (aframe->cmdSet.a[QFV_aliasGBuffer], ent->animation.pose1, ent->animation.pose2, skin, &vertex_constants, 17 * sizeof (float), fragment_constants, sizeof (fragment_constants), - hdr, ctx); + hdr, rFrame); } static void alias_begin_subpass (QFV_AliasSubpass subpass, VkPipeline pipeline, - vulkan_ctx_t *ctx) + qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; aliasctx_t *actx = ctx->alias_context; @@ -181,7 +185,7 @@ alias_begin_subpass (QFV_AliasSubpass subpass, VkPipeline pipeline, dfunc->vkResetCommandBuffer (cmd, 0); VkCommandBufferInheritanceInfo inherit = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0, - ctx->renderpass, subpass_map[subpass], + rFrame->renderpass->renderpass, subpass_map[subpass], cframe->framebuffer, 0, 0, 0, }; @@ -226,28 +230,29 @@ alias_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx) } void -Vulkan_AliasBegin (vulkan_ctx_t *ctx) +Vulkan_AliasBegin (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; aliasctx_t *actx = ctx->alias_context; - __auto_type cframe = &ctx->frames.a[ctx->curFrame]; aliasframe_t *aframe = &actx->frames.a[ctx->curFrame]; //XXX quat_t fog; - DARRAY_APPEND (&cframe->cmdSets[QFV_passDepth], + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passDepth], aframe->cmdSet.a[QFV_aliasDepth]); - DARRAY_APPEND (&cframe->cmdSets[QFV_passGBuffer], + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer], aframe->cmdSet.a[QFV_aliasGBuffer]); //FIXME need per frame matrices aframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d; - alias_begin_subpass (QFV_aliasDepth, actx->depth, ctx); - alias_begin_subpass (QFV_aliasGBuffer, actx->gbuf, ctx); + alias_begin_subpass (QFV_aliasDepth, actx->depth, rFrame); + alias_begin_subpass (QFV_aliasGBuffer, actx->gbuf, rFrame); } void -Vulkan_AliasEnd (vulkan_ctx_t *ctx) +Vulkan_AliasEnd (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; aliasctx_t *actx = ctx->alias_context; aliasframe_t *aframe = &actx->frames.a[ctx->curFrame]; @@ -256,8 +261,10 @@ Vulkan_AliasEnd (vulkan_ctx_t *ctx) } void -Vulkan_AliasDepthRange (vulkan_ctx_t *ctx, float minDepth, float maxDepth) +Vulkan_AliasDepthRange (qfv_renderframe_t *rFrame, + float minDepth, float maxDepth) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; aliasctx_t *actx = ctx->alias_context; diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index bcf1b31b4..7a009943f 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -63,6 +63,7 @@ #include "QF/Vulkan/device.h" #include "QF/Vulkan/image.h" #include "QF/Vulkan/instance.h" +#include "QF/Vulkan/renderpass.h" #include "QF/Vulkan/scrap.h" #include "QF/Vulkan/staging.h" @@ -825,8 +826,9 @@ get_view (qfv_tex_t *tex, qfv_tex_t *default_tex) static void bsp_begin_subpass (QFV_BspSubpass subpass, VkPipeline pipeline, - vulkan_ctx_t *ctx) + qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; bspctx_t *bctx = ctx->bsp_context; @@ -837,7 +839,7 @@ bsp_begin_subpass (QFV_BspSubpass subpass, VkPipeline pipeline, dfunc->vkResetCommandBuffer (cmd, 0); VkCommandBufferInheritanceInfo inherit = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0, - ctx->renderpass, subpass_map[subpass], + rFrame->renderpass->renderpass, subpass_map[subpass], cframe->framebuffer, 0, 0, 0, }; @@ -886,20 +888,20 @@ bsp_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx) } static void -bsp_begin (vulkan_ctx_t *ctx) +bsp_begin (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; bspctx_t *bctx = ctx->bsp_context; //XXX quat_t fog; bctx->default_color[3] = 1; QuatCopy (bctx->default_color, bctx->last_color); - __auto_type cframe = &ctx->frames.a[ctx->curFrame]; bspframe_t *bframe = &bctx->frames.a[ctx->curFrame]; - DARRAY_APPEND (&cframe->cmdSets[QFV_passDepth], + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passDepth], bframe->cmdSet.a[QFV_bspDepth]); - DARRAY_APPEND (&cframe->cmdSets[QFV_passGBuffer], + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer], bframe->cmdSet.a[QFV_bspGBuffer]); //FIXME need per frame matrices @@ -912,8 +914,8 @@ bsp_begin (vulkan_ctx_t *ctx) bframe->imageInfo[4].imageView = get_view (bctx->skybox_tex, bctx->default_skybox); - bsp_begin_subpass (QFV_bspDepth, bctx->depth, ctx); - bsp_begin_subpass (QFV_bspGBuffer, bctx->gbuf, ctx); + bsp_begin_subpass (QFV_bspDepth, bctx->depth, rFrame); + bsp_begin_subpass (QFV_bspGBuffer, bctx->gbuf, rFrame); } static void @@ -927,18 +929,18 @@ bsp_end (vulkan_ctx_t *ctx) } static void -turb_begin (vulkan_ctx_t *ctx) +turb_begin (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; bspctx_t *bctx = ctx->bsp_context; bctx->default_color[3] = bound (0, r_wateralpha->value, 1); QuatCopy (bctx->default_color, bctx->last_color); - __auto_type cframe = &ctx->frames.a[ctx->curFrame]; bspframe_t *bframe = &bctx->frames.a[ctx->curFrame]; - DARRAY_APPEND (&cframe->cmdSets[QFV_passTranslucent], + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent], bframe->cmdSet.a[QFV_bspTurb]); //FIXME need per frame matrices @@ -949,7 +951,7 @@ turb_begin (vulkan_ctx_t *ctx) bframe->imageInfo[3].imageView = bctx->default_skysheet->view; bframe->imageInfo[4].imageView = bctx->default_skybox->view; - bsp_begin_subpass (QFV_bspTurb, bctx->turb, ctx); + bsp_begin_subpass (QFV_bspTurb, bctx->turb, rFrame); } static void @@ -985,8 +987,9 @@ spin (mat4f_t mat, bspctx_t *bctx) } static void -sky_begin (vulkan_ctx_t *ctx) +sky_begin (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; bspctx_t *bctx = ctx->bsp_context; bctx->default_color[3] = 1; @@ -994,10 +997,9 @@ sky_begin (vulkan_ctx_t *ctx) spin (ctx->matrices.sky_3d, bctx); - __auto_type cframe = &ctx->frames.a[ctx->curFrame]; bspframe_t *bframe = &bctx->frames.a[ctx->curFrame]; - DARRAY_APPEND (&cframe->cmdSets[QFV_passTranslucent], + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent], bframe->cmdSet.a[QFV_bspSky]); //FIXME need per frame matrices @@ -1011,9 +1013,9 @@ sky_begin (vulkan_ctx_t *ctx) bctx->default_skybox); if (bctx->skybox_tex) { - bsp_begin_subpass (QFV_bspSky, bctx->skybox, ctx); + bsp_begin_subpass (QFV_bspSky, bctx->skybox, rFrame); } else { - bsp_begin_subpass (QFV_bspSky, bctx->skysheet, ctx); + bsp_begin_subpass (QFV_bspSky, bctx->skysheet, rFrame); } } @@ -1068,8 +1070,9 @@ build_tex_elechain (vulktex_t *tex, bspctx_t *bctx, bspframe_t *bframe) } void -Vulkan_DrawWorld (vulkan_ctx_t *ctx) +Vulkan_DrawWorld (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; bspctx_t *bctx = ctx->bsp_context; @@ -1098,7 +1101,7 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx) } } - bsp_begin (ctx); + bsp_begin (rFrame); push_transform (identity, bctx->layout, dfunc, bframe->cmdSet.a[QFV_bspDepth]); @@ -1152,8 +1155,9 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx) } void -Vulkan_DrawWaterSurfaces (vulkan_ctx_t *ctx) +Vulkan_DrawWaterSurfaces (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; bspctx_t *bctx = ctx->bsp_context; @@ -1166,7 +1170,7 @@ Vulkan_DrawWaterSurfaces (vulkan_ctx_t *ctx) if (!bctx->waterchain) return; - turb_begin (ctx); + turb_begin (rFrame); push_transform (identity, bctx->layout, dfunc, bframe->cmdSet.a[QFV_bspTurb]); fragconst_t frag_constants = { time: vr_data.realtime }; @@ -1214,8 +1218,9 @@ Vulkan_DrawWaterSurfaces (vulkan_ctx_t *ctx) } void -Vulkan_DrawSky (vulkan_ctx_t *ctx) +Vulkan_DrawSky (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; bspctx_t *bctx = ctx->bsp_context; @@ -1228,7 +1233,7 @@ Vulkan_DrawSky (vulkan_ctx_t *ctx) if (!bctx->sky_chain) return; - sky_begin (ctx); + sky_begin (rFrame); push_transform (identity, bctx->layout, dfunc, bframe->cmdSet.a[QFV_bspSky]); fragconst_t frag_constants = { time: vr_data.realtime }; diff --git a/libs/video/renderer/vulkan/vulkan_compose.c b/libs/video/renderer/vulkan/vulkan_compose.c index 5b86ca457..4288ca462 100644 --- a/libs/video/renderer/vulkan/vulkan_compose.c +++ b/libs/video/renderer/vulkan/vulkan_compose.c @@ -48,27 +48,30 @@ #include "QF/Vulkan/descriptor.h" #include "QF/Vulkan/device.h" #include "QF/Vulkan/image.h" +#include "QF/Vulkan/renderpass.h" #include "r_internal.h" #include "vid_vulkan.h" void -Vulkan_Compose_Draw (vulkan_ctx_t *ctx) +Vulkan_Compose_Draw (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; + qfv_renderpass_t *renderpass = rFrame->renderpass; composectx_t *cctx = ctx->compose_context; __auto_type frame = &ctx->frames.a[ctx->curFrame]; composeframe_t *cframe = &cctx->frames.a[ctx->curFrame]; VkCommandBuffer cmd = cframe->cmd; - DARRAY_APPEND (&frame->cmdSets[QFV_passCompose], cmd); + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passCompose], cmd); dfunc->vkResetCommandBuffer (cmd, 0); VkCommandBufferInheritanceInfo inherit = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0, - ctx->renderpass, QFV_passCompose, + renderpass->renderpass, QFV_passCompose, frame->framebuffer, 0, 0, 0, }; @@ -85,9 +88,9 @@ Vulkan_Compose_Draw (vulkan_ctx_t *ctx) cctx->pipeline); cframe->imageInfo[0].imageView - = ctx->attachment_views->a[QFV_attachOpaque]; + = renderpass->attachment_views->a[QFV_attachOpaque]; cframe->imageInfo[1].imageView - = ctx->attachment_views->a[QFV_attachTranslucent]; + = renderpass->attachment_views->a[QFV_attachTranslucent]; dfunc->vkUpdateDescriptorSets (device->dev, COMPOSE_IMAGE_INFOS, cframe->descriptors, 0, 0); diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index af525bf2d..2d3dc4156 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -59,6 +59,7 @@ #include "QF/Vulkan/descriptor.h" #include "QF/Vulkan/device.h" #include "QF/Vulkan/image.h" +#include "QF/Vulkan/renderpass.h" #include "QF/Vulkan/scrap.h" #include "QF/Vulkan/staging.h" #include "QF/ui/view.h" @@ -748,8 +749,9 @@ Vulkan_DrawReset (vulkan_ctx_t *ctx) } void -Vulkan_FlushText (vulkan_ctx_t *ctx) +Vulkan_FlushText (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; flush_draw_scrap (ctx); qfv_device_t *device = ctx->device; @@ -760,7 +762,7 @@ Vulkan_FlushText (vulkan_ctx_t *ctx) VkCommandBuffer cmd = dframe->cmd; //FIXME which pass? - DARRAY_APPEND (&cframe->cmdSets[QFV_passTranslucent], cmd); + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent], cmd); VkMappedMemoryRange range = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0, @@ -772,7 +774,7 @@ Vulkan_FlushText (vulkan_ctx_t *ctx) dfunc->vkResetCommandBuffer (cmd, 0); VkCommandBufferInheritanceInfo inherit = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0, - ctx->renderpass, QFV_passTranslucent, + rFrame->renderpass->renderpass, QFV_passTranslucent, cframe->framebuffer, 0, 0, 0 }; diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index 7ceb025e5..de7bc409f 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -59,6 +59,7 @@ #include "QF/Vulkan/image.h" #include "QF/Vulkan/instance.h" #include "QF/Vulkan/projection.h" +#include "QF/Vulkan/renderpass.h" #include "QF/Vulkan/staging.h" #include "compat.h" @@ -197,10 +198,12 @@ update_lights (vulkan_ctx_t *ctx) } void -Vulkan_Lighting_Draw (vulkan_ctx_t *ctx) +Vulkan_Lighting_Draw (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; + qfv_renderpass_t *renderpass = rFrame->renderpass; update_lights (ctx); @@ -209,12 +212,12 @@ Vulkan_Lighting_Draw (vulkan_ctx_t *ctx) lightingframe_t *lframe = &lctx->frames.a[ctx->curFrame]; VkCommandBuffer cmd = lframe->cmd; - DARRAY_APPEND (&cframe->cmdSets[QFV_passLighting], cmd); + DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passLighting], cmd); dfunc->vkResetCommandBuffer (cmd, 0); VkCommandBufferInheritanceInfo inherit = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0, - ctx->renderpass, QFV_passLighting, + renderpass->renderpass, QFV_passLighting, cframe->framebuffer, 0, 0, 0, }; @@ -231,14 +234,16 @@ Vulkan_Lighting_Draw (vulkan_ctx_t *ctx) lctx->pipeline); lframe->bufferInfo[0].buffer = lframe->light_buffer; - lframe->attachInfo[0].imageView = ctx->attachment_views->a[QFV_attachDepth]; - lframe->attachInfo[1].imageView = ctx->attachment_views->a[QFV_attachColor]; + lframe->attachInfo[0].imageView + = renderpass->attachment_views->a[QFV_attachDepth]; + lframe->attachInfo[1].imageView + = renderpass->attachment_views->a[QFV_attachColor]; lframe->attachInfo[2].imageView - = ctx->attachment_views->a[QFV_attachEmission]; + = renderpass->attachment_views->a[QFV_attachEmission]; lframe->attachInfo[3].imageView - = ctx->attachment_views->a[QFV_attachNormal]; + = renderpass->attachment_views->a[QFV_attachNormal]; lframe->attachInfo[4].imageView - = ctx->attachment_views->a[QFV_attachPosition]; + = renderpass->attachment_views->a[QFV_attachPosition]; dfunc->vkUpdateDescriptorSets (device->dev, LIGHTING_DESCRIPTORS, lframe->descriptors, 0, 0); diff --git a/libs/video/renderer/vulkan/vulkan_main.c b/libs/video/renderer/vulkan/vulkan_main.c index ea7ac5508..5cfa90094 100644 --- a/libs/video/renderer/vulkan/vulkan_main.c +++ b/libs/video/renderer/vulkan/vulkan_main.c @@ -54,6 +54,7 @@ #include "QF/Vulkan/qf_main.h" #include "QF/Vulkan/qf_particles.h" //#include "QF/Vulkan/qf_textures.h" +#include "QF/Vulkan/renderpass.h" #include "mod_internal.h" #include "r_internal.h" @@ -103,7 +104,7 @@ setup_view (vulkan_ctx_t *ctx) } static void -Vulkan_RenderEntities (vulkan_ctx_t *ctx) +Vulkan_RenderEntities (qfv_renderframe_t *rFrame) { if (!r_drawentities->int_val) return; @@ -115,22 +116,22 @@ Vulkan_RenderEntities (vulkan_ctx_t *ctx) if (ent->renderer.model->type != mod_##type_name) \ continue; \ if (!begun) { \ - Vulkan_##Type##Begin (ctx); \ + Vulkan_##Type##Begin (rFrame); \ begun = 1; \ } \ /* hack the depth range to prevent view model */\ /* from poking into walls */\ if (ent == vr_data.view_model) { \ - Vulkan_AliasDepthRange (ctx, 0, 0.3); \ + Vulkan_AliasDepthRange (rFrame, 0, 0.3); \ } \ - Vulkan_Draw##Type (ent, ctx); \ + Vulkan_Draw##Type (ent, rFrame); \ /* unhack in case the view_model is not the last */\ if (ent == vr_data.view_model) { \ - Vulkan_AliasDepthRange (ctx, 0, 1); \ + Vulkan_AliasDepthRange (rFrame, 0, 1); \ } \ } \ if (begun) \ - Vulkan_##Type##End (ctx); \ + Vulkan_##Type##End (rFrame); \ } while (0) RE_LOOP (alias, Alias); @@ -152,8 +153,9 @@ Vulkan_DrawViewModel (vulkan_ctx_t *ctx) } void -Vulkan_RenderView (vulkan_ctx_t *ctx) +Vulkan_RenderView (qfv_renderframe_t *rFrame) { + vulkan_ctx_t *ctx = rFrame->vulkan_ctx; double t[9] = {}; int speeds = r_speeds->int_val; @@ -173,17 +175,17 @@ Vulkan_RenderView (vulkan_ctx_t *ctx) R_PushDlights (vec3_origin); if (speeds) t[3] = Sys_DoubleTime (); - Vulkan_DrawWorld (ctx); + Vulkan_DrawWorld (rFrame); if (speeds) t[4] = Sys_DoubleTime (); - Vulkan_DrawSky (ctx); + Vulkan_DrawSky (rFrame); if (speeds) t[5] = Sys_DoubleTime (); Vulkan_DrawViewModel (ctx); - Vulkan_RenderEntities (ctx); + Vulkan_RenderEntities (rFrame); if (speeds) t[6] = Sys_DoubleTime (); - Vulkan_DrawWaterSurfaces (ctx); + Vulkan_DrawWaterSurfaces (rFrame); if (speeds) t[7] = Sys_DoubleTime (); Vulkan_DrawParticles (ctx); diff --git a/libs/video/renderer/vulkan/vulkan_vid_common.c b/libs/video/renderer/vulkan/vulkan_vid_common.c index 01b991e9d..384cd8b16 100644 --- a/libs/video/renderer/vulkan/vulkan_vid_common.c +++ b/libs/video/renderer/vulkan/vulkan_vid_common.c @@ -66,6 +66,13 @@ #include "QF/Vulkan/staging.h" #include "QF/Vulkan/swapchain.h" +#include "QF/Vulkan/qf_alias.h" +#include "QF/Vulkan/qf_bsp.h" +#include "QF/Vulkan/qf_compose.h" +#include "QF/Vulkan/qf_draw.h" +#include "QF/Vulkan/qf_lighting.h" +#include "QF/Vulkan/qf_main.h" + #include "compat.h" #include "d_iface.h" #include "r_internal.h" @@ -212,7 +219,6 @@ void Vulkan_Shutdown_Common (vulkan_ctx_t *ctx) { PL_Free (ctx->pipelineDef); - PL_Free (ctx->renderpassDef); if (ctx->capture) { QFV_DestroyCapture (ctx->capture); } @@ -297,14 +303,14 @@ qfv_load_pipeline (vulkan_ctx_t *ctx, const char *name) } static plitem_t * -qfv_load_renderpass (vulkan_ctx_t *ctx, const char *name) +qfv_load_renderpass (vulkan_ctx_t *ctx, qfv_renderpass_t *rp, const char *name) { - if (!ctx->renderpassDef) { - ctx->renderpassDef = PL_GetPropertyList (quakeforge_renderpass, - &ctx->hashlinks); + if (!rp->renderpassDef) { + rp->renderpassDef = PL_GetPropertyList (quakeforge_renderpass, + &ctx->hashlinks); } - plitem_t *item = ctx->renderpassDef; + plitem_t *item = rp->renderpassDef; if (!item || !(item = PL_ObjectForKey (item, name))) { Sys_Printf ("error loading %s\n", name); } else { @@ -328,29 +334,121 @@ get_image_size (VkImage image, qfv_device_t *device) return size; } +static void +renderpass_draw (qfv_renderframe_t *rFrame) +{ + Vulkan_RenderView (rFrame); + Vulkan_FlushText (rFrame); + Vulkan_Lighting_Draw (rFrame); + Vulkan_Compose_Draw (rFrame); +} + +static void +create_attachements (vulkan_ctx_t *ctx, qfv_renderpass_t *rp) +{ + qfv_device_t *device = ctx->device; + + plitem_t *item = qfv_load_renderpass (ctx, rp, "images"); + if (!item) { + return; + } + + __auto_type images = QFV_ParseImageSet (ctx, item, rp->renderpassDef); + rp->attachment_images = images; + size_t memSize = 0; + for (size_t i = 0; i < images->size; i++) { + memSize += get_image_size (images->a[i], device); + } + VkDeviceMemory mem; + mem = QFV_AllocImageMemory (device, images->a[0], + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + memSize, 0); + rp->attachmentMemory = mem; + QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY, + mem, "memory:framebuffers"); + size_t offset = 0; + for (size_t i = 0; i < images->size; i++) { + QFV_BindImageMemory (device, images->a[i], mem, offset); + offset += get_image_size (images->a[i], device); + } + + item = qfv_load_renderpass (ctx, rp, "imageViews"); + if (!item) { + return; + } + + __auto_type views = QFV_ParseImageViewSet (ctx, item, rp->renderpassDef); + rp->attachment_views = views; + + item = qfv_load_renderpass (ctx, rp, "framebuffer"); + if (!item) { + return; + } + + rp->framebuffers = QFV_AllocFrameBuffers (ctx->swapchain->numImages, + malloc); + for (size_t i = 0; i < rp->framebuffers->size; i++) { + ctx->swapImageIndex = i; // for $swapImageIndex in the config + rp->framebuffers->a[i] = QFV_ParseFramebuffer (ctx, item, + rp->renderpassDef); + } +} + +static void +init_renderframe (vulkan_ctx_t *ctx, qfv_renderpass_t *rp, + qfv_renderframe_t *rFrame) +{ + rFrame->subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; + rFrame->vulkan_ctx = ctx; + rFrame->renderpass = rp; + rFrame->subpassCount = QFV_NumPasses; + rFrame->subpassCmdSets = malloc (QFV_NumPasses + * sizeof (qfv_cmdbufferset_t)); + for (int j = 0; j < QFV_NumPasses; j++) { + DARRAY_INIT (&rFrame->subpassCmdSets[j], 4); + } +} + void Vulkan_CreateRenderPass (vulkan_ctx_t *ctx) { const char *name = "renderpass";//FIXME + plitem_t *item; + + qfv_renderpass_t *rp = calloc (1, sizeof (qfv_renderpass_t)); hashtab_t *tab = ctx->renderpasses; const char *path; path = va (ctx->va_ctx, "$"QFV_PROPERTIES".%s", name); __auto_type renderpass = (VkRenderPass) QFV_GetHandle (tab, path); if (renderpass) { - ctx->renderpass = renderpass; - return; + rp->renderpass = renderpass; + } else { + item = qfv_load_renderpass (ctx, rp, name); + rp->renderpass = QFV_ParseRenderPass (ctx, item, rp->renderpassDef); + QFV_AddHandle (tab, path, (uint64_t) rp->renderpass); + QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_RENDER_PASS, + rp->renderpass, va (ctx->va_ctx, "renderpass:%s", + name)); } - plitem_t *item = qfv_load_renderpass (ctx, name); + DARRAY_INIT (&rp->frames, 4); + DARRAY_RESIZE (&rp->frames, ctx->frames.size); + for (size_t i = 0; i < rp->frames.size; i++) { + init_renderframe (ctx, rp, &rp->frames.a[i]); + } - ctx->renderpass = QFV_ParseRenderPass (ctx, item, ctx->renderpassDef); - QFV_AddHandle (tab, path, (uint64_t) ctx->renderpass); - QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_RENDER_PASS, - ctx->renderpass, va (ctx->va_ctx, "renderpass:%s", - name)); - item = qfv_load_renderpass (ctx, "clearValues"); - QFV_ParseClearValues (ctx, item, ctx->renderpassDef); + create_attachements (ctx, rp); + + item = qfv_load_renderpass (ctx, rp, "clearValues"); + rp->clearValues = QFV_ParseClearValues (ctx, item, rp->renderpassDef); + + rp->draw = renderpass_draw; + + if (!ctx->renderPasses.grow) { + DARRAY_INIT (&ctx->renderPasses, 4); + } + DARRAY_APPEND (&ctx->renderPasses, rp); qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; @@ -390,13 +488,63 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx) QFV_PacketSubmit (packet); } -void -Vulkan_DestroyRenderPass (vulkan_ctx_t *ctx) +static void +destroy_attachments (vulkan_ctx_t *ctx, qfv_renderpass_t *rp) { qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; - dfunc->vkDestroyRenderPass (device->dev, ctx->renderpass, 0); + for (size_t i = 0; i < rp->attachment_views->size; i++) { + dfunc->vkDestroyImageView (device->dev, rp->attachment_views->a[i], 0); + } + for (size_t i = 0; i < rp->attachment_images->size; i++) { + dfunc->vkDestroyImage (device->dev, rp->attachment_images->a[i], 0); + } + dfunc->vkFreeMemory (device->dev, rp->attachmentMemory, 0); +} + +static void +destroy_renderframes (vulkan_ctx_t *ctx, qfv_renderpass_t *rp) +{ + for (size_t i = 0; i < rp->frames.size; i++) { + __auto_type rFrame = &rp->frames.a[i]; + for (int j = 0; j < rFrame->subpassCount; j++) { + DARRAY_CLEAR (&rFrame->subpassCmdSets[j]); + } + free (rFrame->subpassCmdSets); + } +} + +static void +destroy_framebuffers (vulkan_ctx_t *ctx, qfv_renderpass_t *rp) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + for (size_t i = 0; i < rp->framebuffers->size; i++) { + dfunc->vkDestroyFramebuffer (device->dev, rp->framebuffers->a[i], 0); + } + free (rp->framebuffers); +} + +void +Vulkan_DestroyRenderPasses (vulkan_ctx_t *ctx) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + for (size_t i = 0; i < ctx->renderPasses.size; i++) { + __auto_type rp = ctx->renderPasses.a[i]; + + PL_Free (rp->renderpassDef); + + destroy_attachments (ctx, rp); + dfunc->vkDestroyRenderPass (device->dev, rp->renderpass, 0); + destroy_renderframes (ctx, rp); + destroy_framebuffers (ctx, rp); + + free (rp); + } dfunc->vkFreeMemory (device->dev, ctx->quad_memory, 0); dfunc->vkDestroyBuffer (device->dev, ctx->quad_buffer, 0); @@ -544,12 +692,6 @@ Vulkan_CreateFrames (vulkan_ctx_t *ctx) frame->imageAvailableSemaphore = QFV_CreateSemaphore (device); frame->renderDoneSemaphore = QFV_CreateSemaphore (device); frame->cmdBuffer = cmdBuffers->a[i]; - - frame->cmdSetCount = QFV_NumPasses; - frame->cmdSets = malloc (QFV_NumPasses * sizeof (qfv_cmdbufferset_t)); - for (int j = 0; j < QFV_NumPasses; j++) { - DARRAY_INIT (&frame->cmdSets[j], 4); - } } } @@ -573,82 +715,7 @@ Vulkan_DestroyFrames (vulkan_ctx_t *ctx) df->vkDestroySemaphore (dev, frame->imageAvailableSemaphore, 0); df->vkDestroySemaphore (dev, frame->renderDoneSemaphore, 0); frame->framebuffer = 0; - for (int j = 0; j < frame->cmdSetCount; j++) { - DARRAY_CLEAR (&frame->cmdSets[j]); - } - free (frame->cmdSets); } DARRAY_CLEAR (&ctx->frames); - - for (size_t i = 0; i < ctx->framebuffers->size; i++) { - df->vkDestroyFramebuffer (dev, ctx->framebuffers->a[i], 0); - } - free (ctx->framebuffers); -} - -void -Vulkan_CreateFramebuffers (vulkan_ctx_t *ctx) -{ - qfv_device_t *device = ctx->device; - - plitem_t *item = qfv_load_renderpass (ctx, "images"); - if (!item) { - return; - } - - __auto_type images = QFV_ParseImageSet (ctx, item, ctx->renderpassDef); - ctx->attachment_images = images; - size_t memSize = 0; - for (size_t i = 0; i < images->size; i++) { - memSize += get_image_size (images->a[i], device); - } - VkDeviceMemory mem; - mem = QFV_AllocImageMemory (device, images->a[0], - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - memSize, 0); - ctx->attachmentMemory = mem; - QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY, - mem, "memory:framebuffers"); - size_t offset = 0; - for (size_t i = 0; i < images->size; i++) { - QFV_BindImageMemory (device, images->a[i], mem, offset); - offset += get_image_size (images->a[i], device); - } - - item = qfv_load_renderpass (ctx, "imageViews"); - if (!item) { - return; - } - - __auto_type views = QFV_ParseImageViewSet (ctx, item, ctx->renderpassDef); - ctx->attachment_views = views; - - item = qfv_load_renderpass (ctx, "framebuffer"); - if (!item) { - return; - } - - ctx->framebuffers = QFV_AllocFrameBuffers (ctx->swapchain->numImages, - malloc); - for (size_t i = 0; i < ctx->framebuffers->size; i++) { - ctx->swapImageIndex = i; - ctx->framebuffers->a[i] = QFV_ParseFramebuffer (ctx, item, - ctx->renderpassDef); - } -} - -void -Vulkan_DestroyFramebuffers (vulkan_ctx_t *ctx) -{ - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; - - for (size_t i = 0; i < ctx->attachment_views->size; i++) { - dfunc->vkDestroyImageView (device->dev, ctx->attachment_views->a[i], 0); - } - for (size_t i = 0; i < ctx->attachment_images->size; i++) { - dfunc->vkDestroyImage (device->dev, ctx->attachment_images->a[i], 0); - } - dfunc->vkFreeMemory (device->dev, ctx->attachmentMemory, 0); }