From e5708100bbf8b65a9578c472a2be68d36c1b4e99 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 5 Jan 2021 14:15:35 +0900 Subject: [PATCH] [vulkan] Generate code for resource nodes This makes it easy to add resource nodes defining contextually named resources. It is already used for shaders, set layouts, and pipeline layouts. --- include/QF/Vulkan/shader.h | 5 - include/vid_vulkan.h | 3 +- libs/video/renderer/vulkan/qfpipeline.plist | 22 ++-- libs/video/renderer/vulkan/shader.c | 71 +---------- .../video/renderer/vulkan/vkgen/Makemodule.am | 1 + libs/video/renderer/vulkan/vkgen/vkgen.r | 16 +++ libs/video/renderer/vulkan/vkgen/vkhandle.r | 66 +++++----- libs/video/renderer/vulkan/vkgen/vkresource.h | 9 ++ libs/video/renderer/vulkan/vkgen/vkresource.r | 44 +++++++ libs/video/renderer/vulkan/vkparse.c | 118 ++++++++++++++---- libs/video/renderer/vulkan/vkparse.h | 12 +- libs/video/renderer/vulkan/vkparse.plist | 36 +++++- .../video/renderer/vulkan/vulkan_vid_common.c | 40 +----- 13 files changed, 257 insertions(+), 186 deletions(-) create mode 100644 libs/video/renderer/vulkan/vkgen/vkresource.h create mode 100644 libs/video/renderer/vulkan/vkgen/vkresource.r diff --git a/include/QF/Vulkan/shader.h b/include/QF/Vulkan/shader.h index 41b38a862..f44189978 100644 --- a/include/QF/Vulkan/shader.h +++ b/include/QF/Vulkan/shader.h @@ -10,10 +10,5 @@ VkShaderModule QFV_CreateShaderModule (struct qfv_device_s *device, const char *path); void QFV_DestroyShaderModule (struct qfv_device_s *device, VkShaderModule module); -VkShaderModule QFV_FindShaderModule (struct vulkan_ctx_s *ctx, - const char *name); -void QFV_RegisterShaderModule (struct vulkan_ctx_s *ctx, const char *name, - VkShaderModule module); -void QFV_DeregisterShaderModule (struct vulkan_ctx_s *ctx, const char *name); #endif//__QF_Vulkan_shader_h diff --git a/include/vid_vulkan.h b/include/vid_vulkan.h index d35c0139d..1741165ee 100644 --- a/include/vid_vulkan.h +++ b/include/vid_vulkan.h @@ -44,11 +44,10 @@ typedef struct vulkan_ctx_s { VkSampleCountFlagBits msaaSamples; // FIXME not here? struct hashlink_s *hashlinks; //FIXME want per thread VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain - struct hashtab_s *shadermodules; + struct hashtab_s *shaderModules; struct hashtab_s *setLayouts; struct hashtab_s *pipelineLayouts; struct hashtab_s *renderPasses; - struct shadermodule_s *shadermodule_freelist; VkCommandPool cmdpool; VkCommandBuffer cmdbuffer; diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index d619b8406..ed74f689a 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -1,19 +1,13 @@ { - modules = ( + shaderModules = { // specify shader modules to load into memory - { - // the name of the module for referecy by the pipeline - name = passthrough; - // the path to the spv file to load - // $shader refers to the shader install path - // $builtin refers to compiled-in shaders - file = $builtin/passthrough.vert; - }, - { - name = pushcolor; - file = $builtin/pushcolor.frag; - }, - ); + // key is the name of the module for referecy by the pipeline + // value the path to the spv file to load + // $shader refers to the shader install path + // $builtin refers to compiled-in shaders + passthrough = $builtin/passthrough.vert; + pushcolor = $builtin/pushcolor.frag; + }; setLayouts = { something = { flags = 0; diff --git a/libs/video/renderer/vulkan/shader.c b/libs/video/renderer/vulkan/shader.c index e55833782..f0064bb35 100644 --- a/libs/video/renderer/vulkan/shader.c +++ b/libs/video/renderer/vulkan/shader.c @@ -65,14 +65,6 @@ typedef struct shaderdata_s { size_t size; } shaderdata_t; -typedef struct shadermodule_s { - char *name; - union { - VkShaderModule module; - struct shadermodule_s *next; - }; -} shadermodule_t; - static shaderdata_t builtin_shaders[] = { { "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) }, { "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) }, @@ -122,6 +114,9 @@ QFV_CreateShaderModule (qfv_device_t *device, const char *shader_path) } if (data) { + Sys_MaskPrintf (SYS_VULKAN, + "QFV_CreateShaderModule: creating shader module %s\n", + shader_path); VkShaderModuleCreateInfo createInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, 0, 0, data->size, data->data @@ -151,63 +146,3 @@ QFV_DestroyShaderModule (qfv_device_t *device, VkShaderModule module) dfunc->vkDestroyShaderModule (dev, module, 0); } - -static shadermodule_t * -new_module (vulkan_ctx_t *ctx) -{ - shadermodule_t *shadermodule; - ALLOC (128, shadermodule_t, ctx->shadermodule, shadermodule); - return shadermodule; -} - -static void -del_module (shadermodule_t *shadermodule, vulkan_ctx_t *ctx) -{ - free (shadermodule->name); - FREE (ctx->shadermodule, shadermodule); -} - -static const char * -sm_getkey (const void *sm, void *unused) -{ - return ((shadermodule_t *) sm)->name; -} - -static void -sm_free (void *sm, void *ctx) -{ - del_module (sm, ctx); -} - -VkShaderModule -QFV_FindShaderModule (vulkan_ctx_t *ctx, const char *name) -{ - //FIXME - if (!ctx->shadermodules) { - ctx->shadermodules = Hash_NewTable (127, sm_getkey, sm_free, ctx, 0); - } - return Hash_Find (ctx->shadermodules, name); -} - -void -QFV_RegisterShaderModule (vulkan_ctx_t *ctx, const char *name, - VkShaderModule module) -{ - //FIXME - if (!ctx->shadermodules) { - ctx->shadermodules = Hash_NewTable (127, sm_getkey, sm_free, ctx, 0); - } - shadermodule_t *shadermodule = new_module (ctx); - shadermodule->name = strdup (name); - shadermodule->module = module; - Hash_Add (ctx->shadermodules, shadermodule); -} - -void -QFV_DeregisterShaderModule (vulkan_ctx_t *ctx, const char *name) -{ - if (!ctx->shadermodules) { - return; - } - Hash_Free (ctx->shadermodules, Hash_Del (ctx->shadermodules, name)); -} diff --git a/libs/video/renderer/vulkan/vkgen/Makemodule.am b/libs/video/renderer/vulkan/vkgen/Makemodule.am index 21c2ae97e..2fba61b0b 100644 --- a/libs/video/renderer/vulkan/vkgen/Makemodule.am +++ b/libs/video/renderer/vulkan/vkgen/Makemodule.am @@ -14,6 +14,7 @@ vkgen_dat_src= \ libs/video/renderer/vulkan/vkgen/vkfieldtype.r \ libs/video/renderer/vulkan/vkgen/vkgen.r \ libs/video/renderer/vulkan/vkgen/vkhandle.r \ + libs/video/renderer/vulkan/vkgen/vkresource.r \ libs/video/renderer/vulkan/vkgen/vkstruct.r \ libs/video/renderer/vulkan/vkgen/vktype.r \ libs/video/renderer/vulkan/vkgen/vulkan.r diff --git a/libs/video/renderer/vulkan/vkgen/vkgen.r b/libs/video/renderer/vulkan/vkgen/vkgen.r index 3d4837744..4636df52f 100644 --- a/libs/video/renderer/vulkan/vkgen/vkgen.r +++ b/libs/video/renderer/vulkan/vkgen/vkgen.r @@ -11,6 +11,7 @@ #include "vkstruct.h" #include "vkenum.h" #include "vkhandle.h" +#include "vkresource.h" static AutoreleasePool *autorelease_pool; static void @@ -150,6 +151,7 @@ main(int argc, string *argv) PLItem *plist; PLItem *search; PLItem *handles; + PLItem *resources; arp_start (); @@ -174,6 +176,7 @@ main(int argc, string *argv) } search = [[plist getObjectForKey: "search"] retain]; handles = [[plist getObjectForKey: "handles"] retain]; + resources = [[plist getObjectForKey: "resources"] retain]; parse = [[plist getObjectForKey: "parse"] retain]; encodings = PR_FindGlobal (".type_encodings"); @@ -259,6 +262,19 @@ main(int argc, string *argv) string key = [[handle_keys getObjectAtIndex:i] string]; output_handle (key, [handles getObjectForKey: key]); } + for (int i = [resources count]; i-- > 0; ) { + PLItem *res = [resources getObjectAtIndex:i]; + output_resource_data (res); + } + // keep the order intuitive (since it matters) + fprintf (output_file, "static parseres_t parse_resources[] = {\n"); + for (int i = 0; i < [resources count]; i++) { + PLItem *res = [resources getObjectAtIndex:i]; + output_resource_entry (res); + } + fprintf (output_file, "\t{}\n"); + fprintf (output_file, "};\n"); + fprintf (output_file, "static void\n"); fprintf (output_file, "vkgen_init_symtabs (exprctx_t *context)\n"); fprintf (output_file, "{\n"); diff --git a/libs/video/renderer/vulkan/vkgen/vkhandle.r b/libs/video/renderer/vulkan/vkgen/vkhandle.r index d6e9a7f52..da4a4fbcc 100644 --- a/libs/video/renderer/vulkan/vkgen/vkhandle.r +++ b/libs/video/renderer/vulkan/vkgen/vkhandle.r @@ -10,46 +10,54 @@ output_handle (string name, PLItem *handle) string symtab = str_hold ([[handle getObjectForKey:"symtab"] string]); string class = str_hold ([[handle getObjectForKey:"class"] string]); string create = str_hold ([[handle getObjectForKey:"create"] string]); - fprintf (output_file, "static int parse_%s (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context)\n", name); - fprintf (output_file, "{\n"); - fprintf (output_file, "\t__auto_type handle = (%s *) data;\n", name); - fprintf (output_file, "\tvulkan_ctx_t *ctx = ((parsectx_t *) context)->vctx;\n"); - fprintf (output_file, "\tqfv_device_t *device = ctx->device;\n"); - fprintf (output_file, "\tqfv_devfuncs_t *dfunc = device->funcs;\n"); - fprintf (output_file, "\tif (PL_Type (item) == QFString) {\n"); - fprintf (output_file, "\t\tconst char *name = PL_String (item);\n"); - fprintf (output_file, "\t\thandleref_t *hr = Hash_Find (ctx->%s, name);\n", symtab); - fprintf (output_file, "\t\tif (!hr) {\n"); - fprintf (output_file, "\t\t\tPL_Message (messages, item, \"undefined %s %%s\", name);\n", class); - fprintf (output_file, "\t\t\treturn 0;\n"); - fprintf (output_file, "\t\t}\n"); - fprintf (output_file, "\t\t*handle = (%s) hr->handle;\n", name); - fprintf (output_file, "\t\treturn 1;\n"); - fprintf (output_file, "\t}\n"); + string custom = str_hold ([[handle getObjectForKey:"custom"] string]); + if (!custom) { + fprintf (output_file, "static int parse_%s (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context)\n", name); + fprintf (output_file, "{\n"); + fprintf (output_file, "\t__auto_type handle = (%s *) data;\n", name); + fprintf (output_file, "\tvulkan_ctx_t *ctx = ((parsectx_t *) context)->vctx;\n"); + fprintf (output_file, "\tqfv_device_t *device = ctx->device;\n"); + fprintf (output_file, "\tqfv_devfuncs_t *dfunc = device->funcs;\n"); + fprintf (output_file, "\tif (PL_Type (item) == QFString) {\n"); + fprintf (output_file, "\t\tconst char *name = PL_String (item);\n"); + fprintf (output_file, "\t\thandleref_t *hr = Hash_Find (ctx->%s, name);\n", symtab); + fprintf (output_file, "\t\tif (!hr) {\n"); + fprintf (output_file, "\t\t\tPL_Message (messages, item, \"undefined %s %%s\", name);\n", class); + fprintf (output_file, "\t\t\treturn 0;\n"); + fprintf (output_file, "\t\t}\n"); + fprintf (output_file, "\t\t*handle = (%s) hr->handle;\n", name); + fprintf (output_file, "\t\treturn 1;\n"); + fprintf (output_file, "\t}\n"); - fprintf (output_file, "\t%sCreateInfo createInfo = {};\n", name); + fprintf (output_file, "\t%sCreateInfo createInfo = {};\n", name); - fprintf (output_file, "\tif (!parse_%sCreateInfo (0, item, &createInfo, messages, context)) {\n", name); - fprintf (output_file, "\t\treturn 0;\n"); - fprintf (output_file, "\t}\n"); - fprintf (output_file, "\tVkResult res;\n"); - fprintf (output_file, "\tres = dfunc->%s (device->dev, &createInfo, 0, handle);\n", create); - fprintf (output_file, "\tif (res != VK_SUCCESS) {\n"); - fprintf (output_file, "\t\tPL_Message (messages, item, \"could not create %s\");\n", class); - fprintf (output_file, "\t\treturn 0;\n"); - fprintf (output_file, "\t}\n"); - fprintf (output_file, "\treturn 1;\n"); - fprintf (output_file, "}\n"); + fprintf (output_file, "\tif (!parse_%sCreateInfo (0, item, &createInfo, messages, context)) {\n", name); + fprintf (output_file, "\t\treturn 0;\n"); + fprintf (output_file, "\t}\n"); + fprintf (output_file, "\tVkResult res;\n"); + fprintf (output_file, "\tres = dfunc->%s (device->dev, &createInfo, 0, handle);\n", create); + fprintf (output_file, "\tif (res != VK_SUCCESS) {\n"); + fprintf (output_file, "\t\tPL_Message (messages, item, \"could not create %s\");\n", class); + fprintf (output_file, "\t\treturn 0;\n"); + fprintf (output_file, "\t}\n"); + fprintf (output_file, "\treturn 1;\n"); + fprintf (output_file, "}\n"); + } fprintf (output_file, "int parse_%s_handleref (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context)\n", name); fprintf (output_file, "{\n"); fprintf (output_file, "\thandleref_t *handleref = data;\n"); fprintf (output_file, "\thandleref->name = strdup (field->name);\n"); - fprintf (output_file, "\treturn parse_%s (field, item, &handleref->handle, messages, context);\n", name); + if (custom) { + fprintf (output_file, "\treturn %s (field, item, &handleref->handle, messages, context);\n", custom); + } else { + fprintf (output_file, "\treturn parse_%s (field, item, &handleref->handle, messages, context);\n", name); + } fprintf (output_file, "}\n"); fprintf (header_file, "static int parse_%s (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context);\n", name); fprintf (header_file, "int parse_%s_handleref (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context);\n", name); + str_free (custom); str_free (symtab); str_free (class); str_free (create); diff --git a/libs/video/renderer/vulkan/vkgen/vkresource.h b/libs/video/renderer/vulkan/vkgen/vkresource.h new file mode 100644 index 000000000..e72042c3e --- /dev/null +++ b/libs/video/renderer/vulkan/vkgen/vkresource.h @@ -0,0 +1,9 @@ +#ifndef __renderer_vulkan_vkgen_vkresource_h +#define __renderer_vulkan_vkgen_vkresource_h + +@class PLItem; + +void output_resource_data (PLItem *resource); +void output_resource_entry (PLItem *resource); + +#endif//__renderer_vulkan_vkgen_vkresource_h diff --git a/libs/video/renderer/vulkan/vkgen/vkresource.r b/libs/video/renderer/vulkan/vkgen/vkresource.r new file mode 100644 index 000000000..47478d9f8 --- /dev/null +++ b/libs/video/renderer/vulkan/vkgen/vkresource.r @@ -0,0 +1,44 @@ +#include +#include + +#include "vkgen.h" +#include "vkresource.h" + +void +output_resource_data (PLItem *resource) +{ + string name = str_hold ([[resource getObjectForKey:"name"] string]); + string parse_type = str_hold ([[resource getObjectForKey:"parse_type"] string]); + string parser = str_hold ([[resource getObjectForKey:"parser"] string]); + string type = str_hold ([[resource getObjectForKey:"type"] string]); + + fprintf (output_file, "static plelement_t resource_%s_data = {\n", name); + fprintf (output_file, "\t%s,\n", parse_type); + fprintf (output_file, "\tsizeof (%s),\n", type); + fprintf (output_file, "\tmalloc,\n"); + fprintf (output_file, "\t%s,\n", parser); + fprintf (output_file, "\t0,\n"); + fprintf (output_file, "};\n"); + + fprintf (output_file, "static plfield_t resource_%s_field = {\n", name); + fprintf (output_file, "\t0, 0, %s, 0, &resource_%s_data\n", + parse_type, name); + fprintf (output_file, "};\n"); + + str_free (name); + str_free (parse_type); + str_free (parser); + str_free (type); +} + +void +output_resource_entry (PLItem *resource) +{ + string name = str_hold ([[resource getObjectForKey:"name"] string]); + string table = str_hold ([[resource getObjectForKey:"table"] string]); + fprintf (output_file, + "\t{\"%s\", &resource_%s_field, field_offset (vulkan_ctx_t, %s) },\n", + name, name, table); + str_free (name); + str_free (table); +} diff --git a/libs/video/renderer/vulkan/vkparse.c b/libs/video/renderer/vulkan/vkparse.c index af22a1dc0..418ef707d 100644 --- a/libs/video/renderer/vulkan/vkparse.c +++ b/libs/video/renderer/vulkan/vkparse.c @@ -207,6 +207,9 @@ parse_enum (const plfield_t *field, const plitem_t *item, // field->name, field->offset, field->type, field->parser, // field->data, valstr); ret = !cexpr_parse_enum (enm, valstr, &ectx, data); + if (!ret) { + PL_Message (messages, item, "error parsing enum: %s", valstr); + } //Sys_Printf (" %d\n", *(int *)data); return ret; } @@ -347,24 +350,37 @@ parse_RGBA (const plitem_t *item, void **data, } static int -parse_VkShaderModule (const plitem_t *item, void **data, - plitem_t *messages, parsectx_t *context) +parse_VkShaderModule (const plfield_t *field, const plitem_t *item, void *data, + plitem_t *messages, void *context) { - vulkan_ctx_t *ctx = context->vctx; + __auto_type handle = (VkShaderModule *) data; + vulkan_ctx_t *ctx = ((parsectx_t *) context)->vctx; + const char *name = PL_String (item); - __auto_type mptr = (VkShaderModule *)data[0]; - VkShaderModule module = QFV_FindShaderModule (ctx, name); - if (module) { - *mptr = module; - return 1; + handleref_t *hr = Hash_Find (ctx->shaderModules, name); + if (!hr) { + PL_Message (messages, item, "undefined shader module %s", name); + return 0; } - return 0; + *handle = (VkShaderModule) hr->handle; + return 1; } -typedef struct handleref_s { - char *name; - uint64_t handle; -} handleref_t; +static int +parse_VkShaderModule_resource (const plfield_t *field, const plitem_t *item, + void *data, plitem_t *messages, void *context) +{ + __auto_type handle = (VkShaderModule *) data; + vulkan_ctx_t *ctx = ((parsectx_t *) context)->vctx; + qfv_device_t *device = ctx->device; + + const char *shader_path = PL_String (item); + if (!(*handle = QFV_CreateShaderModule (device, shader_path))) { + PL_Message (messages, item, "could not find shader %s", shader_path); + return 0; + } + return 1; +} static const char * handleref_getkey (const void *hr, void *unused) @@ -393,6 +409,45 @@ setLayout_free (void *hr, void *_ctx) handleref_free (handleref, ctx); } +static void +shaderModule_free (void *hr, void *_ctx) +{ + __auto_type handleref = (handleref_t *) hr; + __auto_type module = (VkShaderModule) handleref->handle; + __auto_type ctx = (vulkan_ctx_t *) _ctx; + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + dfunc->vkDestroyShaderModule (device->dev, module, 0); + handleref_free (handleref, ctx); +} + +static void +pipelineLayout_free (void *hr, void *_ctx) +{ + __auto_type handleref = (handleref_t *) hr; + __auto_type layout = (VkPipelineLayout) handleref->handle; + __auto_type ctx = (vulkan_ctx_t *) _ctx; + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + dfunc->vkDestroyPipelineLayout (device->dev, layout, 0); + handleref_free (handleref, ctx); +} + +static void +renderPass_free (void *hr, void *_ctx) +{ + __auto_type handleref = (handleref_t *) hr; + __auto_type renderPass = (VkRenderPass) handleref->handle; + __auto_type ctx = (vulkan_ctx_t *) _ctx; + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + dfunc->vkDestroyRenderPass (device->dev, renderPass, 0); + handleref_free (handleref, ctx); +} + static hashtab_t *enum_symtab; static int @@ -406,16 +461,6 @@ parse_BasePipeline (const plitem_t *item, void **data, #include "libs/video/renderer/vulkan/vkparse.cinc" -static plelement_t setLayout_data = { - QFDictionary, - sizeof (handleref_t), - malloc, - parse_VkDescriptorSetLayout_handleref, - 0, -}; - -static plfield_t setLayout_field = { 0, 0, QFDictionary, 0, &setLayout_data }; - typedef struct qfv_renderpass_s { qfv_attachmentdescription_t *attachments; qfv_subpassparametersset_t *subpasses; @@ -509,27 +554,46 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist) } void -QFV_ParseDescriptorSetLayouts (vulkan_ctx_t *ctx, plitem_t *sets) +QFV_ParseResources (vulkan_ctx_t *ctx, plitem_t *pipelinedef) { plitem_t *messages = PL_NewArray (); exprctx_t exprctx = {}; parsectx_t parsectx = { &exprctx, ctx }; + int ret = 1; exprctx.memsuper = new_memsuper (); exprctx.messages = messages; exprctx.hashlinks = ctx->hashlinks; if (!ctx->setLayouts) { + ctx->shaderModules = Hash_NewTable (23, handleref_getkey, + shaderModule_free, + ctx, &exprctx.hashlinks); ctx->setLayouts = Hash_NewTable (23, handleref_getkey, setLayout_free, ctx, &exprctx.hashlinks); + ctx->pipelineLayouts = Hash_NewTable (23, handleref_getkey, + pipelineLayout_free, + ctx, &exprctx.hashlinks); + ctx->renderPasses = Hash_NewTable (23, handleref_getkey, + renderPass_free, + ctx, &exprctx.hashlinks); } - int res = PL_ParseSymtab (&setLayout_field, sets, ctx->setLayouts, - messages, &parsectx); - if (!res || developer->int_val & SYS_VULKAN) { + + for (parseres_t *res = parse_resources; res->name; res++) { + plitem_t *item = PL_ObjectForKey (pipelinedef, res->name); + if (item) { + __auto_type table = *(hashtab_t **) ((size_t) ctx + res->offset); + Sys_Printf ("found %s\n", res->name); + ret &= PL_ParseSymtab (res->field, item, table, messages, + &parsectx); + } + } + if (!ret || developer->int_val & SYS_VULKAN) { for (int i = 0; i < PL_A_NumObjects (messages); i++) { Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i))); } } + PL_Free (messages); delete_memsuper (exprctx.memsuper); ctx->hashlinks = exprctx.hashlinks; diff --git a/libs/video/renderer/vulkan/vkparse.h b/libs/video/renderer/vulkan/vkparse.h index 0f47ac16a..e63bb44e2 100644 --- a/libs/video/renderer/vulkan/vkparse.h +++ b/libs/video/renderer/vulkan/vkparse.h @@ -12,9 +12,19 @@ typedef struct parsectx_s { struct vulkan_ctx_s *vctx; } parsectx_t; +typedef struct parseres_s { + const char *name; + plfield_t *field; + size_t offset; +} parseres_t; + +typedef struct handleref_s { + char *name; + uint64_t handle; +} handleref_t; -void QFV_ParseDescriptorSetLayouts (vulkan_ctx_t *ctx, plitem_t *sets); VkRenderPass QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist); +void QFV_ParseResources (vulkan_ctx_t *ctx, plitem_t *plist); void QFV_InitParse (void); exprenum_t *QFV_GetEnum (const char *name); diff --git a/libs/video/renderer/vulkan/vkparse.plist b/libs/video/renderer/vulkan/vkparse.plist index c816b32c4..844b471f9 100644 --- a/libs/video/renderer/vulkan/vkparse.plist +++ b/libs/video/renderer/vulkan/vkparse.plist @@ -21,6 +21,11 @@ qfv_swapchain_t, ); handles = { + VkShaderModule = { + symtab = shaderModules; + class = "shader module"; + custom = parse_VkShaderModule_resource; + }; VkDescriptorSetLayout = { symtab = setLayouts; class = "set layout"; @@ -37,6 +42,29 @@ create = vkCreatePipelineLayout; }; }; + resources = ( + { + name = shaderModules; + parse_type = QFString; + parser = parse_VkShaderModule_handleref; + type = handleref_t; + table = shaderModules; + }, + { + name = setLayouts; + parse_type = QFDictionary; + parser = parse_VkDescriptorSetLayout_handleref; + type = handleref_t; + table = setLayouts; + }, + { + name = pipelineLayouts; + parse_type = QFDictionary; + parser = parse_VkPipelineLayout_handleref; + type = handleref_t; + table = pipelineLayouts; + }, + ); parse = { qfv_swapchain_s = { .name = qfv_swapchain_t; @@ -108,8 +136,12 @@ string = pName; }; module = { - type = (custom, QFString, parse_VkShaderModule); - fields = (module); + type = (single, { + parse_type = QFString; + type = VkShaderModule; + parser = parse_VkShaderModule; + }); + value = module; }; specializationInfo = { type = (single, VkSpecializationInfo); diff --git a/libs/video/renderer/vulkan/vulkan_vid_common.c b/libs/video/renderer/vulkan/vulkan_vid_common.c index f515abd83..12c9a463b 100644 --- a/libs/video/renderer/vulkan/vulkan_vid_common.c +++ b/libs/video/renderer/vulkan/vulkan_vid_common.c @@ -403,46 +403,10 @@ void Vulkan_CreatePipelines (vulkan_ctx_t *ctx) { plitem_t *pipeline_def = qfv_load_pipeline (); - plitem_t *item; - item = pipeline_def; - if (!item || !(item = PL_ObjectForKey (item, "modules"))) { - Sys_Printf ("error loading modules\n"); - } else { - Sys_Printf ("Found modules def\n"); + if (pipeline_def) { + QFV_ParseResources (ctx, pipeline_def); } - for (int i = PL_A_NumObjects (item); i-- > 0; ) { - plitem_t *mod = PL_ObjectAtIndex (item, i); - const char *name = PL_String (PL_ObjectForKey (mod, "name")); - const char *file = PL_String (PL_ObjectForKey (mod, "file")); - if (!name || !file) { - continue; - } - if (QFV_FindShaderModule (ctx, name)) { - continue; - } - VkShaderModule module = QFV_CreateShaderModule (ctx->device, file); - if (module) { - Sys_Printf ("registering shader %s %p\n", name, module); - QFV_RegisterShaderModule (ctx, name, module); - } - } - - item = pipeline_def; - if (!item || !(item = PL_ObjectForKey (item, "setLayouts"))) { - Sys_Printf ("error loading setLayouts\n"); - } else { - Sys_Printf ("Found setLayouts\n"); - QFV_ParseDescriptorSetLayouts (ctx, item); - } - - /*item = pipeline_def; - if (!item || !(item = PL_ObjectForKey (item, "pipelineLayouts"))) { - Sys_Printf ("error loading pipelineLayouts\n"); - } else { - Sys_Printf ("Found pipelineLayouts\n"); - QFV_ParsePipelineLayouts (ctx, item); - }*/ } void