diff --git a/include/QF/Vulkan/qf_alias.h b/include/QF/Vulkan/qf_alias.h index 205510afc..fe18c278a 100644 --- a/include/QF/Vulkan/qf_alias.h +++ b/include/QF/Vulkan/qf_alias.h @@ -100,7 +100,5 @@ void Vulkan_AliasAddSkin (struct vulkan_ctx_s *ctx, qfv_alias_skin_t *skin); void Vulkan_AliasRemoveSkin (struct vulkan_ctx_s *ctx, qfv_alias_skin_t *skin); void Vulkan_Alias_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Alias_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Alias_Shutdown (struct vulkan_ctx_s *ctx); #endif//__QF_Vulkan_qf_alias_h diff --git a/include/QF/Vulkan/qf_bsp.h b/include/QF/Vulkan/qf_bsp.h index 1979f96d8..2f0dfa2aa 100644 --- a/include/QF/Vulkan/qf_bsp.h +++ b/include/QF/Vulkan/qf_bsp.h @@ -401,8 +401,6 @@ void Vulkan_RegisterTextures (model_t **models, int num_models, 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_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx); bsp_pass_t *Vulkan_Bsp_GetPass (struct vulkan_ctx_s *ctx, QFV_BspPass pass_ind); ///@} diff --git a/include/QF/Vulkan/qf_compose.h b/include/QF/Vulkan/qf_compose.h index 4c1a42adb..349b2abcf 100644 --- a/include/QF/Vulkan/qf_compose.h +++ b/include/QF/Vulkan/qf_compose.h @@ -53,7 +53,5 @@ typedef struct composectx_s { struct vulkan_ctx_s; void Vulkan_Compose_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Compose_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Compose_Shutdown (struct vulkan_ctx_s *ctx); #endif//__QF_Vulkan_qf_compose_h diff --git a/include/QF/Vulkan/qf_draw.h b/include/QF/Vulkan/qf_draw.h index 94d80aeaf..9f26359f1 100644 --- a/include/QF/Vulkan/qf_draw.h +++ b/include/QF/Vulkan/qf_draw.h @@ -38,8 +38,6 @@ struct draw_charbuffer_s; void Vulkan_Draw_CharBuffer (int x, int y, struct draw_charbuffer_s *buffer, struct vulkan_ctx_s *ctx); void Vulkan_Draw_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Draw_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Draw_Shutdown (struct vulkan_ctx_s *ctx); void Vulkan_Draw_Character (int x, int y, unsigned ch, struct vulkan_ctx_s *ctx); void Vulkan_Draw_String (int x, int y, const char *str, diff --git a/include/QF/Vulkan/qf_iqm.h b/include/QF/Vulkan/qf_iqm.h index d39051882..6ee00acdf 100644 --- a/include/QF/Vulkan/qf_iqm.h +++ b/include/QF/Vulkan/qf_iqm.h @@ -107,7 +107,5 @@ void Vulkan_IQMAddSkin (struct vulkan_ctx_s *ctx, qfv_iqm_skin_t *skin); void Vulkan_IQMRemoveSkin (struct vulkan_ctx_s *ctx, qfv_iqm_skin_t *skin); void Vulkan_IQM_Init (struct vulkan_ctx_s *ctx); -void Vulkan_IQM_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_IQM_Shutdown (struct vulkan_ctx_s *ctx); #endif//__QF_Vulkan_qf_iqm_h diff --git a/include/QF/Vulkan/qf_lighting.h b/include/QF/Vulkan/qf_lighting.h index 412f7b454..2da60da63 100644 --- a/include/QF/Vulkan/qf_lighting.h +++ b/include/QF/Vulkan/qf_lighting.h @@ -174,8 +174,6 @@ typedef struct lightingctx_s { struct vulkan_ctx_s; void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Lighting_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx); void Vulkan_LoadLights (struct scene_s *scene, struct vulkan_ctx_s *ctx); VkDescriptorSet Vulkan_Lighting_Descriptors (struct vulkan_ctx_s *ctx, int frame) __attribute__((pure)); diff --git a/include/QF/Vulkan/qf_matrices.h b/include/QF/Vulkan/qf_matrices.h index c83fa8b83..7b17959bc 100644 --- a/include/QF/Vulkan/qf_matrices.h +++ b/include/QF/Vulkan/qf_matrices.h @@ -78,8 +78,6 @@ void Vulkan_SetSkyMatrix (struct vulkan_ctx_s *ctx, mat4f_t sky); void Vulkan_SetSkyMatrix (struct vulkan_ctx_s *ctx, mat4f_t sky); void Vulkan_Matrix_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Matrix_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Matrix_Shutdown (struct vulkan_ctx_s *ctx); VkDescriptorSet Vulkan_Matrix_Descriptors (struct vulkan_ctx_s *ctx, int frame) __attribute__((pure)); diff --git a/include/QF/Vulkan/qf_output.h b/include/QF/Vulkan/qf_output.h index eecd2c6b2..21c6c1109 100644 --- a/include/QF/Vulkan/qf_output.h +++ b/include/QF/Vulkan/qf_output.h @@ -54,7 +54,5 @@ typedef struct outputctx_s { struct vulkan_ctx_s; void Vulkan_Output_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Output_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Output_Shutdown (struct vulkan_ctx_s *ctx); #endif//__QF_Vulkan_qf_output_h diff --git a/include/QF/Vulkan/qf_palette.h b/include/QF/Vulkan/qf_palette.h index c1c1a4b33..bafb35377 100644 --- a/include/QF/Vulkan/qf_palette.h +++ b/include/QF/Vulkan/qf_palette.h @@ -44,8 +44,7 @@ typedef struct palettectx_s { struct vulkan_ctx_s; void Vulkan_Palette_Update (struct vulkan_ctx_s *ctx, const byte *palette); -void Vulkan_Palette_Init (struct vulkan_ctx_s *ctx, const byte *palette); -void Vulkan_Palette_Shutdown (struct vulkan_ctx_s *ctx); +void Vulkan_Palette_Init (struct vulkan_ctx_s *ctx); VkDescriptorSet Vulkan_Palette_Descriptor (struct vulkan_ctx_s *ctx) __attribute__((pure)); #endif//__QF_Vulkan_qf_palette_h diff --git a/include/QF/Vulkan/qf_particles.h b/include/QF/Vulkan/qf_particles.h index 72d07eee5..2948eebd7 100644 --- a/include/QF/Vulkan/qf_particles.h +++ b/include/QF/Vulkan/qf_particles.h @@ -58,7 +58,5 @@ struct vulkan_ctx_s; struct psystem_s *Vulkan_ParticleSystem (struct vulkan_ctx_s *ctx); void Vulkan_Particles_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Particles_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Particles_Shutdown (struct vulkan_ctx_s *ctx); #endif//__QF_Vulkan_qf_particles_h diff --git a/include/QF/Vulkan/qf_planes.h b/include/QF/Vulkan/qf_planes.h index 81c2c6a77..6e5b9d275 100644 --- a/include/QF/Vulkan/qf_planes.h +++ b/include/QF/Vulkan/qf_planes.h @@ -56,7 +56,5 @@ struct mod_planes_ctx_s; struct planes_s; void Vulkan_Planes_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Planes_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Planes_Shutdown (struct vulkan_ctx_s *ctx); #endif//__QF_Vulkan_qf_planes_h diff --git a/include/QF/Vulkan/qf_scene.h b/include/QF/Vulkan/qf_scene.h index 456e2cad5..b43cd789d 100644 --- a/include/QF/Vulkan/qf_scene.h +++ b/include/QF/Vulkan/qf_scene.h @@ -71,8 +71,6 @@ struct vulkan_ctx_s; struct entity_s; void Vulkan_Scene_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Scene_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Scene_Shutdown (struct vulkan_ctx_s *ctx); int Vulkan_Scene_MaxEntities (struct vulkan_ctx_s *ctx) __attribute__((pure)); VkDescriptorSet Vulkan_Scene_Descriptors (struct vulkan_ctx_s *ctx) __attribute__((pure)); int Vulkan_Scene_AddEntity (struct vulkan_ctx_s *ctx, struct entity_s entity); diff --git a/include/QF/Vulkan/qf_sprite.h b/include/QF/Vulkan/qf_sprite.h index 57520dbd6..932afca3b 100644 --- a/include/QF/Vulkan/qf_sprite.h +++ b/include/QF/Vulkan/qf_sprite.h @@ -76,7 +76,5 @@ void Vulkan_Mod_SpriteLoadFrames (struct mod_sprite_ctx_s *sprite_ctx, struct vulkan_ctx_s *ctx); void Vulkan_Sprite_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Sprite_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Sprite_Shutdown (struct vulkan_ctx_s *ctx); #endif//__QF_Vulkan_qf_sprite_h diff --git a/include/QF/Vulkan/qf_texture.h b/include/QF/Vulkan/qf_texture.h index 835ee624c..6035d38ed 100644 --- a/include/QF/Vulkan/qf_texture.h +++ b/include/QF/Vulkan/qf_texture.h @@ -29,8 +29,6 @@ void Vulkan_UpdateTex (struct vulkan_ctx_s *ctx, qfv_tex_t *tex, tex_t *src, int x, int y, int layer, int mip); void Vulkan_UnloadTex (struct vulkan_ctx_s *ctx, qfv_tex_t *tex); void Vulkan_Texture_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Texture_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Texture_Shutdown (struct vulkan_ctx_s *ctx); VkDescriptorSet Vulkan_CreateCombinedImageSampler (struct vulkan_ctx_s *ctx, VkImageView view, VkSampler sampler); diff --git a/include/QF/Vulkan/qf_translucent.h b/include/QF/Vulkan/qf_translucent.h index be5020b57..8d38fd6d5 100644 --- a/include/QF/Vulkan/qf_translucent.h +++ b/include/QF/Vulkan/qf_translucent.h @@ -43,8 +43,6 @@ typedef struct translucentctx_s { struct vulkan_ctx_s; void Vulkan_Translucent_Init (struct vulkan_ctx_s *ctx); -void Vulkan_Translucent_Setup (struct vulkan_ctx_s *ctx); -void Vulkan_Translucent_Shutdown (struct vulkan_ctx_s *ctx); VkDescriptorSet Vulkan_Translucent_Descriptors (struct vulkan_ctx_s *ctx, int frame)__attribute__((pure)); diff --git a/include/QF/Vulkan/render.h b/include/QF/Vulkan/render.h index dfde03061..bb9912d4f 100644 --- a/include/QF/Vulkan/render.h +++ b/include/QF/Vulkan/render.h @@ -274,8 +274,10 @@ typedef struct qfv_jobinfo_s { uint32_t num_dslayouts; qfv_descriptorsetlayoutinfo_t *dslayouts; - uint32_t newscene_num_tasks; qfv_taskinfo_t *newscene_tasks; + uint32_t newscene_num_tasks; + uint32_t init_num_tasks; + qfv_taskinfo_t *init_tasks; } qfv_jobinfo_t; typedef struct qfv_samplercreateinfo_s { @@ -400,12 +402,13 @@ typedef struct qfv_step_s { qfv_time_t time; } qfv_step_t; +typedef void (*qfv_initfunc_f) (exprctx_t *ectx); +typedef struct qfv_initfuncset_s + DARRAY_TYPE (qfv_initfunc_f) qfv_initfuncset_t; + typedef struct qfv_job_s { qfv_label_t label; - uint32_t newscene_task_count; - qfv_taskinfo_t *newscene_tasks; - uint32_t num_renderpasses; uint32_t num_pipelines; uint32_t num_layouts; @@ -418,6 +421,14 @@ typedef struct qfv_job_s { uint32_t num_dsmanagers; struct qfv_dsmanager_s **dsmanager; qfv_time_t time; + + qfv_taskinfo_t *newscene_tasks; + qfv_taskinfo_t *init_tasks; + uint32_t newscene_task_count; + uint32_t init_task_count; + qfv_initfuncset_t startup_funcs; + qfv_initfuncset_t shutdown_funcs; + qfv_initfuncset_t clearstate_funcs; } qfv_job_t; typedef struct qfv_renderframe_s { @@ -467,8 +478,14 @@ void QFV_LoadRenderInfo (struct vulkan_ctx_s *ctx, struct plitem_s *item); void QFV_LoadSamplerInfo (struct vulkan_ctx_s *ctx, struct plitem_s *item); void QFV_BuildRender (struct vulkan_ctx_s *ctx); void QFV_Render_Init (struct vulkan_ctx_s *ctx); +void QFV_Render_Run_Init (struct vulkan_ctx_s *ctx); +void QFV_Render_Run_Startup (struct vulkan_ctx_s *ctx); +void QFV_Render_Run_ClearState (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_AddStartup (struct vulkan_ctx_s *ctx, qfv_initfunc_f func); +void QFV_Render_AddShutdown (struct vulkan_ctx_s *ctx, qfv_initfunc_f func); +void QFV_Render_AddClearState (struct vulkan_ctx_s *ctx, qfv_initfunc_f func); void QFV_Render_AddAttachments (struct vulkan_ctx_s *ctx, uint32_t num_attachments, qfv_attachmentinfo_t **attachments); diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index bd4f37548..695d53653 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -106,6 +106,7 @@ vulkan_R_Init (struct plitem_s *config) Vulkan_CreateStagingBuffers (vulkan_ctx); Vulkan_Texture_Init (vulkan_ctx); + Vulkan_Palette_Init (vulkan_ctx); Vulkan_CreateSwapchain (vulkan_ctx); @@ -131,27 +132,11 @@ vulkan_R_Init (struct plitem_s *config) const char *mode = vulkan_render_mode ? "main_def" : "main_fwd"; auto render_graph = Vulkan_GetConfig (vulkan_ctx, mode); auto samplers = Vulkan_GetConfig (vulkan_ctx, "smp_quake"); - QFV_LoadRenderInfo (vulkan_ctx, render_graph); QFV_LoadSamplerInfo (vulkan_ctx, samplers); + QFV_LoadRenderInfo (vulkan_ctx, render_graph); } QFV_BuildRender (vulkan_ctx); - Vulkan_Texture_Setup (vulkan_ctx); - Vulkan_Palette_Init (vulkan_ctx, vid.palette); - Vulkan_Alias_Setup (vulkan_ctx); - Vulkan_Bsp_Setup (vulkan_ctx); - Vulkan_IQM_Setup (vulkan_ctx); - Vulkan_Matrix_Setup (vulkan_ctx); - Vulkan_Scene_Setup (vulkan_ctx); - Vulkan_Sprite_Setup (vulkan_ctx); - Vulkan_Output_Setup (vulkan_ctx); - Vulkan_Compose_Setup (vulkan_ctx); - Vulkan_Draw_Setup (vulkan_ctx); - Vulkan_Particles_Setup (vulkan_ctx); - Vulkan_Planes_Setup (vulkan_ctx); - Vulkan_Translucent_Setup (vulkan_ctx); - Vulkan_Lighting_Setup (vulkan_ctx); - Skin_Init (); SCR_Init (); @@ -166,7 +151,7 @@ vulkan_R_ClearState (void) r_refdef.worldmodel = 0; EntQueue_Clear (r_ent_queue); R_ClearParticles (); - Vulkan_LoadLights (0, vulkan_ctx); + QFV_Render_Run_ClearState (vulkan_ctx); } static void @@ -584,25 +569,8 @@ vulkan_vid_render_shutdown (void) SCR_Shutdown (); Mod_ClearAll (); - Vulkan_Compose_Shutdown (vulkan_ctx); - Vulkan_Translucent_Shutdown (vulkan_ctx); - Vulkan_Lighting_Shutdown (vulkan_ctx); - Vulkan_Draw_Shutdown (vulkan_ctx); - Vulkan_Sprite_Shutdown (vulkan_ctx); - Vulkan_Planes_Shutdown (vulkan_ctx); - Vulkan_Particles_Shutdown (vulkan_ctx); - Vulkan_IQM_Shutdown (vulkan_ctx); - Vulkan_Bsp_Shutdown (vulkan_ctx); - Vulkan_Alias_Shutdown (vulkan_ctx); - Vulkan_Scene_Shutdown (vulkan_ctx); - Vulkan_Matrix_Shutdown (vulkan_ctx); - QFV_MousePick_Shutdown (vulkan_ctx); QFV_Capture_Shutdown (vulkan_ctx); - Vulkan_Output_Shutdown (vulkan_ctx); - - Vulkan_Palette_Shutdown (vulkan_ctx); - Vulkan_Texture_Shutdown (vulkan_ctx); QFV_Render_Shutdown (vulkan_ctx); diff --git a/libs/video/renderer/vulkan/render.c b/libs/video/renderer/vulkan/render.c index d9eae2a19..ec3588ba8 100644 --- a/libs/video/renderer/vulkan/render.c +++ b/libs/video/renderer/vulkan/render.c @@ -618,14 +618,63 @@ tf_free_syms (void *_sym, void *data) } } +void +QFV_Render_Run_Init (vulkan_ctx_t *ctx) +{ + auto rctx = ctx->render_context; + if (rctx->job) { + qfv_taskctx_t taskctx = { + .ctx = ctx, + }; + auto job = rctx->job; + run_tasks (job->init_task_count, job->init_tasks, &taskctx); + } +} + +void +QFV_Render_Run_Startup (vulkan_ctx_t *ctx) +{ + auto rctx = ctx->render_context; + if (rctx->job) { + qfv_taskctx_t taskctx = { + .ctx = ctx, + }; + auto job = rctx->job; + for (size_t i = 0; i < job->startup_funcs.size; i++) { + job->startup_funcs.a[i] ((exprctx_t *) &taskctx); + } + } +} + +void +QFV_Render_Run_ClearState (vulkan_ctx_t *ctx) +{ + auto rctx = ctx->render_context; + if (rctx->job) { + qfv_taskctx_t taskctx = { + .ctx = ctx, + }; + auto job = rctx->job; + for (size_t i = 0; i < job->clearstate_funcs.size; i++) { + job->clearstate_funcs.a[i] ((exprctx_t *) &taskctx); + } + } +} + void QFV_Render_Shutdown (vulkan_ctx_t *ctx) { qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; - __auto_type rctx = ctx->render_context; + auto rctx = ctx->render_context; if (rctx->job) { - __auto_type job = rctx->job; + qfv_taskctx_t taskctx = { + .ctx = ctx, + }; + auto job = rctx->job; + for (size_t i = job->shutdown_funcs.size; i-- > 0; ) { + job->shutdown_funcs.a[i] ((exprctx_t *) &taskctx); + } for (uint32_t i = 0; i < job->num_renderpasses; i++) { dfunc->vkDestroyRenderPass (device->dev, job->renderpasses[i], 0); } @@ -703,8 +752,8 @@ void QFV_Render_AddTasks (vulkan_ctx_t *ctx, exprsym_t *task_syms) { qfZoneScoped (true); - __auto_type rctx = ctx->render_context; - exprctx_t ectx = { .hashctx = &rctx->hashctx }; + auto rctx = ctx->render_context; + exprctx_t ectx = { .hashctx = &rctx->hashctx }; for (exprsym_t *sym = task_syms; sym->name; sym++) { Hash_Add (rctx->task_functions.tab, sym); for (exprfunc_t *f = sym->value; f->func; f++) { @@ -718,6 +767,27 @@ QFV_Render_AddTasks (vulkan_ctx_t *ctx, exprsym_t *task_syms) } } +void +QFV_Render_AddStartup (vulkan_ctx_t *ctx, qfv_initfunc_f func) +{ + auto rctx = ctx->render_context; + DARRAY_APPEND (&rctx->job->startup_funcs, func); +} + +void +QFV_Render_AddShutdown (vulkan_ctx_t *ctx, qfv_initfunc_f func) +{ + auto rctx = ctx->render_context; + DARRAY_APPEND (&rctx->job->shutdown_funcs, func); +} + +void +QFV_Render_AddClearState (vulkan_ctx_t *ctx, qfv_initfunc_f func) +{ + auto rctx = ctx->render_context; + DARRAY_APPEND (&rctx->job->clearstate_funcs, func); +} + void QFV_Render_AddAttachments (vulkan_ctx_t *ctx, uint32_t num_attachments, qfv_attachmentinfo_t **attachments) diff --git a/libs/video/renderer/vulkan/render_load.c b/libs/video/renderer/vulkan/render_load.c index f7ec33189..5e5a74346 100644 --- a/libs/video/renderer/vulkan/render_load.c +++ b/libs/video/renderer/vulkan/render_load.c @@ -222,6 +222,7 @@ count_stuff (qfv_jobinfo_t *jobinfo, objcount_t *counts) count_step_stuff (&jobinfo->steps[i], counts); } counts->num_tasks += jobinfo->newscene_num_tasks; + counts->num_tasks += jobinfo->init_num_tasks; } static qfv_imageinfo_t * __attribute__((pure)) @@ -979,14 +980,13 @@ init_step (uint32_t ind, jobptr_t *jp, objstate_t *s) } } -static void -init_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t s) +static jobptr_t +create_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t *s) { auto rctx = ctx->render_context; auto jobinfo = rctx->jobinfo; size_t size = sizeof (qfv_job_t); - size += sizeof (qfv_step_t [counts->num_steps]); size += sizeof (qfv_render_t [counts->num_render]); size += sizeof (qfv_compute_t [counts->num_compute]); @@ -1001,7 +1001,7 @@ init_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t s) size += sizeof (VkRenderPass [counts->num_renderpasses]); size += sizeof (VkPipeline [counts->num_graph_pipelines]); size += sizeof (VkPipeline [counts->num_comp_pipelines]); - size += sizeof (VkPipelineLayout [s.inds.num_layouts]); + size += sizeof (VkPipelineLayout [counts->num_layouts]); size += sizeof (VkImageView [counts->num_attachments]); size += sizeof (qfv_dsmanager_t *[jobinfo->num_dslayouts]); size += sizeof (uint32_t [counts->num_ds_indices]); @@ -1012,10 +1012,13 @@ init_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t s) .num_renderpasses = counts->num_renderpasses, .num_pipelines = counts->num_graph_pipelines + counts->num_comp_pipelines, - .num_layouts = s.inds.num_layouts, + .num_layouts = s->inds.num_layouts, .num_steps = counts->num_steps, .commands = DARRAY_STATIC_INIT (16), .num_dsmanagers = jobinfo->num_dslayouts, + .startup_funcs = DARRAY_STATIC_INIT (16), + .shutdown_funcs = DARRAY_STATIC_INIT (16), + .clearstate_funcs = DARRAY_STATIC_INIT (16), }; job->steps = (qfv_step_t *) &job[1]; auto rn = (qfv_render_t *) &job->steps[job->num_steps]; @@ -1030,11 +1033,11 @@ init_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t s) job->renderpasses = (VkRenderPass *) &cv[counts->num_attachments]; job->pipelines = (VkPipeline *) &job->renderpasses[job->num_renderpasses]; job->layouts = (VkPipelineLayout *) &job->pipelines[job->num_pipelines]; - auto av = (VkImageView *) &job->layouts[s.inds.num_layouts]; + auto av = (VkImageView *) &job->layouts[counts->num_layouts]; job->dsmanager = (qfv_dsmanager_t **) &av[counts->num_attachments]; auto ds = (uint32_t *) &job->dsmanager[jobinfo->num_dslayouts]; - jobptr_t jp = { + return (jobptr_t) { .steps = job->steps, .renders = rn, .computes = cp, @@ -1047,33 +1050,38 @@ init_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t s) .ds_indices = ds, .attachment_views = av, }; +} + +static void +init_job (vulkan_ctx_t *ctx, objcount_t *counts, jobptr_t jp, objstate_t *s) +{ + auto rctx = ctx->render_context; + auto job = rctx->job; + auto jobinfo = rctx->jobinfo; for (uint32_t i = 0; i < job->num_renderpasses; i++) { - job->renderpasses[i] = s.ptr.rp[i]; + job->renderpasses[i] = s->ptr.rp[i]; } for (uint32_t i = 0; i < job->num_pipelines; i++) { // compute pipelines come immediately after the graphics pipelines - job->pipelines[i] = s.ptr.gpl[i]; + job->pipelines[i] = s->ptr.gpl[i]; } - for (uint32_t i = 0; i < s.inds.num_layouts; i++) { - job->layouts[i] = s.ptr.layouts[i].layout; + for (uint32_t i = 0; i < s->inds.num_layouts; i++) { + job->layouts[i] = s->ptr.layouts[i].layout; } - memcpy (cv, s.ptr.clear, sizeof (VkClearValue [counts->num_attachments ])); + for (uint32_t i = s->inds.num_layouts; i < counts->num_layouts; i++) { + job->layouts[i] = nullptr; + } + auto cv = jp.clearvalues; + memcpy (cv, s->ptr.clear, sizeof (VkClearValue [counts->num_attachments ])); - uint32_t num_layouts = s.inds.num_layouts; - s.inds = (objcount_t) {}; - s.inds.num_layouts = num_layouts; for (uint32_t i = 0; i < job->num_steps; i++) { - init_step (i, &jp, &s); + init_step (i, &jp, s); } for (uint32_t i = 0; i < job->num_dsmanagers; i++) { auto layoutInfo = &jobinfo->dslayouts[i]; job->dsmanager[i] = QFV_DSManager_Create (layoutInfo, 16, ctx); } - - init_tasks (&job->newscene_task_count, &job->newscene_tasks, - jobinfo->newscene_num_tasks, jobinfo->newscene_tasks, - &jp, &s); } static void @@ -1137,6 +1145,86 @@ del_objstate (void *_state) free (state->symtab); } +static void +create_pipeline_layout (const qfv_pipelineinfo_t *pli, objstate_t *s) +{ + if (pli->layout.name) { + __auto_type li = find_layout (&pli->layout, s); + s->inds.num_ds_indices += li->num_sets; + } +} + +static void +create_subpass_layouts (uint32_t index, qfv_subpassinfo_t *sub, objstate_t *s) +{ + auto spi = &sub[index]; + s->plc = &s->ptr.gplCreate[s->inds.num_graph_pipelines]; + s->spc = &s->ptr.subpass[s->inds.num_subpasses]; + + for (uint32_t i = 0; i < spi->num_pipelines; i++) { + if (spi->base_pipeline) { + create_pipeline_layout (spi->base_pipeline, s); + } + create_pipeline_layout (&spi->pipelines[i], s); + } +} + +static void +create_renderpass_layouts (uint32_t index, const qfv_renderinfo_t *rinfo, + objstate_t *s) +{ + auto rpi = &rinfo->renderpasses[index]; + for (uint32_t i = 0; i < rpi->num_subpasses; i++) { + create_subpass_layouts (i, rpi->subpasses, s); + } +} + +static void +create_step_render_layouts (uint32_t index, const qfv_stepinfo_t *step, + objstate_t *s) +{ + __auto_type rinfo = step->render; + if (!rinfo) { + return; + } + for (uint32_t i = 0; i < rinfo->num_renderpasses; i++) { + create_renderpass_layouts (i, rinfo, s); + } +} + +static void +create_step_compute_layouts (uint32_t index, const qfv_stepinfo_t *step, + objstate_t *s) +{ + __auto_type cinfo = step->compute; + if (!cinfo) { + return; + } + + uint32_t base = s->inds.num_graph_pipelines; + for (uint32_t i = 0; i < cinfo->num_pipelines; i++) { + auto pli = &cinfo->pipelines[i]; + auto li = find_layout (&pli->layout, s); + s->ptr.plName[base + s->inds.num_comp_pipelines] = pli->name; + s->inds.num_ds_indices += li->num_sets; + } +} + +static void +create_layouts (vulkan_ctx_t *ctx, objstate_t *s) +{ + qfZoneScoped (true); + auto rctx = ctx->render_context; + auto jinfo = rctx->jobinfo; + + for (uint32_t i = 0; i < jinfo->num_steps; i++) { + create_step_render_layouts (i, &jinfo->steps[i], s); + } + for (uint32_t i = 0; i < jinfo->num_steps; i++) { + create_step_compute_layouts (i, &jinfo->steps[i], s); + } +} + static void create_objects (vulkan_ctx_t *ctx, objcount_t *counts) { @@ -1191,6 +1279,24 @@ create_objects (vulkan_ctx_t *ctx, objcount_t *counts) .jinfo = jinfo, .symtab = QFV_CreateSymtab (jinfo->plitem, "properties", 0, 0, &ectx), }; + + // Create pipeline layouts first so they and the descriptor set indices + // can be counted correctly. + create_layouts (ctx, &s); + counts->num_layouts = s.inds.num_layouts; + counts->num_ds_indices = s.inds.num_ds_indices; + + auto jp = create_job (ctx, counts, &s); + + auto job = rctx->job; + init_tasks (&job->newscene_task_count, &job->newscene_tasks, + jinfo->newscene_num_tasks, jinfo->newscene_tasks, + &jp, &s); + init_tasks (&job->init_task_count, &job->init_tasks, + jinfo->init_num_tasks, jinfo->init_tasks, + &jp, &s); + QFV_Render_Run_Init (ctx); + for (uint32_t i = 0; i < jinfo->num_steps; i++) { create_step_render_objects (i, &jinfo->steps[i], &s); } @@ -1208,7 +1314,8 @@ create_objects (vulkan_ctx_t *ctx, objcount_t *counts) || s.inds.num_colorblend != counts->num_colorblend || s.inds.num_preserve != counts->num_preserve || s.inds.num_graph_pipelines != counts->num_graph_pipelines - || s.inds.num_comp_pipelines != counts->num_comp_pipelines) { + || s.inds.num_comp_pipelines != counts->num_comp_pipelines + || s.inds.num_layouts > counts->num_layouts) { Sys_Error ("create_objects: something was missed"); } @@ -1243,7 +1350,13 @@ create_objects (vulkan_ctx_t *ctx, objcount_t *counts) } counts->num_ds_indices = s.inds.num_ds_indices; - init_job (ctx, counts, s); + + uint32_t num_layouts = s.inds.num_layouts; + uint32_t num_tasks = s.inds.num_tasks; + s.inds = (objcount_t) {}; + s.inds.num_layouts = num_layouts; + s.inds.num_tasks = num_tasks; + init_job (ctx, counts, jp, &s); } void @@ -1256,4 +1369,5 @@ QFV_BuildRender (vulkan_ctx_t *ctx) count_stuff (rctx->jobinfo, &counts); create_objects (ctx, &counts); + QFV_Render_Run_Startup (ctx); } diff --git a/libs/video/renderer/vulkan/rp_main_def.plist b/libs/video/renderer/vulkan/rp_main_def.plist index 6c332722c..2dda1e5cd 100644 --- a/libs/video/renderer/vulkan/rp_main_def.plist +++ b/libs/video/renderer/vulkan/rp_main_def.plist @@ -2682,3 +2682,20 @@ newscene_tasks = ( { func = bsp_build_display_lists; }, { func = lighting_load_lights; }, ); +init_tasks = ( + { func = texture_init; }, + { func = palette_init; }, + { func = alias_init; }, + { func = bsp_init; }, + { func = iqm_init; }, + { func = matrices_init; }, + { func = scene_init; }, + { func = sprite_init; }, + { func = output_init; }, + { func = compose_init; }, + { func = draw_init; }, + { func = particle_init; }, + { func = planes_init; }, + { func = translucent_init; }, + { func = lighting_init; }, +); diff --git a/libs/video/renderer/vulkan/rp_main_fwd.plist b/libs/video/renderer/vulkan/rp_main_fwd.plist index 6c6643a8f..e3b01d6a2 100644 --- a/libs/video/renderer/vulkan/rp_main_fwd.plist +++ b/libs/video/renderer/vulkan/rp_main_fwd.plist @@ -1592,3 +1592,19 @@ newscene_tasks = ( { func = bsp_build_lightmaps; }, { func = bsp_build_display_lists; }, ); +init_tasks = ( + { func = texture_init; }, + { func = palette_init; }, + { func = alias_init; }, + { func = bsp_init; }, + { func = iqm_init; }, + { func = matrices_init; }, + { func = scene_init; }, + { func = sprite_init; }, + { func = output_init; }, + { func = compose_init; }, + { func = draw_init; }, + { func = particle_init; }, + { func = planes_init; }, + { func = translucent_init; }, +); diff --git a/libs/video/renderer/vulkan/vkparse.plist b/libs/video/renderer/vulkan/vkparse.plist index 52225d695..e254befe1 100644 --- a/libs/video/renderer/vulkan/vkparse.plist +++ b/libs/video/renderer/vulkan/vkparse.plist @@ -626,6 +626,11 @@ parse = { size = newscene_num_tasks; values = newscene_tasks; }; + init_tasks = { + type = (array, qfv_taskinfo_t); + size = init_num_tasks; + values = init_tasks; + }; plitem = ignore; }; qfv_samplercreateinfo_s = { diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index 76a085386..fa70cde10 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -356,6 +356,46 @@ alias_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) } } +static void +alias_shutdown (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "alias shutdown"); + auto actx = ctx->alias_context; + + free (actx); + qfvPopDebug (ctx); +} + +static void +alias_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + auto actx = ctx->alias_context; + actx->sampler = QFV_Render_Sampler (ctx, "alias_sampler"); +} + +static void +alias_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "alias init"); + + QFV_Render_AddShutdown (ctx, alias_shutdown); + QFV_Render_AddStartup (ctx, alias_startup); + + aliasctx_t *actx = calloc (1, sizeof (aliasctx_t)); + ctx->alias_context = actx; + + qfvPopDebug (ctx); +} + static exprenum_t alias_stage_enum; static exprtype_t alias_stage_type = { .name = "alias_stage", @@ -383,8 +423,15 @@ static exprfunc_t alias_draw_func[] = { { .func = alias_draw, .num_params = 2, .param_types = alias_draw_params }, {} }; + +static exprfunc_t alias_init_func[] = { + { .func = alias_init }, + {} +}; + static exprsym_t alias_task_syms[] = { { "alias_draw", &cexpr_function, alias_draw_func }, + { "alias_init", &cexpr_function, alias_init_func }, {} }; @@ -395,27 +442,5 @@ Vulkan_Alias_Init (vulkan_ctx_t *ctx) qfvPushDebug (ctx, "alias init"); QFV_Render_AddTasks (ctx, alias_task_syms); - aliasctx_t *actx = calloc (1, sizeof (aliasctx_t)); - ctx->alias_context = actx; - qfvPopDebug (ctx); } - -void -Vulkan_Alias_Setup (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - auto actx = ctx->alias_context; - actx->sampler = QFV_Render_Sampler (ctx, "alias_sampler"); -} - -void -Vulkan_Alias_Shutdown (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - //qfv_device_t *device = ctx->device; - //qfv_devfuncs_t *dfunc = device->funcs; - aliasctx_t *actx = ctx->alias_context; - - free (actx); -} diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index 338a8ad03..3f4b8c0f8 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -1423,6 +1423,171 @@ bsp_register_textures (const exprval_t **params, exprval_t *result, Vulkan_RegisterTextures (scene->models, scene->num_models, ctx); } +static void +bsp_shutdown (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "bsp shutdown"); + + auto device = ctx->device; + auto dfunc = device->funcs; + auto bctx = ctx->bsp_context; + + bctx->main_pass.entqueue = 0; // owned by r_ent_queue + shutdown_pass_draw_queues (&bctx->main_pass); + shutdown_pass_draw_queues (&bctx->shadow_pass); + shutdown_pass_draw_queues (&bctx->debug_pass); + + clear_textures (ctx); + DARRAY_CLEAR (&bctx->registered_textures); + + free (bctx->faces); + free (bctx->poly_indices); + free (bctx->surfaces); + free (bctx->models); + + shutdown_pass_instances (&bctx->main_pass, bctx); + shutdown_pass_instances (&bctx->shadow_pass, bctx); + shutdown_pass_instances (&bctx->debug_pass, bctx); + + free (bctx->frames.a); + + QFV_DestroyStagingBuffer (bctx->light_stage); + QFV_DestroyScrap (bctx->light_scrap); + if (bctx->vertex_buffer) { + dfunc->vkDestroyBuffer (device->dev, bctx->vertex_buffer, 0); + dfunc->vkFreeMemory (device->dev, bctx->vertex_memory, 0); + } + if (bctx->index_buffer) { + dfunc->vkDestroyBuffer (device->dev, bctx->index_buffer, 0); + dfunc->vkFreeMemory (device->dev, bctx->index_memory, 0); + } + dfunc->vkDestroyBuffer (device->dev, bctx->entid_buffer, 0); + dfunc->vkFreeMemory (device->dev, bctx->entid_memory, 0); + + if (bctx->skybox_tex) { + Vulkan_UnloadTex (ctx, bctx->skybox_tex); + } + if (bctx->notexture.tex) { + Vulkan_UnloadTex (ctx, bctx->notexture.tex); + } + + dfunc->vkDestroyImageView (device->dev, bctx->default_skysheet->view, 0); + dfunc->vkDestroyImage (device->dev, bctx->default_skysheet->image, 0); + + dfunc->vkDestroyImageView (device->dev, bctx->default_skybox->view, 0); + dfunc->vkDestroyImage (device->dev, bctx->default_skybox->image, 0); + dfunc->vkFreeMemory (device->dev, bctx->default_skybox->memory, 0); + free (bctx->default_skybox); + free (bctx); + qfvPopDebug (ctx); +} + +static void +bsp_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "bsp startup"); + auto bctx = ctx->bsp_context; + + auto device = ctx->device; + auto dfunc = device->funcs; + + bctx->main_pass.bsp_context = bctx; + bctx->shadow_pass.bsp_context = bctx; + bctx->shadow_pass.entqueue = EntQueue_New (mod_num_types); + bctx->debug_pass.bsp_context = bctx; + bctx->debug_pass.entqueue = EntQueue_New (mod_num_types); + + bctx->sampler = QFV_Render_Sampler (ctx, "quakebsp_sampler"); + + bctx->light_scrap = QFV_CreateScrap (device, "lightmap_atlas", 2048, + tex_frgba, ctx->staging); + size_t size = QFV_ScrapSize (bctx->light_scrap); + bctx->light_stage = QFV_CreateStagingBuffer (device, "lightmap", size, + ctx->cmdpool); + + create_default_skys (ctx); + create_notexture (ctx); + + DARRAY_INIT (&bctx->registered_textures, 64); + + setup_pass_draw_queues (&bctx->main_pass); + setup_pass_draw_queues (&bctx->shadow_pass); + setup_pass_draw_queues (&bctx->debug_pass); + + auto rctx = ctx->render_context; + size_t frames = rctx->frames.size; + DARRAY_INIT (&bctx->frames, frames); + DARRAY_RESIZE (&bctx->frames, frames); + bctx->frames.grow = 0; + + size_t entid_count = Vulkan_Scene_MaxEntities (ctx); + size_t entid_size = entid_count * sizeof (uint32_t); + size_t atom = device->physDev->p.properties.limits.nonCoherentAtomSize; + size_t atom_mask = atom - 1; + entid_size = (entid_size + atom_mask) & ~atom_mask; + bctx->entid_buffer + = QFV_CreateBuffer (device, frames * entid_size, + VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + QFV_duSetObjectName (device, VK_OBJECT_TYPE_BUFFER, bctx->entid_buffer, + "buffer:bsp:entid"); + bctx->entid_memory + = QFV_AllocBufferMemory (device, bctx->entid_buffer, + VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + frames * entid_size, 0); + QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY, + bctx->entid_memory, "memory:bsp:entid"); + QFV_BindBufferMemory (device, + bctx->entid_buffer, bctx->entid_memory, 0); + uint32_t *entid_data; + dfunc->vkMapMemory (device->dev, bctx->entid_memory, 0, + frames * entid_size, 0, (void **) &entid_data); + + for (size_t i = 0; i < frames; i++) { + auto bframe = &bctx->frames.a[i]; + + + bframe->entid_data = entid_data + i * entid_count; + bframe->entid_offset = i * entid_size; + } + + bctx->lightmap_descriptor + = Vulkan_CreateCombinedImageSampler (ctx, + Vulkan_LightmapImageView (ctx), + bctx->sampler); + bctx->skybox_descriptor + = Vulkan_CreateTextureDescriptor (ctx, bctx->default_skybox, + bctx->sampler); + bctx->notexture.descriptor + = Vulkan_CreateTextureDescriptor (ctx, bctx->notexture.tex, + bctx->sampler); + + r_notexture_mip->render = &bctx->notexture; + + qfvPopDebug (ctx); +} + +static void +bsp_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + + QFV_Render_AddShutdown (ctx, bsp_shutdown); + QFV_Render_AddStartup (ctx, bsp_startup); + + bspctx_t *bctx = calloc (1, sizeof (bspctx_t)); + ctx->bsp_context = bctx; + bctx->vulkan_ctx = ctx; +} + static exprenum_t bsp_pass_enum; static exprtype_t bsp_pass_type = { .name = "bsp_pass", @@ -1510,6 +1675,12 @@ static exprfunc_t bsp_register_textures_func[] = { { .func = bsp_register_textures }, {} }; + +static exprfunc_t bsp_init_func[] = { + { .func = bsp_init }, + {} +}; + static exprsym_t bsp_task_syms[] = { { "bsp_reset_queues", &cexpr_function, bsp_reset_queues_func }, { "bsp_visit_world", &cexpr_function, bsp_visit_world_func }, @@ -1519,6 +1690,7 @@ static exprsym_t bsp_task_syms[] = { { "bsp_build_display_lists", &cexpr_function, bsp_build_display_lists_func }, { "bsp_register_textures", &cexpr_function, bsp_register_textures_func }, + { "bsp_init", &cexpr_function, bsp_init_func }, {} }; @@ -1527,154 +1699,6 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx) { qfZoneScoped (true); QFV_Render_AddTasks (ctx, bsp_task_syms); - - bspctx_t *bctx = calloc (1, sizeof (bspctx_t)); - ctx->bsp_context = bctx; - bctx->vulkan_ctx = ctx; - - bctx->main_pass.bsp_context = bctx; - bctx->shadow_pass.bsp_context = bctx; - bctx->shadow_pass.entqueue = EntQueue_New (mod_num_types); - bctx->debug_pass.bsp_context = bctx; - bctx->debug_pass.entqueue = EntQueue_New (mod_num_types); -} - -void -Vulkan_Bsp_Setup (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - qfvPushDebug (ctx, "bsp init"); - - auto device = ctx->device; - auto dfunc = device->funcs; - - auto bctx = ctx->bsp_context; - - bctx->sampler = QFV_Render_Sampler (ctx, "quakebsp_sampler"); - - bctx->light_scrap = QFV_CreateScrap (device, "lightmap_atlas", 2048, - tex_frgba, ctx->staging); - size_t size = QFV_ScrapSize (bctx->light_scrap); - bctx->light_stage = QFV_CreateStagingBuffer (device, "lightmap", size, - ctx->cmdpool); - - create_default_skys (ctx); - create_notexture (ctx); - - DARRAY_INIT (&bctx->registered_textures, 64); - - setup_pass_draw_queues (&bctx->main_pass); - setup_pass_draw_queues (&bctx->shadow_pass); - setup_pass_draw_queues (&bctx->debug_pass); - - auto rctx = ctx->render_context; - size_t frames = rctx->frames.size; - DARRAY_INIT (&bctx->frames, frames); - DARRAY_RESIZE (&bctx->frames, frames); - bctx->frames.grow = 0; - - size_t entid_count = Vulkan_Scene_MaxEntities (ctx); - size_t entid_size = entid_count * sizeof (uint32_t); - size_t atom = device->physDev->p.properties.limits.nonCoherentAtomSize; - size_t atom_mask = atom - 1; - entid_size = (entid_size + atom_mask) & ~atom_mask; - bctx->entid_buffer - = QFV_CreateBuffer (device, frames * entid_size, - VK_BUFFER_USAGE_TRANSFER_DST_BIT - | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); - QFV_duSetObjectName (device, VK_OBJECT_TYPE_BUFFER, bctx->entid_buffer, - "buffer:bsp:entid"); - bctx->entid_memory - = QFV_AllocBufferMemory (device, bctx->entid_buffer, - VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - frames * entid_size, 0); - QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY, - bctx->entid_memory, "memory:bsp:entid"); - QFV_BindBufferMemory (device, - bctx->entid_buffer, bctx->entid_memory, 0); - uint32_t *entid_data; - dfunc->vkMapMemory (device->dev, bctx->entid_memory, 0, - frames * entid_size, 0, (void **) &entid_data); - - for (size_t i = 0; i < frames; i++) { - auto bframe = &bctx->frames.a[i]; - - - bframe->entid_data = entid_data + i * entid_count; - bframe->entid_offset = i * entid_size; - } - - bctx->lightmap_descriptor - = Vulkan_CreateCombinedImageSampler (ctx, - Vulkan_LightmapImageView (ctx), - bctx->sampler); - bctx->skybox_descriptor - = Vulkan_CreateTextureDescriptor (ctx, bctx->default_skybox, - bctx->sampler); - bctx->notexture.descriptor - = Vulkan_CreateTextureDescriptor (ctx, bctx->notexture.tex, - bctx->sampler); - - r_notexture_mip->render = &bctx->notexture; - - qfvPopDebug (ctx); -} - -void -Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx) -{ - qfZoneScoped (true); - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; - bspctx_t *bctx = ctx->bsp_context; - - bctx->main_pass.entqueue = 0; // owned by r_ent_queue - shutdown_pass_draw_queues (&bctx->main_pass); - shutdown_pass_draw_queues (&bctx->shadow_pass); - shutdown_pass_draw_queues (&bctx->debug_pass); - - clear_textures (ctx); - DARRAY_CLEAR (&bctx->registered_textures); - - free (bctx->faces); - free (bctx->poly_indices); - free (bctx->surfaces); - free (bctx->models); - - shutdown_pass_instances (&bctx->main_pass, bctx); - shutdown_pass_instances (&bctx->shadow_pass, bctx); - shutdown_pass_instances (&bctx->debug_pass, bctx); - - free (bctx->frames.a); - - QFV_DestroyStagingBuffer (bctx->light_stage); - QFV_DestroyScrap (bctx->light_scrap); - if (bctx->vertex_buffer) { - dfunc->vkDestroyBuffer (device->dev, bctx->vertex_buffer, 0); - dfunc->vkFreeMemory (device->dev, bctx->vertex_memory, 0); - } - if (bctx->index_buffer) { - dfunc->vkDestroyBuffer (device->dev, bctx->index_buffer, 0); - dfunc->vkFreeMemory (device->dev, bctx->index_memory, 0); - } - dfunc->vkDestroyBuffer (device->dev, bctx->entid_buffer, 0); - dfunc->vkFreeMemory (device->dev, bctx->entid_memory, 0); - - if (bctx->skybox_tex) { - Vulkan_UnloadTex (ctx, bctx->skybox_tex); - } - if (bctx->notexture.tex) { - Vulkan_UnloadTex (ctx, bctx->notexture.tex); - } - - dfunc->vkDestroyImageView (device->dev, bctx->default_skysheet->view, 0); - dfunc->vkDestroyImage (device->dev, bctx->default_skysheet->image, 0); - - dfunc->vkDestroyImageView (device->dev, bctx->default_skybox->view, 0); - dfunc->vkDestroyImage (device->dev, bctx->default_skybox->image, 0); - dfunc->vkFreeMemory (device->dev, bctx->default_skybox->memory, 0); - free (bctx->default_skybox); - free (bctx); } void diff --git a/libs/video/renderer/vulkan/vulkan_compose.c b/libs/video/renderer/vulkan/vulkan_compose.c index 2b13e1eda..b4f9f2977 100644 --- a/libs/video/renderer/vulkan/vulkan_compose.c +++ b/libs/video/renderer/vulkan/vulkan_compose.c @@ -114,36 +114,27 @@ compose_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) dfunc->vkCmdDraw (cmd, 3, 1, 0, 0); } -static exprtype_t *compose_draw_params[] = { - &cexpr_int, -}; -static exprfunc_t compose_draw_func[] = { - { .func = compose_draw, .num_params = 1, - .param_types = compose_draw_params }, - {} -}; -static exprsym_t compose_task_syms[] = { - { "compose_draw", &cexpr_function, compose_draw_func }, - {} -}; - -void -Vulkan_Compose_Init (vulkan_ctx_t *ctx) +static void +compose_shutdown (exprctx_t *ectx) { qfZoneScoped (true); - QFV_Render_AddTasks (ctx, compose_task_syms); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + composectx_t *cctx = ctx->compose_context; - composectx_t *cctx = calloc (1, sizeof (composectx_t)); - ctx->compose_context = cctx; + free (cctx->frames.a); + free (cctx); } -void -Vulkan_Compose_Setup (vulkan_ctx_t *ctx) +static void +compose_startup (exprctx_t *ectx) { qfZoneScoped (true); - qfvPushDebug (ctx, "compose init"); - + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; auto device = ctx->device; + qfvPushDebug (ctx, "compose startup"); + auto cctx = ctx->compose_context; auto rctx = ctx->render_context; @@ -171,12 +162,43 @@ Vulkan_Compose_Setup (vulkan_ctx_t *ctx) qfvPopDebug (ctx); } -void -Vulkan_Compose_Shutdown (vulkan_ctx_t *ctx) +static void +compose_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) { qfZoneScoped (true); - composectx_t *cctx = ctx->compose_context; + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; - free (cctx->frames.a); - free (cctx); + QFV_Render_AddShutdown (ctx, compose_shutdown); + QFV_Render_AddStartup (ctx, compose_startup); + + composectx_t *cctx = calloc (1, sizeof (composectx_t)); + ctx->compose_context = cctx; +} + +static exprtype_t *compose_draw_params[] = { + &cexpr_int, +}; +static exprfunc_t compose_draw_func[] = { + { .func = compose_draw, .num_params = 1, + .param_types = compose_draw_params }, + {} +}; + +static exprfunc_t compose_init_func[] = { + { .func = compose_init }, + {} +}; + +static exprsym_t compose_task_syms[] = { + { "compose_draw", &cexpr_function, compose_draw_func }, + { "compose_init", &cexpr_function, compose_init_func }, + {} +}; + +void +Vulkan_Compose_Init (vulkan_ctx_t *ctx) +{ + qfZoneScoped (true); + QFV_Render_AddTasks (ctx, compose_task_syms); } diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index 2b6fd50de..d34653dcf 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -819,9 +819,11 @@ Vulkan_Draw_UncachePic (const char *path, vulkan_ctx_t *ctx) Hash_Free (dctx->pic_cache, Hash_Del (dctx->pic_cache, path)); } -void -Vulkan_Draw_Shutdown (vulkan_ctx_t *ctx) +static void +draw_shutdown (exprctx_t *ectx) { + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; qfZoneScoped (true); auto device = ctx->device; auto dctx = ctx->draw_context; @@ -919,6 +921,101 @@ load_white_pic (vulkan_ctx_t *ctx) dctx->white_pic, ctx); } +static void +draw_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + auto dctx = ctx->draw_context; + qfvPushDebug (ctx, "draw startup"); + + auto device = ctx->device; + auto dfunc = device->funcs; + + dctx->pic_sampler = QFV_Render_Sampler (ctx, "quakepic"); + dctx->glyph_sampler = QFV_Render_Sampler (ctx, "glyph"); + + dctx->dsmanager = QFV_Render_DSManager (ctx, "quad_data_set"); + + auto rctx = ctx->render_context; + size_t frames = rctx->frames.size; + DARRAY_INIT (&dctx->frames, frames); + DARRAY_RESIZE (&dctx->frames, frames); + dctx->frames.grow = 0; + memset (dctx->frames.a, 0, dctx->frames.size * sizeof (drawframe_t)); + + DARRAY_INIT (&dctx->fonts, 16); + DARRAY_RESIZE (&dctx->fonts, 16); + dctx->fonts.size = 0; + + dctx->pic_memsuper = new_memsuper (); + dctx->string_memsuper = new_memsuper (); + dctx->pic_cache = Hash_NewTable (127, cachepic_getkey, cachepic_free, + dctx, 0); + + create_buffers (ctx); + dctx->stage = QFV_CreateStagingBuffer (device, "draw", 4 * 1024 * 1024, + ctx->cmdpool); + dctx->scrap = QFV_CreateScrap (device, "draw_atlas", 2048, tex_rgba, + dctx->stage); + + load_conchars (ctx); + load_crosshairs (ctx); + load_white_pic (ctx); + + dctx->backtile_pic = Vulkan_Draw_PicFromWad ("backtile", ctx); + if (!dctx->backtile_pic) { + dctx->backtile_pic = dctx->white_pic; + } + + flush_draw_scrap (ctx); + + // core set + dynamic sets + + VkDescriptorImageInfo imageInfo = { + dctx->pic_sampler, + QFV_ScrapImageView (dctx->scrap), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + + for (size_t i = 0; i < frames; i++) { + __auto_type frame = &dctx->frames.a[i]; + frame->dyn_descs = (descpool_t) { .dctx = dctx }; + } + dctx->core_quad_set = QFV_DSManager_AllocSet (dctx->dsmanager); + + VkWriteDescriptorSet write[] = { + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + dctx->core_quad_set, 0, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + &imageInfo, 0, 0 }, + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, + dctx->core_quad_set, 1, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + 0, 0, &dctx->svertex_objects[1].buffer_view.view }, + }; + dfunc->vkUpdateDescriptorSets (device->dev, 2, write, 0, 0); + + DARRAY_APPEND (&dctx->fonts, (drawfont_t) { .set = dctx->core_quad_set }); + + qfvPopDebug (ctx); +} + +static void +draw_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + + QFV_Render_AddShutdown (ctx, draw_shutdown); + QFV_Render_AddStartup (ctx, draw_startup); + + drawctx_t *dctx = calloc (1, sizeof (drawctx_t)); + ctx->draw_context = dctx; +} + static void draw_quads (qfv_taskctx_t *taskctx) { @@ -1117,11 +1214,18 @@ static exprfunc_t draw_scr_funcs_func[] = { { .func = draw_scr_funcs }, {} }; + +static exprfunc_t draw_init_func[] = { + { .func = draw_init }, + {} +}; + static exprsym_t draw_task_syms[] = { { "flush_draw", &cexpr_function, flush_draw_func }, { "slice_draw", &cexpr_function, slice_draw_func }, { "line_draw", &cexpr_function, line_draw_func }, { "draw_scr_funcs", &cexpr_function, draw_scr_funcs_func }, + { "draw_init", &cexpr_function, draw_init_func }, {} }; @@ -1130,88 +1234,6 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx) { qfZoneScoped (true); QFV_Render_AddTasks (ctx, draw_task_syms); - - drawctx_t *dctx = calloc (1, sizeof (drawctx_t)); - ctx->draw_context = dctx; -} - -void -Vulkan_Draw_Setup (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - qfvPushDebug (ctx, "draw init"); - - auto device = ctx->device; - auto dfunc = device->funcs; - auto dctx = ctx->draw_context; - - dctx->pic_sampler = QFV_Render_Sampler (ctx, "quakepic"); - dctx->glyph_sampler = QFV_Render_Sampler (ctx, "glyph"); - - dctx->dsmanager = QFV_Render_DSManager (ctx, "quad_data_set"); - - auto rctx = ctx->render_context; - size_t frames = rctx->frames.size; - DARRAY_INIT (&dctx->frames, frames); - DARRAY_RESIZE (&dctx->frames, frames); - dctx->frames.grow = 0; - memset (dctx->frames.a, 0, dctx->frames.size * sizeof (drawframe_t)); - - DARRAY_INIT (&dctx->fonts, 16); - DARRAY_RESIZE (&dctx->fonts, 16); - dctx->fonts.size = 0; - - dctx->pic_memsuper = new_memsuper (); - dctx->string_memsuper = new_memsuper (); - dctx->pic_cache = Hash_NewTable (127, cachepic_getkey, cachepic_free, - dctx, 0); - - create_buffers (ctx); - dctx->stage = QFV_CreateStagingBuffer (device, "draw", 4 * 1024 * 1024, - ctx->cmdpool); - dctx->scrap = QFV_CreateScrap (device, "draw_atlas", 2048, tex_rgba, - dctx->stage); - - load_conchars (ctx); - load_crosshairs (ctx); - load_white_pic (ctx); - - dctx->backtile_pic = Vulkan_Draw_PicFromWad ("backtile", ctx); - if (!dctx->backtile_pic) { - dctx->backtile_pic = dctx->white_pic; - } - - flush_draw_scrap (ctx); - - // core set + dynamic sets - - VkDescriptorImageInfo imageInfo = { - dctx->pic_sampler, - QFV_ScrapImageView (dctx->scrap), - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }; - - for (size_t i = 0; i < frames; i++) { - __auto_type frame = &dctx->frames.a[i]; - frame->dyn_descs = (descpool_t) { .dctx = dctx }; - } - dctx->core_quad_set = QFV_DSManager_AllocSet (dctx->dsmanager); - - VkWriteDescriptorSet write[] = { - { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, - dctx->core_quad_set, 0, 0, 1, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - &imageInfo, 0, 0 }, - { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, - dctx->core_quad_set, 1, 0, 1, - VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, - 0, 0, &dctx->svertex_objects[1].buffer_view.view }, - }; - dfunc->vkUpdateDescriptorSets (device->dev, 2, write, 0, 0); - - DARRAY_APPEND (&dctx->fonts, (drawfont_t) { .set = dctx->core_quad_set }); - - qfvPopDebug (ctx); } static inline descbatch_t * diff --git a/libs/video/renderer/vulkan/vulkan_iqm.c b/libs/video/renderer/vulkan/vulkan_iqm.c index 3a82576f9..e7a4e9b46 100644 --- a/libs/video/renderer/vulkan/vulkan_iqm.c +++ b/libs/video/renderer/vulkan/vulkan_iqm.c @@ -416,6 +416,48 @@ iqm_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) } } +static void +iqm_shutdown (exprctx_t *ectx) +{ + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfZoneScoped (true); + iqmctx_t *ictx = ctx->iqm_context; + + free (ictx->frames.a); + free (ictx); +} + +static void +iqm_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + auto ictx = ctx->iqm_context; + + auto rctx = ctx->render_context; + size_t frames = rctx->frames.size; + DARRAY_INIT (&ictx->frames, frames); + DARRAY_RESIZE (&ictx->frames, frames); + ictx->frames.grow = 0; + ictx->sampler = QFV_Render_Sampler (ctx, "alias_sampler"); +} + +static void +iqm_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) +{ + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfZoneScoped (true); + + QFV_Render_AddShutdown (ctx, iqm_shutdown); + QFV_Render_AddStartup (ctx, iqm_startup); + + iqmctx_t *ictx = calloc (1, sizeof (iqmctx_t)); + ctx->iqm_context = ictx; +} + static exprtype_t *iqm_draw_params[] = { &cexpr_int, }; @@ -423,8 +465,15 @@ static exprfunc_t iqm_draw_func[] = { { .func = iqm_draw, .num_params = 1, .param_types = iqm_draw_params }, {} }; + +static exprfunc_t iqm_init_func[] = { + { .func = iqm_init }, + {} +}; + static exprsym_t iqm_task_syms[] = { { "iqm_draw", &cexpr_function, iqm_draw_func }, + { "iqm_init", &cexpr_function, iqm_init_func }, {} }; @@ -435,32 +484,5 @@ Vulkan_IQM_Init (vulkan_ctx_t *ctx) qfvPushDebug (ctx, "iqm init"); QFV_Render_AddTasks (ctx, iqm_task_syms); - iqmctx_t *ictx = calloc (1, sizeof (iqmctx_t)); - ctx->iqm_context = ictx; - - auto rctx = ctx->render_context; - size_t frames = rctx->frames.size; - DARRAY_INIT (&ictx->frames, frames); - DARRAY_RESIZE (&ictx->frames, frames); - ictx->frames.grow = 0; - qfvPopDebug (ctx); } - -void -Vulkan_IQM_Setup (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - auto ictx = ctx->iqm_context; - ictx->sampler = QFV_Render_Sampler (ctx, "alias_sampler"); -} - -void -Vulkan_IQM_Shutdown (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - iqmctx_t *ictx = ctx->iqm_context; - - free (ictx->frames.a); - free (ictx); -} diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index 8419d8194..99dc941c1 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -1360,172 +1360,6 @@ lighting_load_lights (const exprval_t **params, exprval_t *result, Vulkan_LoadLights (scene, ctx); } -static exprenum_t lighting_stage_enum; -static exprtype_t lighting_stage_type = { - .name = "lighting_stage", - .size = sizeof (int), - .get_string = cexpr_enum_get_string, - .data = &lighting_stage_enum, -}; -static int lighting_stage_values[] = { - lighting_main, - lighting_shadow, - lighting_hull, -}; -static exprsym_t lighting_stage_symbols[] = { - {"main", &lighting_stage_type, lighting_stage_values + 0}, - {"shadow", &lighting_stage_type, lighting_stage_values + 1}, - {"hull", &lighting_stage_type, lighting_stage_values + 2}, - {} -}; -static exprtab_t lighting_stage_symtab = { .symbols = lighting_stage_symbols }; -static exprenum_t lighting_stage_enum = { - &lighting_stage_type, - &lighting_stage_symtab, -}; - -static exprenum_t shadow_type_enum; -static exprtype_t shadow_type_type = { - .name = "shadow_type", - .size = sizeof (int), - .get_string = cexpr_enum_get_string, - .data = &shadow_type_enum, -}; -static int shadow_type_values[] = { ST_NONE, ST_PLANE, ST_CASCADE, ST_CUBE }; -static exprsym_t shadow_type_symbols[] = { - {"none", &shadow_type_type, shadow_type_values + 0}, - {"plane", &shadow_type_type, shadow_type_values + 1}, - {"cascade", &shadow_type_type, shadow_type_values + 2}, - {"cube", &shadow_type_type, shadow_type_values + 3}, - {} -}; -static exprtab_t shadow_type_symtab = { .symbols = shadow_type_symbols }; -static exprenum_t shadow_type_enum = { - &shadow_type_type, - &shadow_type_symtab, -}; - -static exprtype_t *shadow_type_param[] = { - &shadow_type_type, - &lighting_stage_type, -}; - -static exprtype_t *stepref_param[] = { - &cexpr_string, -}; - -static exprfunc_t lighting_update_lights_func[] = { - { .func = lighting_update_lights }, - {} -}; -static exprfunc_t lighting_update_descriptors_func[] = { - { .func = lighting_update_descriptors, .num_params = 1, - .param_types = stepref_param }, - {} -}; -static exprfunc_t lighting_bind_descriptors_func[] = { - { .func = lighting_bind_descriptors, .num_params = 2, - .param_types = shadow_type_param }, - {} -}; -static exprfunc_t lighting_draw_splats_func[] = { - { .func = lighting_draw_splats }, - {} -}; -static exprfunc_t lighting_cull_select_renderpass_func[] = { - { .func = lighting_cull_select_renderpass, .num_params = 1, - .param_types = stepref_param }, - {} -}; -static exprfunc_t lighting_cull_lights_func[] = { - { .func = lighting_cull_lights, .num_params = 1, - .param_types = stepref_param }, - {} -}; -static exprfunc_t lighting_draw_hulls_func[] = { - { .func = lighting_draw_hulls }, - {} -}; -static exprfunc_t lighting_draw_lights_func[] = { - { .func = lighting_draw_lights, .num_params = 2, - .param_types = shadow_type_param }, - {} -}; -static exprfunc_t lighting_setup_shadow_func[] = { - { .func = lighting_setup_shadow }, - {} -}; -static exprfunc_t lighting_draw_shadow_maps_func[] = { - { .func = lighting_draw_shadow_maps, .num_params = 1, - .param_types = stepref_param }, - {} -}; - -static exprfunc_t lighting_load_lights_func[] = { - { .func = lighting_load_lights }, - {} -}; -static exprsym_t lighting_task_syms[] = { - { "lighting_update_lights", &cexpr_function, lighting_update_lights_func }, - { "lighting_update_descriptors", &cexpr_function, - lighting_update_descriptors_func }, - { "lighting_bind_descriptors", &cexpr_function, - lighting_bind_descriptors_func }, - { "lighting_draw_splats", &cexpr_function, lighting_draw_splats_func }, - { "lighting_cull_select_renderpass", &cexpr_function, - lighting_cull_select_renderpass_func }, - { "lighting_cull_lights", &cexpr_function, lighting_cull_lights_func }, - { "lighting_draw_hulls", &cexpr_function, lighting_draw_hulls_func }, - { "lighting_draw_lights", &cexpr_function, lighting_draw_lights_func }, - { "lighting_setup_shadow", &cexpr_function, lighting_setup_shadow_func }, - { "lighting_draw_shadow_maps", &cexpr_function, - lighting_draw_shadow_maps_func }, - - { "lighting_load_lights", &cexpr_function, lighting_load_lights_func }, - {} -}; - -static int -round_light_size (int size) -{ - size = ((size + shadow_quanta - 1) / shadow_quanta) * shadow_quanta; - return min (size, 1024); -} - -static void -dynlight_size_listener (void *data, const cvar_t *cvar) -{ - dynlight_size = round_light_size (dynlight_size); -} - -void -Vulkan_Lighting_Init (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - lightingctx_t *lctx = calloc (1, sizeof (lightingctx_t)); - ctx->lighting_context = lctx; - - Cvar_Register (&dynlight_size_cvar, dynlight_size_listener, 0); - - QFV_Render_AddTasks (ctx, lighting_task_syms); - - lctx->shadow_info = (qfv_attachmentinfo_t) { - .name = "$shadow", - .format = VK_FORMAT_D32_SFLOAT, - .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_TRANSFER_SRC_OPTIMAL,//FIXME plist - }; - qfv_attachmentinfo_t *attachments[] = { - &lctx->shadow_info, - }; - QFV_Render_AddAttachments (ctx, 1, attachments); -} - static void make_default_map (int size, VkImage default_map, vulkan_ctx_t *ctx) { @@ -1622,16 +1456,85 @@ write_inds (qfv_packet_t *packet) memcpy (inds, cone_inds, sizeof (cone_inds)); } -void -Vulkan_Lighting_Setup (vulkan_ctx_t *ctx) +static void +clear_shadows (vulkan_ctx_t *ctx) { qfZoneScoped (true); - qfvPushDebug (ctx, "lighting init"); + qfv_device_t *device = ctx->device; + auto dfunc = device->funcs; + lightingctx_t *lctx = ctx->lighting_context; + if (lctx->shadow_resources) { + QFV_DestroyResource (device, lctx->shadow_resources); + free (lctx->shadow_resources); + lctx->shadow_resources = 0; + } + for (int i = 0; i < LIGHTING_STAGES; i++) { + for (int j = 0; j < 32; j++) { + auto framebuffer = lctx->stage_framebuffers[j][i]; + if (framebuffer) { + dfunc->vkDestroyFramebuffer (device->dev, framebuffer, 0); + } + lctx->stage_framebuffers[j][i] = 0; + } + // images and views freed via shadow_resources + lctx->stage_images[i] = 0; + lctx->stage_views[i] = 0; + } + free (lctx->map_images); + free (lctx->map_views); + free (lctx->map_cube); + lctx->map_images = 0; + lctx->map_views = 0; + lctx->map_cube = 0; + lctx->num_maps = 0; + lctx->light_control.size = 0; +} + +static void +lighting_shutdown (exprctx_t *ectx) +{ + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfZoneScoped (true); auto device = ctx->device; auto dfunc = device->funcs; auto lctx = ctx->lighting_context; + clear_shadows (ctx); + + QFV_DestroyResource (device, lctx->light_resources); + free (lctx->light_resources); + + for (size_t i = 0; i < lctx->frames.size; i++) { + auto lframe = &lctx->frames.a[i]; + dfunc->vkDestroyQueryPool (device->dev, lframe->query, 0); + dfunc->vkDestroyFence (device->dev, lframe->fence, 0); + qftCVkContextDestroy (lframe->qftVkCtx); + } + free (lctx->frames.a[0].stage_targets); + free (lctx->frames.a[0].id_radius); + free (lctx->frames.a[0].positions); + DARRAY_CLEAR (&lctx->light_mats); + DARRAY_CLEAR (&lctx->light_control); + free (lctx->map_images); + free (lctx->map_views); + free (lctx->map_cube); + free (lctx->frames.a); + free (lctx); +} + +static void +lighting_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + auto device = ctx->device; + auto dfunc = device->funcs; + auto lctx = ctx->lighting_context; + qfvPushDebug (ctx, "lighting init"); + lctx->sampler = QFV_Render_Sampler (ctx, "shadow_sampler"); Vulkan_Script_SetOutput (ctx, @@ -1988,69 +1891,198 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx) } static void -clear_shadows (vulkan_ctx_t *ctx) +lighting_clearstate (exprctx_t *ectx) { qfZoneScoped (true); - qfv_device_t *device = ctx->device; - auto dfunc = device->funcs; - lightingctx_t *lctx = ctx->lighting_context; + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + Vulkan_LoadLights (0, ctx); +} - if (lctx->shadow_resources) { - QFV_DestroyResource (device, lctx->shadow_resources); - free (lctx->shadow_resources); - lctx->shadow_resources = 0; - } - for (int i = 0; i < LIGHTING_STAGES; i++) { - for (int j = 0; j < 32; j++) { - auto framebuffer = lctx->stage_framebuffers[j][i]; - if (framebuffer) { - dfunc->vkDestroyFramebuffer (device->dev, framebuffer, 0); - } - lctx->stage_framebuffers[j][i] = 0; - } - // images and views freed via shadow_resources - lctx->stage_images[i] = 0; - lctx->stage_views[i] = 0; - } - free (lctx->map_images); - free (lctx->map_views); - free (lctx->map_cube); - lctx->map_images = 0; - lctx->map_views = 0; - lctx->map_cube = 0; - lctx->num_maps = 0; - lctx->light_control.size = 0; +static void +lighting_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + + QFV_Render_AddShutdown (ctx, lighting_shutdown); + QFV_Render_AddStartup (ctx, lighting_startup); + QFV_Render_AddClearState (ctx, lighting_clearstate); + + lightingctx_t *lctx = calloc (1, sizeof (lightingctx_t)); + ctx->lighting_context = lctx; + + lctx->shadow_info = (qfv_attachmentinfo_t) { + .name = "$shadow", + .format = VK_FORMAT_D32_SFLOAT, + .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_TRANSFER_SRC_OPTIMAL,//FIXME plist + }; + qfv_attachmentinfo_t *attachments[] = { + &lctx->shadow_info, + }; + QFV_Render_AddAttachments (ctx, 1, attachments); +} + +static exprenum_t lighting_stage_enum; +static exprtype_t lighting_stage_type = { + .name = "lighting_stage", + .size = sizeof (int), + .get_string = cexpr_enum_get_string, + .data = &lighting_stage_enum, +}; +static int lighting_stage_values[] = { + lighting_main, + lighting_shadow, + lighting_hull, +}; +static exprsym_t lighting_stage_symbols[] = { + {"main", &lighting_stage_type, lighting_stage_values + 0}, + {"shadow", &lighting_stage_type, lighting_stage_values + 1}, + {"hull", &lighting_stage_type, lighting_stage_values + 2}, + {} +}; +static exprtab_t lighting_stage_symtab = { .symbols = lighting_stage_symbols }; +static exprenum_t lighting_stage_enum = { + &lighting_stage_type, + &lighting_stage_symtab, +}; + +static exprenum_t shadow_type_enum; +static exprtype_t shadow_type_type = { + .name = "shadow_type", + .size = sizeof (int), + .get_string = cexpr_enum_get_string, + .data = &shadow_type_enum, +}; +static int shadow_type_values[] = { ST_NONE, ST_PLANE, ST_CASCADE, ST_CUBE }; +static exprsym_t shadow_type_symbols[] = { + {"none", &shadow_type_type, shadow_type_values + 0}, + {"plane", &shadow_type_type, shadow_type_values + 1}, + {"cascade", &shadow_type_type, shadow_type_values + 2}, + {"cube", &shadow_type_type, shadow_type_values + 3}, + {} +}; +static exprtab_t shadow_type_symtab = { .symbols = shadow_type_symbols }; +static exprenum_t shadow_type_enum = { + &shadow_type_type, + &shadow_type_symtab, +}; + +static exprtype_t *shadow_type_param[] = { + &shadow_type_type, + &lighting_stage_type, +}; + +static exprtype_t *stepref_param[] = { + &cexpr_string, +}; + +static exprfunc_t lighting_update_lights_func[] = { + { .func = lighting_update_lights }, + {} +}; +static exprfunc_t lighting_update_descriptors_func[] = { + { .func = lighting_update_descriptors, .num_params = 1, + .param_types = stepref_param }, + {} +}; +static exprfunc_t lighting_bind_descriptors_func[] = { + { .func = lighting_bind_descriptors, .num_params = 2, + .param_types = shadow_type_param }, + {} +}; +static exprfunc_t lighting_draw_splats_func[] = { + { .func = lighting_draw_splats }, + {} +}; +static exprfunc_t lighting_cull_select_renderpass_func[] = { + { .func = lighting_cull_select_renderpass, .num_params = 1, + .param_types = stepref_param }, + {} +}; +static exprfunc_t lighting_cull_lights_func[] = { + { .func = lighting_cull_lights, .num_params = 1, + .param_types = stepref_param }, + {} +}; +static exprfunc_t lighting_draw_hulls_func[] = { + { .func = lighting_draw_hulls }, + {} +}; +static exprfunc_t lighting_draw_lights_func[] = { + { .func = lighting_draw_lights, .num_params = 2, + .param_types = shadow_type_param }, + {} +}; +static exprfunc_t lighting_setup_shadow_func[] = { + { .func = lighting_setup_shadow }, + {} +}; +static exprfunc_t lighting_draw_shadow_maps_func[] = { + { .func = lighting_draw_shadow_maps, .num_params = 1, + .param_types = stepref_param }, + {} +}; + +static exprfunc_t lighting_load_lights_func[] = { + { .func = lighting_load_lights }, + {} +}; + +static exprfunc_t lighting_init_func[] = { + { .func = lighting_init }, + {} +}; + +static exprsym_t lighting_task_syms[] = { + { "lighting_update_lights", &cexpr_function, lighting_update_lights_func }, + { "lighting_update_descriptors", &cexpr_function, + lighting_update_descriptors_func }, + { "lighting_bind_descriptors", &cexpr_function, + lighting_bind_descriptors_func }, + { "lighting_draw_splats", &cexpr_function, lighting_draw_splats_func }, + { "lighting_cull_select_renderpass", &cexpr_function, + lighting_cull_select_renderpass_func }, + { "lighting_cull_lights", &cexpr_function, lighting_cull_lights_func }, + { "lighting_draw_hulls", &cexpr_function, lighting_draw_hulls_func }, + { "lighting_draw_lights", &cexpr_function, lighting_draw_lights_func }, + { "lighting_setup_shadow", &cexpr_function, lighting_setup_shadow_func }, + { "lighting_draw_shadow_maps", &cexpr_function, + lighting_draw_shadow_maps_func }, + + { "lighting_load_lights", &cexpr_function, lighting_load_lights_func }, + { "lighting_init", &cexpr_function, lighting_init_func }, + {} +}; + +static int +round_light_size (int size) +{ + size = ((size + shadow_quanta - 1) / shadow_quanta) * shadow_quanta; + return min (size, 1024); +} + +static void +dynlight_size_listener (void *data, const cvar_t *cvar) +{ + dynlight_size = round_light_size (dynlight_size); } void -Vulkan_Lighting_Shutdown (vulkan_ctx_t *ctx) +Vulkan_Lighting_Init (vulkan_ctx_t *ctx) { qfZoneScoped (true); - auto device = ctx->device; - auto dfunc = device->funcs; - auto lctx = ctx->lighting_context; - clear_shadows (ctx); + Cvar_Register (&dynlight_size_cvar, dynlight_size_listener, 0); - QFV_DestroyResource (device, lctx->light_resources); - free (lctx->light_resources); - - for (size_t i = 0; i < lctx->frames.size; i++) { - auto lframe = &lctx->frames.a[i]; - dfunc->vkDestroyQueryPool (device->dev, lframe->query, 0); - dfunc->vkDestroyFence (device->dev, lframe->fence, 0); - qftCVkContextDestroy (lframe->qftVkCtx); - } - free (lctx->frames.a[0].stage_targets); - free (lctx->frames.a[0].id_radius); - free (lctx->frames.a[0].positions); - DARRAY_CLEAR (&lctx->light_mats); - DARRAY_CLEAR (&lctx->light_control); - free (lctx->map_images); - free (lctx->map_views); - free (lctx->map_cube); - free (lctx->frames.a); - free (lctx); + QFV_Render_AddTasks (ctx, lighting_task_syms); } static void diff --git a/libs/video/renderer/vulkan/vulkan_matrices.c b/libs/video/renderer/vulkan/vulkan_matrices.c index ba62c2cb6..b05001cc4 100644 --- a/libs/video/renderer/vulkan/vulkan_matrices.c +++ b/libs/video/renderer/vulkan/vulkan_matrices.c @@ -170,33 +170,34 @@ update_matrices (const exprval_t **params, exprval_t *result, exprctx_t *ectx) QFV_PacketSubmit (packet); } -static exprfunc_t update_matrices_func[] = { - { .func = update_matrices }, - {} -}; -static exprsym_t matrix_task_syms[] = { - { "update_matrices", &cexpr_function, update_matrices_func }, - {} -}; - -void -Vulkan_Matrix_Init (vulkan_ctx_t *ctx) +static void +matrices_shutdown (exprctx_t *ectx) { qfZoneScoped (true); - QFV_Render_AddTasks (ctx, matrix_task_syms); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "matrix shutdown"); + auto device = ctx->device; + auto mctx = ctx->matrix_context; - matrixctx_t *mctx = calloc (1, sizeof (matrixctx_t)); - ctx->matrix_context = mctx; + QFV_DestroyStagingBuffer (mctx->stage); + QFV_DestroyResource (device, mctx->resource); + free (mctx->resource); + free (mctx->frames.a); + free (mctx); + + qfvPopDebug (ctx); } -void -Vulkan_Matrix_Setup (vulkan_ctx_t *ctx) +static void +matrices_startup (exprctx_t *ectx) { qfZoneScoped (true); - qfvPushDebug (ctx, "matrix init"); - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; - + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "matrix shutdown"); + auto device = ctx->device; + auto dfunc = device->funcs; auto mctx = ctx->matrix_context; auto rctx = ctx->render_context; size_t frames = rctx->frames.size; @@ -267,21 +268,41 @@ Vulkan_Matrix_Setup (vulkan_ctx_t *ctx) qfvPopDebug (ctx); } -void -Vulkan_Matrix_Shutdown (vulkan_ctx_t *ctx) +static void +matrices_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) { qfZoneScoped (true); - qfvPushDebug (ctx, "matrix shutdown"); - auto device = ctx->device; - auto mctx = ctx->matrix_context; + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; - QFV_DestroyStagingBuffer (mctx->stage); - QFV_DestroyResource (device, mctx->resource); - free (mctx->resource); - free (mctx->frames.a); - free (mctx); + QFV_Render_AddShutdown (ctx, matrices_shutdown); + QFV_Render_AddStartup (ctx, matrices_startup); - qfvPopDebug (ctx); + matrixctx_t *mctx = calloc (1, sizeof (matrixctx_t)); + ctx->matrix_context = mctx; +} + +static exprfunc_t update_matrices_func[] = { + { .func = update_matrices }, + {} +}; + +static exprfunc_t matrices_init_func[] = { + { .func = matrices_init }, + {} +}; + +static exprsym_t matrix_task_syms[] = { + { "update_matrices", &cexpr_function, update_matrices_func }, + { "matrices_init", &cexpr_function, matrices_init_func }, + {} +}; + +void +Vulkan_Matrix_Init (vulkan_ctx_t *ctx) +{ + qfZoneScoped (true); + QFV_Render_AddTasks (ctx, matrix_task_syms); } VkDescriptorSet diff --git a/libs/video/renderer/vulkan/vulkan_output.c b/libs/video/renderer/vulkan/vulkan_output.c index d53b16b04..159a8c9e1 100644 --- a/libs/video/renderer/vulkan/vulkan_output.c +++ b/libs/video/renderer/vulkan/vulkan_output.c @@ -272,6 +272,89 @@ output_draw_fisheye (const exprval_t **params, exprval_t *result, exprctx_t *ect output_draw (taskctx, 2, push_constants); } +static void +output_shutdown (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + outputctx_t *octx = ctx->output_context; + + if (octx->framebuffers) { + for (uint32_t i = 0; i < ctx->swapchain->imageViews->size; i++) { + dfunc->vkDestroyFramebuffer (device->dev, octx->framebuffers[i], 0); + } + free (octx->framebuffers); + } + auto step = QFV_FindStep ("output", ctx->render_context->job); + auto render = step->render; + auto rp = &render->renderpasses[0]; + rp->beginInfo.framebuffer = 0; + + free (octx->frames.a); + free (octx); +} + +static void +output_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "output init"); + auto octx = ctx->output_context; + + auto rctx = ctx->render_context; + size_t frames = rctx->frames.size; + DARRAY_INIT (&octx->frames, frames); + DARRAY_RESIZE (&octx->frames, frames); + octx->frames.grow = 0; + + octx->sampler = QFV_Render_Sampler (ctx, "linear"); + + auto dsmanager = QFV_Render_DSManager (ctx, "output_set"); + + for (size_t i = 0; i < frames; i++) { + auto oframe = &octx->frames.a[i]; + oframe->input = 0; + oframe->set = QFV_DSManager_AllocSet (dsmanager); + } + + qfvPopDebug (ctx); +} + +static void +output_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + + QFV_Render_AddShutdown (ctx, output_shutdown); + QFV_Render_AddStartup (ctx, output_startup); + + 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_attachmentinfo_t *attachments[] = { + &octx->swapchain_info, + }; + QFV_Render_AddAttachments (ctx, 1, attachments); +} + static exprtype_t *stepref_param[] = { &cexpr_string, }; @@ -305,6 +388,12 @@ static exprfunc_t output_draw_fisheye_func[] = { { .func = output_draw_fisheye }, {} }; + +static exprfunc_t output_init_func[] = { + { .func = output_init }, + {} +}; + static exprsym_t output_task_syms[] = { { "acquire_output", &cexpr_function, acquire_output_func }, { "update_input", &cexpr_function, update_input_func }, @@ -314,6 +403,7 @@ static exprsym_t output_task_syms[] = { { "output_draw_flat", &cexpr_function, output_draw_flat_func }, { "output_draw_waterwarp", &cexpr_function, output_draw_waterwarp_func }, { "output_draw_fisheye", &cexpr_function, output_draw_fisheye_func }, + { "output_init", &cexpr_function, output_init_func }, {} }; @@ -321,74 +411,5 @@ void Vulkan_Output_Init (vulkan_ctx_t *ctx) { qfZoneScoped (true); - 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 -Vulkan_Output_Setup (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - qfvPushDebug (ctx, "output init"); - - auto octx = ctx->output_context; - - auto rctx = ctx->render_context; - size_t frames = rctx->frames.size; - DARRAY_INIT (&octx->frames, frames); - DARRAY_RESIZE (&octx->frames, frames); - octx->frames.grow = 0; - - octx->sampler = QFV_Render_Sampler (ctx, "linear"); - - auto dsmanager = QFV_Render_DSManager (ctx, "output_set"); - - for (size_t i = 0; i < frames; i++) { - auto oframe = &octx->frames.a[i]; - oframe->input = 0; - oframe->set = QFV_DSManager_AllocSet (dsmanager); - } - - qfvPopDebug (ctx); -} - -void -Vulkan_Output_Shutdown (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; - outputctx_t *octx = ctx->output_context; - - if (octx->framebuffers) { - for (uint32_t i = 0; i < ctx->swapchain->imageViews->size; i++) { - dfunc->vkDestroyFramebuffer (device->dev, octx->framebuffers[i], 0); - } - free (octx->framebuffers); - } - auto step = QFV_FindStep ("output", ctx->render_context->job); - auto render = step->render; - auto rp = &render->renderpasses[0]; - rp->beginInfo.framebuffer = 0; - - free (octx->frames.a); - free (octx); } diff --git a/libs/video/renderer/vulkan/vulkan_palette.c b/libs/video/renderer/vulkan/vulkan_palette.c index 5d159f46f..08efdc998 100644 --- a/libs/video/renderer/vulkan/vulkan_palette.c +++ b/libs/video/renderer/vulkan/vulkan_palette.c @@ -46,6 +46,7 @@ #include "QF/Vulkan/qf_palette.h" #include "QF/Vulkan/qf_texture.h" +#include "r_internal.h" #include "vid_vulkan.h" void @@ -62,14 +63,30 @@ Vulkan_Palette_Update (vulkan_ctx_t *ctx, const byte *palette) Vulkan_UpdateTex (ctx, pctx->palette, &tex, 0, 0, 0, 0); } -void -Vulkan_Palette_Init (vulkan_ctx_t *ctx, const byte *palette) +static void +palette_shutdown (exprctx_t *ectx) { qfZoneScoped (true); - qfvPushDebug (ctx, "palette init"); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "palette shutdown"); - palettectx_t *pctx = calloc (1, sizeof (palettectx_t)); - ctx->palette_context = pctx; + auto pctx = ctx->palette_context; + + Vulkan_UnloadTex (ctx, pctx->palette); + free (pctx); + + qfvPopDebug (ctx); +} + +static void +palette_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "palette init"); + auto pctx = ctx->palette_context; pctx->sampler = QFV_Render_Sampler (ctx, "palette_sampler"); @@ -78,7 +95,7 @@ Vulkan_Palette_Init (vulkan_ctx_t *ctx, const byte *palette) .height = 16, .format = tex_rgb, .loaded = 1, - .data = (byte *) palette, + .data = (byte *) vid.palette, }; pctx->palette = Vulkan_LoadTex (ctx, &tex, 0, "palette"); pctx->descriptor = Vulkan_CreateCombinedImageSampler (ctx, @@ -88,18 +105,35 @@ Vulkan_Palette_Init (vulkan_ctx_t *ctx, const byte *palette) qfvPopDebug (ctx); } -void -Vulkan_Palette_Shutdown (vulkan_ctx_t *ctx) +static void +palette_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) { qfZoneScoped (true); - qfvPushDebug (ctx, "palette shutdown"); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; - __auto_type pctx = ctx->palette_context; + QFV_Render_AddShutdown (ctx, palette_shutdown); + QFV_Render_AddStartup (ctx, palette_startup); - Vulkan_UnloadTex (ctx, pctx->palette); - free (pctx); + palettectx_t *pctx = calloc (1, sizeof (palettectx_t)); + ctx->palette_context = pctx; +} - qfvPopDebug (ctx); +static exprfunc_t palette_init_func[] = { + { .func = palette_init }, + {} +}; + +static exprsym_t palette_task_syms[] = { + { "palette_init", &cexpr_function, palette_init_func }, + {} +}; + +void +Vulkan_Palette_Init (vulkan_ctx_t *ctx) +{ + qfZoneScoped (true); + QFV_Render_AddTasks (ctx, palette_task_syms); } VkDescriptorSet diff --git a/libs/video/renderer/vulkan/vulkan_particles.c b/libs/video/renderer/vulkan/vulkan_particles.c index d8e26c53a..6d2059f88 100644 --- a/libs/video/renderer/vulkan/vulkan_particles.c +++ b/libs/video/renderer/vulkan/vulkan_particles.c @@ -402,50 +402,42 @@ particle_wait_physics (const exprval_t **params, exprval_t *result, dfunc->vkEndCommandBuffer (cmd); } -static exprfunc_t particles_draw_func[] = { - { .func = particles_draw }, - {} -}; -static exprfunc_t update_particles_func[] = { - { .func = update_particles }, - {} -}; -static exprfunc_t particle_physics_func[] = { - { .func = particle_physics }, - {} -}; -static exprfunc_t particle_wait_physics_func[] = { - { .func = particle_wait_physics }, - {} -}; -static exprsym_t particles_task_syms[] = { - { "particles_draw", &cexpr_function, particles_draw_func }, - { "update_particles", &cexpr_function, update_particles_func }, - { "particle_physics", &cexpr_function, particle_physics_func }, - { "particle_wait_physics", &cexpr_function, particle_wait_physics_func }, - {} -}; - -void -Vulkan_Particles_Init (vulkan_ctx_t *ctx) +static void +particle_shutdown (exprctx_t *ectx) { qfZoneScoped (true); - QFV_Render_AddTasks (ctx, particles_task_syms); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + particlectx_t *pctx = ctx->particle_context; + size_t frames = pctx->frames.size; - particlectx_t *pctx = calloc (1, sizeof (particlectx_t)); - ctx->particle_context = pctx; - pctx->psystem = &r_psystem; + for (size_t i = 0; i < frames; i++) { + __auto_type pframe = &pctx->frames.a[i]; + dfunc->vkDestroyEvent (device->dev, pframe->updateEvent, 0); + dfunc->vkDestroyEvent (device->dev, pframe->physicsEvent, 0); + } + + QFV_DestroyStagingBuffer (pctx->stage); + QFV_DestroyResource (device, pctx->resources); + free (pctx->resources); + + free (pctx->frames.a); + free (pctx); } -void -Vulkan_Particles_Setup (vulkan_ctx_t *ctx) +static void +particle_startup (exprctx_t *ectx) { qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; qfvPushDebug (ctx, "particles init"); - + auto pctx = ctx->particle_context; + pctx->psystem = &r_psystem; auto device = ctx->device; auto dfunc = device->funcs; - auto pctx = ctx->particle_context; size_t frames = ctx->render_context->frames.size; DARRAY_INIT (&pctx->frames, frames); @@ -475,27 +467,56 @@ Vulkan_Particles_Setup (vulkan_ctx_t *ctx) qfvPopDebug (ctx); } -void -Vulkan_Particles_Shutdown (vulkan_ctx_t *ctx) +static void +particle_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) { qfZoneScoped (true); - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; - particlectx_t *pctx = ctx->particle_context; - size_t frames = pctx->frames.size; + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; - for (size_t i = 0; i < frames; i++) { - __auto_type pframe = &pctx->frames.a[i]; - dfunc->vkDestroyEvent (device->dev, pframe->updateEvent, 0); - dfunc->vkDestroyEvent (device->dev, pframe->physicsEvent, 0); - } + QFV_Render_AddShutdown (ctx, particle_shutdown); + QFV_Render_AddStartup (ctx, particle_startup); - QFV_DestroyStagingBuffer (pctx->stage); - QFV_DestroyResource (device, pctx->resources); - free (pctx->resources); + particlectx_t *pctx = calloc (1, sizeof (particlectx_t)); + ctx->particle_context = pctx; +} - free (pctx->frames.a); - free (pctx); +static exprfunc_t particles_draw_func[] = { + { .func = particles_draw }, + {} +}; +static exprfunc_t update_particles_func[] = { + { .func = update_particles }, + {} +}; +static exprfunc_t particle_physics_func[] = { + { .func = particle_physics }, + {} +}; +static exprfunc_t particle_wait_physics_func[] = { + { .func = particle_wait_physics }, + {} +}; + +static exprfunc_t particle_init_func[] = { + { .func = particle_init }, + {} +}; + +static exprsym_t particles_task_syms[] = { + { "particles_draw", &cexpr_function, particles_draw_func }, + { "update_particles", &cexpr_function, update_particles_func }, + { "particle_physics", &cexpr_function, particle_physics_func }, + { "particle_wait_physics", &cexpr_function, particle_wait_physics_func }, + { "particle_init", &cexpr_function, particle_init_func }, + {} +}; + +void +Vulkan_Particles_Init (vulkan_ctx_t *ctx) +{ + qfZoneScoped (true); + QFV_Render_AddTasks (ctx, particles_task_syms); } psystem_t *__attribute__((pure))//FIXME? diff --git a/libs/video/renderer/vulkan/vulkan_planes.c b/libs/video/renderer/vulkan/vulkan_planes.c index 4418b4382..5d5ae0a37 100644 --- a/libs/video/renderer/vulkan/vulkan_planes.c +++ b/libs/video/renderer/vulkan/vulkan_planes.c @@ -128,38 +128,31 @@ debug_planes_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) dfunc->vkCmdDraw (cmd, 3, 1, 0, 0); } -static exprtype_t *debug_planes_draw_params[] = { - &cexpr_int, -}; -static exprfunc_t debug_planes_draw_func[] = { - { .func = debug_planes_draw, .num_params = 1, .param_types = debug_planes_draw_params }, - {} -}; -static exprsym_t debug_planes_task_syms[] = { - { "debug_planes_draw", &cexpr_function, debug_planes_draw_func }, - {} -}; - -void -Vulkan_Planes_Init (vulkan_ctx_t *ctx) +static void +planes_shutdown (exprctx_t *ectx) { qfZoneScoped (true); - qfvPushDebug (ctx, "debug planes init"); - QFV_Render_AddTasks (ctx, debug_planes_task_syms); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + auto device = ctx->device; + auto pctx = ctx->planes_context; - planesctx_t *pctx = calloc (1, sizeof (planesctx_t)); - ctx->planes_context = pctx; + QFV_DestroyResource (device, pctx->resources); + free (pctx->resources); - qfvPopDebug (ctx); + free (pctx->frames.a); + free (pctx); } -void -Vulkan_Planes_Setup (vulkan_ctx_t *ctx) +static void +planes_startup (exprctx_t *ectx) { qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + auto pctx = ctx->planes_context; auto device = ctx->device; auto dfunc = device->funcs; - auto pctx = ctx->planes_context; auto rctx = ctx->render_context; size_t frames = rctx->frames.size; @@ -242,16 +235,45 @@ Vulkan_Planes_Setup (vulkan_ctx_t *ctx) } } -void -Vulkan_Planes_Shutdown (vulkan_ctx_t *ctx) +static void +planes_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) { qfZoneScoped (true); - auto device = ctx->device; - auto pctx = ctx->planes_context; + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; - QFV_DestroyResource (device, pctx->resources); - free (pctx->resources); + QFV_Render_AddShutdown (ctx, planes_shutdown); + QFV_Render_AddStartup (ctx, planes_startup); - free (pctx->frames.a); - free (pctx); + planesctx_t *pctx = calloc (1, sizeof (planesctx_t)); + ctx->planes_context = pctx; +} + +static exprtype_t *debug_planes_draw_params[] = { + &cexpr_int, +}; +static exprfunc_t debug_planes_draw_func[] = { + { .func = debug_planes_draw, .num_params = 1, .param_types = debug_planes_draw_params }, + {} +}; + +static exprfunc_t planes_init_func[] = { + { .func = planes_init }, + {} +}; + +static exprsym_t debug_planes_task_syms[] = { + { "debug_planes_draw", &cexpr_function, debug_planes_draw_func }, + { "planes_init", &cexpr_function, planes_init_func }, + {} +}; + +void +Vulkan_Planes_Init (vulkan_ctx_t *ctx) +{ + qfZoneScoped (true); + qfvPushDebug (ctx, "debug planes init"); + QFV_Render_AddTasks (ctx, debug_planes_task_syms); + + qfvPopDebug (ctx); } diff --git a/libs/video/renderer/vulkan/vulkan_scene.c b/libs/video/renderer/vulkan/vulkan_scene.c index a65c32c6c..2280f03ce 100644 --- a/libs/video/renderer/vulkan/vulkan_scene.c +++ b/libs/video/renderer/vulkan/vulkan_scene.c @@ -157,37 +157,38 @@ scene_draw_viewmodel (const exprval_t **params, exprval_t *result, EntQueue_AddEntity (r_ent_queue, ent, renderer->model->type); } -static exprfunc_t scene_draw_viewmodel_func[] = { - { .func = scene_draw_viewmodel }, - {} -}; -static exprsym_t scene_task_syms[] = { - { "scene_draw_viewmodel", &cexpr_function, scene_draw_viewmodel_func }, - {} -}; - -void -Vulkan_Scene_Init (vulkan_ctx_t *ctx) +static void +scene_shutdown (exprctx_t *ectx) { qfZoneScoped (true); - QFV_Render_AddTasks (ctx, scene_task_syms); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "scene shutdown"); + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + scenectx_t *sctx = ctx->scene_context; - scenectx_t *sctx = calloc (1, sizeof (scenectx_t) - + sizeof (qfv_resource_t) - + sizeof (qfv_resobj_t)); - ctx->scene_context = sctx; - sctx->max_entities = qfv_max_entities; + for (size_t i = 0; i < sctx->frames.size; i++) { + __auto_type sframe = &sctx->frames.a[i]; + set_delete (sframe->pooled_entities); + } + + dfunc->vkUnmapMemory (device->dev, sctx->entities->memory); + QFV_DestroyResource (device, sctx->entities); + free (sctx->frames.a); + free (sctx); + qfvPopDebug (ctx); } -void -Vulkan_Scene_Setup (vulkan_ctx_t *ctx) +static void +scene_startup (exprctx_t *ectx) { qfZoneScoped (true); - qfvPushDebug (ctx, "scene init"); - + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfZoneScoped (true); auto device = ctx->device; auto dfunc = device->funcs; - auto sctx = ctx->scene_context; auto rctx = ctx->render_context; @@ -245,25 +246,44 @@ Vulkan_Scene_Setup (vulkan_ctx_t *ctx) qfvPopDebug (ctx); } +static void +scene_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) +{ + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "scene init"); + + QFV_Render_AddShutdown (ctx, scene_shutdown); + QFV_Render_AddStartup (ctx, scene_startup); + + scenectx_t *sctx = calloc (1, sizeof (scenectx_t) + + sizeof (qfv_resource_t) + + sizeof (qfv_resobj_t)); + ctx->scene_context = sctx; + sctx->max_entities = qfv_max_entities; +} + +static exprfunc_t scene_draw_viewmodel_func[] = { + { .func = scene_draw_viewmodel }, + {} +}; + +static exprfunc_t scene_init_func[] = { + { .func = scene_init }, + {} +}; + +static exprsym_t scene_task_syms[] = { + { "scene_draw_viewmodel", &cexpr_function, scene_draw_viewmodel_func }, + { "scene_init", &cexpr_function, scene_init_func }, + {} +}; + void -Vulkan_Scene_Shutdown (vulkan_ctx_t *ctx) +Vulkan_Scene_Init (vulkan_ctx_t *ctx) { qfZoneScoped (true); - qfvPushDebug (ctx, "scene shutdown"); - qfv_device_t *device = ctx->device; - qfv_devfuncs_t *dfunc = device->funcs; - scenectx_t *sctx = ctx->scene_context; - - for (size_t i = 0; i < sctx->frames.size; i++) { - __auto_type sframe = &sctx->frames.a[i]; - set_delete (sframe->pooled_entities); - } - - dfunc->vkUnmapMemory (device->dev, sctx->entities->memory); - QFV_DestroyResource (device, sctx->entities); - free (sctx->frames.a); - free (sctx); - qfvPopDebug (ctx); + QFV_Render_AddTasks (ctx, scene_task_syms); } void diff --git a/libs/video/renderer/vulkan/vulkan_sprite.c b/libs/video/renderer/vulkan/vulkan_sprite.c index 38e9b391a..4d9eb9793 100644 --- a/libs/video/renderer/vulkan/vulkan_sprite.c +++ b/libs/video/renderer/vulkan/vulkan_sprite.c @@ -205,12 +205,52 @@ sprite_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) } } +static void +sprite_shutdown (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + spritectx_t *sctx = ctx->sprite_context; + + free (sctx); +} + +static void +sprite_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + auto sctx = ctx->sprite_context; + sctx->sampler = QFV_Render_Sampler (ctx, "sprite_sampler"); +} + +static void +sprite_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + QFV_Render_AddShutdown (ctx, sprite_shutdown); + QFV_Render_AddStartup (ctx, sprite_startup); + spritectx_t *sctx = calloc (1, sizeof (spritectx_t)); + ctx->sprite_context = sctx; +} + static exprfunc_t sprite_draw_func[] = { { .func = sprite_draw }, {} }; + +static exprfunc_t sprite_init_func[] = { + { .func = sprite_init }, + {} +}; + static exprsym_t sprite_task_syms[] = { { "sprite_draw", &cexpr_function, sprite_draw_func }, + { "sprite_init", &cexpr_function, sprite_init_func }, {} }; @@ -221,25 +261,5 @@ Vulkan_Sprite_Init (vulkan_ctx_t *ctx) qfvPushDebug (ctx, "sprite init"); QFV_Render_AddTasks (ctx, sprite_task_syms); - spritectx_t *sctx = calloc (1, sizeof (spritectx_t)); - ctx->sprite_context = sctx; - qfvPopDebug (ctx); } - -void -Vulkan_Sprite_Setup (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - auto sctx = ctx->sprite_context; - sctx->sampler = QFV_Render_Sampler (ctx, "sprite_sampler"); -} - -void -Vulkan_Sprite_Shutdown (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - spritectx_t *sctx = ctx->sprite_context; - - free (sctx); -} diff --git a/libs/video/renderer/vulkan/vulkan_texture.c b/libs/video/renderer/vulkan/vulkan_texture.c index eafa6495f..d3cda8af2 100644 --- a/libs/video/renderer/vulkan/vulkan_texture.c +++ b/libs/video/renderer/vulkan/vulkan_texture.c @@ -506,20 +506,26 @@ static tex_t default_magenta_tex = { .data = magenta_data, }; -void -Vulkan_Texture_Init (vulkan_ctx_t *ctx) +static void +texture_shutdown (exprctx_t *ectx) { qfZoneScoped (true); - texturectx_t *tctx = calloc (1, sizeof (texturectx_t)); - ctx->texture_context = tctx; + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + Vulkan_UnloadTex (ctx, ctx->default_black); + Vulkan_UnloadTex (ctx, ctx->default_white); + Vulkan_UnloadTex (ctx, ctx->default_magenta); + Vulkan_UnloadTex (ctx, ctx->default_magenta_array); + free (ctx->texture_context); } -void -Vulkan_Texture_Setup (vulkan_ctx_t *ctx) +static void +texture_startup (exprctx_t *ectx) { qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; qfvPushDebug (ctx, "texture init"); - auto tctx = ctx->texture_context; tctx->dsmanager = QFV_Render_DSManager (ctx, "texture_set"); @@ -543,15 +549,35 @@ Vulkan_Texture_Setup (vulkan_ctx_t *ctx) qfvPopDebug (ctx); } -void -Vulkan_Texture_Shutdown (vulkan_ctx_t *ctx) +static void +texture_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) { qfZoneScoped (true); - Vulkan_UnloadTex (ctx, ctx->default_black); - Vulkan_UnloadTex (ctx, ctx->default_white); - Vulkan_UnloadTex (ctx, ctx->default_magenta); - Vulkan_UnloadTex (ctx, ctx->default_magenta_array); - free (ctx->texture_context); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + + QFV_Render_AddShutdown (ctx, texture_shutdown); + QFV_Render_AddStartup (ctx, texture_startup); + + texturectx_t *tctx = calloc (1, sizeof (texturectx_t)); + ctx->texture_context = tctx; +} + +static exprfunc_t texture_init_func[] = { + { .func = texture_init }, + {} +}; + +static exprsym_t texture_task_syms[] = { + { "texture_init", &cexpr_function, texture_init_func }, + {} +}; + +void +Vulkan_Texture_Init (vulkan_ctx_t *ctx) +{ + qfZoneScoped (true); + QFV_Render_AddTasks (ctx, texture_task_syms); } static VkDescriptorImageInfo base_image_info = { diff --git a/libs/video/renderer/vulkan/vulkan_translucent.c b/libs/video/renderer/vulkan/vulkan_translucent.c index 5a06ee139..65a552f58 100644 --- a/libs/video/renderer/vulkan/vulkan_translucent.c +++ b/libs/video/renderer/vulkan/vulkan_translucent.c @@ -191,28 +191,6 @@ clear_translucent (const exprval_t **params, exprval_t *result, exprctx_t *ectx) QFV_PacketSubmit (packet); } -static exprtype_t *clear_translucent_params[] = { - &cexpr_string, -}; -static exprfunc_t clear_translucent_func[] = { - { .func = clear_translucent, .num_params = 1, clear_translucent_params }, - {} -}; -static exprsym_t translucent_task_syms[] = { - { "clear_translucent", &cexpr_function, clear_translucent_func }, - {} -}; - -void -Vulkan_Translucent_Init (vulkan_ctx_t *ctx) -{ - qfZoneScoped (true); - QFV_Render_AddTasks (ctx, translucent_task_syms); - - translucentctx_t *tctx = calloc (1, sizeof (translucentctx_t)); - ctx->translucent_context = tctx; -} - static void trans_create_resources (vulkan_ctx_t *ctx) { @@ -307,12 +285,36 @@ trans_create_resources (vulkan_ctx_t *ctx) } } -void -Vulkan_Translucent_Setup (vulkan_ctx_t *ctx) +static void +translucent_shutdown (exprctx_t *ectx) { qfZoneScoped (true); - qfvPushDebug (ctx, "translucent init"); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfv_device_t *device = ctx->device; + translucentctx_t *tctx = ctx->translucent_context; + if (tctx->resources) { + if (tctx->resources->memory) { + QFV_DestroyResource (device, tctx->resources); + } + for (uint32_t i = 0; i < tctx->resources->num_objects; i++) { + auto obj = &tctx->resources->objects[i]; + free ((char *) obj->name); + } + } + free (tctx->resources); + free (tctx->frames.a); + free (tctx); +} + +static void +translucent_startup (exprctx_t *ectx) +{ + qfZoneScoped (true); + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; + qfvPushDebug (ctx, "translucent init"); auto tctx = ctx->translucent_context; auto rctx = ctx->render_context; @@ -334,25 +336,44 @@ Vulkan_Translucent_Setup (vulkan_ctx_t *ctx) qfvPopDebug (ctx); } -void -Vulkan_Translucent_Shutdown (vulkan_ctx_t *ctx) +static void +translucent_init (const exprval_t **params, exprval_t *result, exprctx_t *ectx) { qfZoneScoped (true); - qfv_device_t *device = ctx->device; - translucentctx_t *tctx = ctx->translucent_context; + auto taskctx = (qfv_taskctx_t *) ectx; + auto ctx = taskctx->ctx; - if (tctx->resources) { - if (tctx->resources->memory) { - QFV_DestroyResource (device, tctx->resources); - } - for (uint32_t i = 0; i < tctx->resources->num_objects; i++) { - auto obj = &tctx->resources->objects[i]; - free ((char *) obj->name); - } - } - free (tctx->resources); - free (tctx->frames.a); - free (tctx); + QFV_Render_AddShutdown (ctx, translucent_shutdown); + QFV_Render_AddStartup (ctx, translucent_startup); + + translucentctx_t *tctx = calloc (1, sizeof (translucentctx_t)); + ctx->translucent_context = tctx; +} + +static exprtype_t *clear_translucent_params[] = { + &cexpr_string, +}; +static exprfunc_t clear_translucent_func[] = { + { .func = clear_translucent, .num_params = 1, clear_translucent_params }, + {} +}; + +static exprfunc_t translucent_init_func[] = { + { .func = translucent_init }, + {} +}; + +static exprsym_t translucent_task_syms[] = { + { "clear_translucent", &cexpr_function, clear_translucent_func }, + { "translucent_init", &cexpr_function, translucent_init_func }, + {} +}; + +void +Vulkan_Translucent_Init (vulkan_ctx_t *ctx) +{ + qfZoneScoped (true); + QFV_Render_AddTasks (ctx, translucent_task_syms); } VkDescriptorSet