From 8179c44042c60ef4db469e1302cc1b029f7a616d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 4 Feb 2021 17:03:49 +0900 Subject: [PATCH] [vulkan] Rework pipeline parsing for better reuse It's not entirely there yet, but the basics are working. Work is still needed for avoiding duplication of objects (different threads will have different contexts and thus different tables, so necessary per-thread duplication should not become a problem) and general access to arbitrary fields (mostly just parsing the strings) --- include/QF/Vulkan/qf_vid.h | 10 +- include/vid_vulkan.h | 1 + libs/video/renderer/vulkan/qfpipeline.plist | 103 +++--- .../video/renderer/vulkan/vkgen/Makemodule.am | 2 - libs/video/renderer/vulkan/vkgen/vkgen.r | 32 -- libs/video/renderer/vulkan/vkgen/vkhandle.h | 8 - libs/video/renderer/vulkan/vkgen/vkhandle.r | 74 ---- libs/video/renderer/vulkan/vkgen/vkresource.h | 9 - libs/video/renderer/vulkan/vkgen/vkresource.r | 44 --- libs/video/renderer/vulkan/vkparse.c | 323 ++++++++++++------ libs/video/renderer/vulkan/vkparse.h | 13 +- libs/video/renderer/vulkan/vkparse.plist | 69 +--- libs/video/renderer/vulkan/vulkan_alias.c | 9 +- libs/video/renderer/vulkan/vulkan_bsp.c | 13 +- libs/video/renderer/vulkan/vulkan_draw.c | 9 +- .../video/renderer/vulkan/vulkan_vid_common.c | 100 ++++-- 16 files changed, 388 insertions(+), 431 deletions(-) delete mode 100644 libs/video/renderer/vulkan/vkgen/vkhandle.h delete mode 100644 libs/video/renderer/vulkan/vkgen/vkhandle.r delete mode 100644 libs/video/renderer/vulkan/vkgen/vkresource.h delete mode 100644 libs/video/renderer/vulkan/vkgen/vkresource.r diff --git a/include/QF/Vulkan/qf_vid.h b/include/QF/Vulkan/qf_vid.h index 7e30a3a57..1102845b5 100644 --- a/include/QF/Vulkan/qf_vid.h +++ b/include/QF/Vulkan/qf_vid.h @@ -40,7 +40,6 @@ void Vulkan_DestroyFramebuffers (struct vulkan_ctx_s *ctx); void Vulkan_CreateFramebuffers (struct vulkan_ctx_s *ctx); void Vulkan_CreateRenderPass (struct vulkan_ctx_s *ctx); void Vulkan_DestroyRenderPass (struct vulkan_ctx_s *ctx); -VkPipeline Vulkan_CreatePipeline (struct vulkan_ctx_s *ctx, const char *name); void Vulkan_CreateMatrices (struct vulkan_ctx_s *ctx); void Vulkan_DestroyMatrices (struct vulkan_ctx_s *ctx); void Vulkan_CalcProjectionMatrices (struct vulkan_ctx_s *ctx, float aspect); @@ -51,4 +50,13 @@ void Vulkan_Init_Common (struct vulkan_ctx_s *ctx); void Vulkan_Shutdown_Common (struct vulkan_ctx_s *ctx); void Vulkan_CreateStagingBuffers (struct vulkan_ctx_s *ctx); +VkPipeline Vulkan_CreatePipeline (struct vulkan_ctx_s *ctx, const char *name); +VkDescriptorPool Vulkan_CreateDescriptorPool (struct vulkan_ctx_s *ctx, + const char *name); +VkPipelineLayout Vulkan_CreatePipelineLayout (struct vulkan_ctx_s *ctx, + const char *name); +VkSampler Vulkan_CreateSampler (struct vulkan_ctx_s *ctx, const char *name); +VkDescriptorSetLayout Vulkan_CreateDescriptorSetLayout(struct vulkan_ctx_s*ctx, + const char *name); + #endif // __QF_Vulkan_vid_h diff --git a/include/vid_vulkan.h b/include/vid_vulkan.h index a213c7ac5..38aa4b69f 100644 --- a/include/vid_vulkan.h +++ b/include/vid_vulkan.h @@ -58,6 +58,7 @@ typedef struct vulkan_ctx_s { struct hashlink_s *hashlinks; //FIXME want per thread VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain struct plitem_s *pipelineDef; + struct hashtab_s *shaderModules; struct hashtab_s *setLayouts; struct hashtab_s *pipelineLayouts; diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 96de769c9..8ba2937c2 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -1,19 +1,4 @@ { - shaderModules = { - // specify shader modules to load into memory - // 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; - twodv = $builtin/twod.vert; - twodf = $builtin/twod.frag; - quakebspv = $builtin/quakebsp.vert; - quakebspf = $builtin/quakebsp.frag; - aliasv = $builtin/alias.vert; - aliasf = $builtin/alias.frag; - }; samplers = { quakepic = { magFilter = nearest; @@ -32,7 +17,7 @@ borderColor = float_transparent_black; unnormalizedCoordinates = false; }; - quakebsp.sampler = { + quakebsp_sampler = { magFilter = linear; minFilter = linear; mipmapMode = linear; @@ -49,7 +34,7 @@ borderColor = float_transparent_black; unnormalizedCoordinates = false; }; - alias.sampler = { + alias_sampler = { magFilter = linear; minFilter = linear; mipmapMode = linear; @@ -68,7 +53,7 @@ }; }; descriptorPools = { - twod.pool = { + twod_pool = { flags = 0; maxSets = $framebuffers.size; bindings = ( @@ -82,7 +67,7 @@ }, ); }; - alias.pool = { + alias_pool = { flags = 0; maxSets = "2z * $framebuffers.size"; bindings = ( @@ -94,7 +79,7 @@ }; }; setLayouts = { - twod.set = { + twod_set = { bindings = ( { binding = 0; @@ -110,7 +95,7 @@ }, ); }; - quakebsp.set = { + quakebsp_set = { flags = push_descriptor; bindings = ( { @@ -151,7 +136,7 @@ }, ); }; - alias.set = { + alias_set = { flags = push_descriptor; bindings = ( { @@ -174,7 +159,7 @@ }, ); }; - alias.matrices = { + alias_matrices = { bindings = ( { binding = 0; @@ -184,7 +169,7 @@ }, ); }; - alias.textures = { + alias_textures = { flags = push_descriptor; bindings = ( { @@ -213,7 +198,7 @@ }, ); }; - alias.lights = { + alias_lights = { bindings = ( { binding = 0; @@ -242,11 +227,11 @@ }; }; pipelineLayouts = { - twod.layout = { - setLayouts = (twod.set); + twod_layout = { + setLayouts = (twod_set); }; - quakebsp.layout = { - setLayouts = (quakebsp.set); + quakebsp_layout = { + setLayouts = (quakebsp_set); pushConstantRanges = ( { stageFlags = vertex; @@ -260,9 +245,9 @@ }, ); }; - alias.layout = { - //setLayouts = (alias.matrices, alias.lights, alias.textures); - setLayouts = (alias.set); + alias_layout = { + //setLayouts = (alias_matrices, alias_lights, alias_textures); + setLayouts = (alias_set); pushConstantRanges = ( { stageFlags = vertex; @@ -290,11 +275,15 @@ pipelines = { alias = { stages = ( - { stage = vertex; name = main; module = aliasv; }, + { + stage = vertex; + name = main; + module = $builtin/alias.vert; + }, { stage = fragment; name = main; - module = aliasf; + module = $builtin/alias.frag; specializationInfo = { mapEntries = ( { size = 4; offset = 0; constantID = 0; }, @@ -412,13 +401,21 @@ dynamic = { dynamicState = ( viewport, scissor, blend_constants ); }; - layout = alias.layout; + layout = alias_layout; //renderPass = renderpass; }; - quakebsp.main = { + quakebsp_main = { stages = ( - { stage = vertex; name = main; module = quakebspv; }, - { stage = fragment; name = main; module = quakebspf; }, + { + stage = vertex; + name = main; + module = $builtin/quakebsp.vert; + }, + { + stage = fragment; + name = main; + module = $builtin/quakebsp.frag; + }, ); vertexInput = { bindings = ( @@ -501,16 +498,20 @@ dynamic = { dynamicState = ( viewport, scissor, blend_constants ); }; - layout = quakebsp.layout; + layout = quakebsp_layout; //renderPass = renderpass; }; - quakebsp.skysheet = { + quakebsp_skysheet = { stages = ( - { stage = vertex; name = main; module = quakebspv; }, + { + stage = vertex; + name = main; + module = $builtin/quakebsp.vert; + }, { stage = fragment; name = main; - module = quakebspf; + module = $builtin/quakebsp.frag; specializationInfo = { mapEntries = ( { size = 4; offset = 0; constantID = 0; }, @@ -603,13 +604,21 @@ dynamic = { dynamicState = ( viewport, scissor, blend_constants ); }; - layout = quakebsp.layout; + layout = quakebsp_layout; //renderPass = renderpass; }; twod = { stages = ( - { stage = vertex; name = main; module = twodv; }, - { stage = fragment; name = main; module = twodf; }, + { + stage = vertex; + name = main; + module = $builtin/twod.vert; + }, + { + stage = fragment; + name = main; + module = $builtin/twod.frag; + }, ); vertexInput = { bindings = ( @@ -698,7 +707,7 @@ dynamic = { dynamicState = ( viewport, scissor ); }; - layout = twod.layout; + layout = twod_layout; //renderPass = renderpass; }; }; @@ -764,7 +773,7 @@ }, ); }; - renderpass.msaa = { + renderpass_msaa = { attachments = ( { flags = 0; diff --git a/libs/video/renderer/vulkan/vkgen/Makemodule.am b/libs/video/renderer/vulkan/vkgen/Makemodule.am index 2fba61b0b..b60e97f1d 100644 --- a/libs/video/renderer/vulkan/vkgen/Makemodule.am +++ b/libs/video/renderer/vulkan/vkgen/Makemodule.am @@ -13,8 +13,6 @@ vkgen_dat_src= \ libs/video/renderer/vulkan/vkgen/vkfieldstring.r \ 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 a336a861c..25bcbaf69 100644 --- a/libs/video/renderer/vulkan/vkgen/vkgen.r +++ b/libs/video/renderer/vulkan/vkgen/vkgen.r @@ -10,8 +10,6 @@ #include "vkgen.h" #include "vkstruct.h" #include "vkenum.h" -#include "vkhandle.h" -#include "vkresource.h" static AutoreleasePool *autorelease_pool; static void @@ -154,7 +152,6 @@ main(int argc, string *argv) PLItem *plist; PLItem *search; PLItem *handles; - PLItem *resources; arp_start (); @@ -179,7 +176,6 @@ 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"); @@ -204,17 +200,6 @@ main(int argc, string *argv) } } - PLItem *handle_keys = [[handles allKeys] retain]; - for (int i = [handle_keys count]; i-- > 0; ) { - string search_name = [[handle_keys getObjectAtIndex:i] string]; - id obj = (id) Hash_Find (available_types, search_name); - obj = [obj resolveType]; - printf("handle: %d %s\n", obj, class_get_class_name([obj class])); - if (obj && [obj class] == [Struct class]) { - [obj addToQueue]; - } - } - while ([queue count]) { id obj = [queue objectAtIndex:0]; [queue removeObjectAtIndex:0]; @@ -261,23 +246,6 @@ main(int argc, string *argv) [obj writeTable]; arp_end (); } - for (int i = [handle_keys count]; i-- > 0; ) { - 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.h b/libs/video/renderer/vulkan/vkgen/vkhandle.h deleted file mode 100644 index 47a68798b..000000000 --- a/libs/video/renderer/vulkan/vkgen/vkhandle.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __renderer_vulkan_vkgen_vkhandle_h -#define __renderer_vulkan_vkgen_vkhandle_h - -@class PLItem; - -void output_handle (string name, PLItem *handle); - -#endif//__renderer_vulkan_vkgen_vkhandle_h diff --git a/libs/video/renderer/vulkan/vkgen/vkhandle.r b/libs/video/renderer/vulkan/vkgen/vkhandle.r deleted file mode 100644 index ec78c22ba..000000000 --- a/libs/video/renderer/vulkan/vkgen/vkhandle.r +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include - -#include "vkgen.h" -#include "vkhandle.h" - -void -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]); - string custom = str_hold ([[handle getObjectForKey:"custom"] string]); - if (!custom) { - fprintf (output_file, "static int parse_%s (const plitem_t *item, void **data, plitem_t *messages, parsectx_t *context)\n", name); - fprintf (output_file, "{\n"); - fprintf (output_file, "\t__auto_type handle = (%s *) data[0];\n", name); - fprintf (output_file, "\tvulkan_ctx_t *ctx = 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, "\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, "\tvoid *hrdata[] = { &handleref->handle };\n"); - fprintf (output_file, "\thandleref->name = strdup (field->name);\n"); - if (custom) { - fprintf (output_file, "\treturn %s (item, hrdata, messages, context);\n", custom); - } else { - fprintf (output_file, "\treturn parse_%s (item, hrdata, messages, context);\n", name); - } - fprintf (output_file, "}\n"); - - fprintf (output_file, "%s QFV_Get%s (vulkan_ctx_t *ctx, const char *name)\n", name, str_mid (name, 2)); - fprintf (output_file, "{\n"); - fprintf (output_file, "\thandleref_t *handleref = Hash_Find (ctx->%s, name);\n", symtab); - fprintf (output_file, "\treturn handleref ? (%s) handleref->handle : 0;\n", name); - fprintf (output_file, "}\n"); - - if (!custom) { - fprintf (header_file, "static int parse_%s (const plitem_t *item, void **data, plitem_t *messages, parsectx_t *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); - fprintf (output_file, "%s QFV_Get%s (vulkan_ctx_t *ctx, const char *name);\n", name, str_mid (name, 2)); - 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 deleted file mode 100644 index e72042c3e..000000000 --- a/libs/video/renderer/vulkan/vkgen/vkresource.h +++ /dev/null @@ -1,9 +0,0 @@ -#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 deleted file mode 100644 index 47478d9f8..000000000 --- a/libs/video/renderer/vulkan/vkgen/vkresource.r +++ /dev/null @@ -1,44 +0,0 @@ -#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 4108a75f5..88c580506 100644 --- a/libs/video/renderer/vulkan/vkparse.c +++ b/libs/video/renderer/vulkan/vkparse.c @@ -362,48 +362,103 @@ parse_RGBA (const plitem_t *item, void **data, return ret; } +static void +add_handle (hashtab_t *tab, const char *name, uint64_t handle) +{ + handleref_t *hr = malloc (sizeof (handleref_t)); + hr->name = strdup (name); + hr->handle = handle; + Hash_Add (tab, hr); +} + static int parse_VkShaderModule (const plitem_t *item, void **data, plitem_t *messages, parsectx_t *context) { __auto_type handle = (VkShaderModule *) data[0]; vulkan_ctx_t *ctx = context->vctx; + qfv_device_t *device = ctx->device; const char *name = PL_String (item); handleref_t *hr = Hash_Find (ctx->shaderModules, name); - if (!hr) { - PL_Message (messages, item, "undefined shader module %s", name); + if (hr) { + *handle = (VkShaderModule) hr->handle; + return 1; + } + if (!(*handle = QFV_CreateShaderModule (device, name))) { + PL_Message (messages, item, "could not find shader %s", name); return 0; } - *handle = (VkShaderModule) hr->handle; + add_handle (ctx->shaderModules, name, (uint64_t) *handle); return 1; } static int -parse_VkShaderModule_resource (const plitem_t *item, void **data, - plitem_t *messages, parsectx_t *context) +parse_VkDescriptorSetLayout (const plfield_t *field, const plitem_t *item, + void *data, plitem_t *messages, void *context) { - __auto_type handle = (VkShaderModule *) data[0]; + __auto_type handle = (VkDescriptorSetLayout *) data; + int ret = 1; + exprctx_t ectx = *((parsectx_t *) context)->ectx; 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; + const char *name = PL_String (item); + Sys_Printf ("parse_VkDescriptorSetLayout: %s\n", name); + name = va (ctx->va_ctx, "$properties.setLayouts.%s", name); + + handleref_t *hr = Hash_Find (ctx->setLayouts, name); + if (hr) { + *handle = (VkDescriptorSetLayout) hr->handle; + return 1; } - QFV_duSetObjectName (device, VK_OBJECT_TYPE_SHADER_MODULE, *handle, - va (ctx->va_ctx, "shader:%s", shader_path)); - return 1; + + plitem_t *setItem = 0; + exprval_t result = { &cexpr_plitem, &setItem }; + ectx.symtab = 0; + ectx.result = &result; + ret = !cexpr_eval_string (name, &ectx); + if (ret) { + VkDescriptorSetLayout setLayout; + setLayout = QFV_ParseDescriptorSetLayout (ctx, setItem); + *handle = (VkDescriptorSetLayout) setLayout; + + add_handle (ctx->setLayouts, name, (uint64_t) setLayout); + } + return ret; } static int -parse_VkDescriptorSetLayout_array (const plfield_t *field, - const plitem_t *item, void *data, - plitem_t *messages, void *context) +parse_VkPipelineLayout (const plitem_t *item, void **data, + plitem_t *messages, parsectx_t *context) { - void *layout[] = { data }; - return parse_VkDescriptorSetLayout (item, layout, messages, context); + __auto_type handle = (VkPipelineLayout *) data[0]; + int ret = 1; + exprctx_t ectx = *((parsectx_t *) context)->ectx; + vulkan_ctx_t *ctx = ((parsectx_t *) context)->vctx; + + const char *name = PL_String (item); + Sys_Printf ("parse_VkPipelineLayout: %s\n", name); + name = va (ctx->va_ctx, "$properties.pipelineLayouts.%s", name); + + handleref_t *hr = Hash_Find (ctx->pipelineLayouts, name); + if (hr) { + *handle = (VkPipelineLayout) hr->handle; + return 1; + } + + plitem_t *setItem = 0; + exprval_t result = { &cexpr_plitem, &setItem }; + ectx.symtab = 0; + ectx.result = &result; + ret = !cexpr_eval_string (name, &ectx); + if (ret) { + VkPipelineLayout layout; + layout = QFV_ParsePipelineLayout (ctx, setItem); + *handle = (VkPipelineLayout) layout; + + add_handle (ctx->pipelineLayouts, name, (uint64_t) layout); + } + return ret; } static const char * @@ -600,54 +655,6 @@ handlref_symtab (void (*free_func)(void*,void*), vulkan_ctx_t *ctx) ctx, &ctx->hashlinks); } -void -QFV_ParseResources (vulkan_ctx_t *ctx, plitem_t *pipelinedef) -{ - plitem_t *messages = PL_NewArray (); - exprsym_t var_syms[] = { - {"swapchain", &qfv_swapchain_t_type, ctx->swapchain}, - {"framebuffers", &vulkan_framebufferset_t_type, &ctx->framebuffers}, - {"msaaSamples", &VkSampleCountFlagBits_type, &ctx->msaaSamples}, - {} - }; - exprtab_t vars_tab = { var_syms, 0 }; - exprctx_t exprctx = {}; - parsectx_t parsectx = { &exprctx, ctx }; - int ret = 1; - - exprctx.memsuper = new_memsuper (); - exprctx.messages = messages; - exprctx.hashlinks = &ctx->hashlinks; - exprctx.external_variables = &vars_tab; - cexpr_init_symtab (&vars_tab, &exprctx); - - if (!ctx->setLayouts) { - ctx->shaderModules = handlref_symtab (shaderModule_free, ctx); - ctx->setLayouts = handlref_symtab (setLayout_free, ctx); - ctx->pipelineLayouts = handlref_symtab (pipelineLayout_free, ctx); - ctx->descriptorPools = handlref_symtab (descriptorPool_free, ctx); - ctx->samplers = handlref_symtab (sampler_free, ctx); - } - - 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); -} - static const char * enum_symtab_getkey (const void *e, void *unused) { @@ -666,6 +673,14 @@ QFV_InitParse (vulkan_ctx_t *ctx) cexpr_init_symtab (&qfv_swapchain_t_symtab, &context); cexpr_init_symtab (&vulkan_framebufferset_t_symtab, &context); cexpr_init_symtab (&imageset_symtab, &context); + + if (!ctx->setLayouts) { + ctx->shaderModules = handlref_symtab (shaderModule_free, ctx); + ctx->setLayouts = handlref_symtab (setLayout_free, ctx); + ctx->pipelineLayouts = handlref_symtab (pipelineLayout_free, ctx); + ctx->descriptorPools = handlref_symtab (descriptorPool_free, ctx); + ctx->samplers = handlref_symtab (sampler_free, ctx); + } } exprenum_t * @@ -674,13 +689,79 @@ QFV_GetEnum (const char *name) return Hash_Find (enum_symtab, name); } +static int +parse_object (vulkan_ctx_t *ctx, plitem_t *plist, + plparser_t parser, void *object) +{ + plitem_t *messages = PL_NewArray (); + exprctx_t exprctx = {}; + parsectx_t parsectx = { &exprctx, ctx }; + exprsym_t var_syms[] = { + {"swapchain", &qfv_swapchain_t_type, ctx->swapchain}, + {"framebuffers", &vulkan_framebufferset_t_type, &ctx->framebuffers}, + {"msaaSamples", &VkSampleCountFlagBits_type, &ctx->msaaSamples}, + {"properties", &cexpr_plitem, &ctx->pipelineDef}, + {} + }; + exprtab_t vars_tab = { var_syms, 0 }; + + exprctx.external_variables = &vars_tab; + exprctx.memsuper = new_memsuper (); + exprctx.messages = messages; + exprctx.hashlinks = &ctx->hashlinks; + + cexpr_init_symtab (&vars_tab, &exprctx); + + + if (!parser (0, plist, object, messages, &parsectx)) { + for (int i = 0; i < PL_A_NumObjects (messages); i++) { + Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i))); + } + return 0; + } + PL_Free (messages); + delete_memsuper (exprctx.memsuper); + + return 1; +} + +static int +parse_qfv_renderpass (const plfield_t *field, const plitem_t *item, void *data, + plitem_t *messages, void *context) +{ + return PL_ParseStruct (renderpass_fields, item, data, messages, context); +} + VkRenderPass QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist) { qfv_device_t *device = ctx->device; + qfv_renderpass_t renderpass_data = {}; - plitem_t *messages = PL_NewArray (); + + if (!parse_object (ctx, plist, parse_qfv_renderpass, &renderpass_data)) { + return 0; + } + VkRenderPass renderpass; + renderpass = QFV_CreateRenderPass (device, + renderpass_data.attachments, + renderpass_data.subpasses, + renderpass_data.dependencies); + + free (renderpass_data.attachments); + for (size_t i = 0; i < renderpass_data.subpasses->size; i++) { + free ((void *) renderpass_data.subpasses->a[i].pInputAttachments); + free ((void *) renderpass_data.subpasses->a[i].pColorAttachments); + free ((void *) renderpass_data.subpasses->a[i].pResolveAttachments); + free ((void *) renderpass_data.subpasses->a[i].pDepthStencilAttachment); + free ((void *) renderpass_data.subpasses->a[i].pPreserveAttachments); + } + free (renderpass_data.subpasses); + free (renderpass_data.dependencies); + return renderpass; + +/* plitem_t *messages = PL_NewArray (); exprsym_t var_syms[] = { {"swapchain", &qfv_swapchain_t_type, ctx->swapchain}, {"framebuffers", &vulkan_framebufferset_t_type, &ctx->framebuffers}, @@ -707,11 +788,6 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist) PL_Free (messages); delete_memsuper (exprctx.memsuper); - renderpass = QFV_CreateRenderPass (device, - renderpass_data.attachments, - renderpass_data.subpasses, - renderpass_data.dependencies); - free (renderpass_data.attachments); for (size_t i = 0; i < renderpass_data.subpasses->size; i++) { free ((void *) renderpass_data.subpasses->a[i].pInputAttachments); @@ -722,7 +798,7 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist) } free (renderpass_data.subpasses); free (renderpass_data.dependencies); - return renderpass; + return renderpass;*/ } VkPipeline @@ -730,34 +806,13 @@ QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist) { qfv_device_t *device = ctx->device; - plitem_t *messages = PL_NewArray (); - exprctx_t exprctx = {}; - parsectx_t parsectx = { &exprctx, ctx }; - exprsym_t var_syms[] = { - {"msaaSamples", &VkSampleCountFlagBits_type, &ctx->msaaSamples}, - {} - }; - exprtab_t vars_tab = { var_syms, 0 }; - - exprctx.external_variables = &vars_tab; - exprctx.memsuper = new_memsuper (); - exprctx.messages = messages; - exprctx.hashlinks = &ctx->hashlinks; - - cexpr_init_symtab (&vars_tab, &exprctx); - __auto_type cInfo = QFV_AllocGraphicsPipelineCreateInfoSet (1, alloca); memset (&cInfo->a[0], 0, sizeof (cInfo->a[0])); - if (!parse_VkGraphicsPipelineCreateInfo (0, plist, &cInfo->a[0], - messages, &parsectx)) { - for (int i = 0; i < PL_A_NumObjects (messages); i++) { - Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i))); - } + if (!parse_object (ctx, plist, parse_VkGraphicsPipelineCreateInfo, + &cInfo->a[0])) { return 0; } - PL_Free (messages); - delete_memsuper (exprctx.memsuper); cInfo->a[0].renderPass = ctx->renderpass.renderpass; __auto_type plSet = QFV_CreateGraphicsPipelines (device, 0, cInfo); @@ -765,3 +820,77 @@ QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist) free (plSet); return pipeline; } + +VkDescriptorPool +QFV_ParseDescriptorPool (vulkan_ctx_t *ctx, plitem_t *plist) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + VkDescriptorPoolCreateInfo cInfo = {}; + + if (!parse_object (ctx, plist, parse_VkDescriptorPoolCreateInfo, &cInfo)) { + return 0; + } + + VkDescriptorPool pool; + dfunc->vkCreateDescriptorPool (device->dev, &cInfo, 0, &pool); + + return pool; +} + +VkDescriptorSetLayout +QFV_ParseDescriptorSetLayout (vulkan_ctx_t *ctx, plitem_t *plist) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + VkDescriptorSetLayoutCreateInfo cInfo = {}; + + if (!parse_object (ctx, plist, parse_VkDescriptorSetLayoutCreateInfo, + &cInfo)) { + return 0; + } + + VkDescriptorSetLayout setLayout; + dfunc->vkCreateDescriptorSetLayout (device->dev, &cInfo, 0, &setLayout); + + return setLayout; +} + +VkPipelineLayout +QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + VkPipelineLayoutCreateInfo cInfo = {}; + + if (!parse_object (ctx, plist, parse_VkPipelineLayoutCreateInfo, + &cInfo)) { + return 0; + } + + VkPipelineLayout layout; + dfunc->vkCreatePipelineLayout (device->dev, &cInfo, 0, &layout); + + return layout; +} + +VkSampler +QFV_ParseSampler (vulkan_ctx_t *ctx, plitem_t *plist) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + VkSamplerCreateInfo cInfo = {}; + + if (!parse_object (ctx, plist, parse_VkSamplerCreateInfo, &cInfo)) { + return 0; + } + + VkSampler sampler; + dfunc->vkCreateSampler (device->dev, &cInfo, 0, &sampler); + + return sampler; +} diff --git a/libs/video/renderer/vulkan/vkparse.h b/libs/video/renderer/vulkan/vkparse.h index 459c0f6a2..480c8bc99 100644 --- a/libs/video/renderer/vulkan/vkparse.h +++ b/libs/video/renderer/vulkan/vkparse.h @@ -24,18 +24,15 @@ typedef struct handleref_s { uint64_t handle; } handleref_t; -VkShaderModule QFV_GetShaderModule (vulkan_ctx_t *ctx, const char *name); -VkDescriptorPool QFV_GetDescriptorPool (vulkan_ctx_t *ctx, const char *name); -VkDescriptorSetLayout QFV_GetDescriptorSetLayout (vulkan_ctx_t *ctx, - const char *name); -VkPipelineLayout QFV_GetPipelineLayout (vulkan_ctx_t *ctx, const char *name); -VkSampler QFV_GetSampler (vulkan_ctx_t *ctx, const char *name); - -void QFV_ParseResources (vulkan_ctx_t *ctx, plitem_t *plist); void QFV_InitParse (vulkan_ctx_t *ctx); exprenum_t *QFV_GetEnum (const char *name); VkRenderPass QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist); VkPipeline QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist); +VkDescriptorPool QFV_ParseDescriptorPool (vulkan_ctx_t *ctx, plitem_t *plist); +VkDescriptorSetLayout QFV_ParseDescriptorSetLayout (vulkan_ctx_t *ctx, + plitem_t *plist); +VkPipelineLayout QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist); +VkSampler QFV_ParseSampler (vulkan_ctx_t *ctx, plitem_t *plist); #endif//__vkparse_h diff --git a/libs/video/renderer/vulkan/vkparse.plist b/libs/video/renderer/vulkan/vkparse.plist index edf68541e..c3a0bfdd9 100644 --- a/libs/video/renderer/vulkan/vkparse.plist +++ b/libs/video/renderer/vulkan/vkparse.plist @@ -21,70 +21,6 @@ VkDescriptorPoolCreateInfo, VkSamplerCreateInfo, ); - handles = { - VkShaderModule = { - symtab = shaderModules; - class = "shader module"; - custom = parse_VkShaderModule_resource; - }; - VkDescriptorPool = { - symtab = descriptorPools; - class = "descriptor pool"; - create = vkCreateDescriptorPool; - }; - VkDescriptorSetLayout = { - symtab = setLayouts; - class = "set layout"; - create = vkCreateDescriptorSetLayout; - }; - VkPipelineLayout = { - symtab = pipelineLayouts; - class = "pipeline layout"; - create = vkCreatePipelineLayout; - }; - VkSampler = { - symtab = samplers; - class = "sampler"; - create = vkCreateSampler; - }; - }; - 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; - }, - { - name = descriptorPools; - parse_type = QFDictionary; - parser = parse_VkDescriptorPool_handleref; - type = handleref_t; - table = descriptorPools; - }, - { - name = samplers; - parse_type = QFDictionary; - parser = parse_VkSampler_handleref; - type = handleref_t; - table = samplers; - }, - ); parse = { VkSubpassDescription = { flags = auto; @@ -279,7 +215,7 @@ type = (array, { parse_type = (QFDictionary, QFString); type = VkDescriptorSetLayout; - parser = parse_VkDescriptorSetLayout_array; + parser = parse_VkDescriptorSetLayout; }); size = setLayoutCount; values = pSetLayouts; @@ -338,8 +274,7 @@ value = pDynamicState; }; layout = { - type = (custom, (QFDictionary, QFString), - parse_VkPipelineLayout); + type = (custom, QFString, parse_VkPipelineLayout); fields = (layout); }; basePipelineHandle = { diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index 76f4ac7b5..ad42daed4 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -63,7 +63,6 @@ #include "r_internal.h" #include "vid_vulkan.h" -#include "vkparse.h" void Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx) @@ -259,12 +258,8 @@ Vulkan_Alias_Init (vulkan_ctx_t *ctx) actx->frames.grow = 0; actx->pipeline = Vulkan_CreatePipeline (ctx, "alias"); - actx->layout = QFV_GetPipelineLayout (ctx, "alias.layout"); - QFV_duSetObjectName (device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, actx->layout, - va (ctx->va_ctx, "layout:%s", "alias.layout")); - actx->sampler = QFV_GetSampler (ctx, "alias.sampler"); - QFV_duSetObjectName (device, VK_OBJECT_TYPE_SAMPLER, actx->sampler, - va (ctx->va_ctx, "sampler:%s", "alias.sampler")); + actx->layout = Vulkan_CreatePipelineLayout (ctx, "alias_layout"); + actx->sampler = Vulkan_CreateSampler (ctx, "alias_sampler"); /*__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (2 * frames, alloca); for (size_t i = 0; i < layouts->size / 2; i++) { diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index a0dcd9134..5ae835897 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -68,7 +68,6 @@ #include "r_internal.h" #include "vid_vulkan.h" -#include "vkparse.h" static float identity[] = { 1, 0, 0, 0, @@ -1449,14 +1448,10 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx) DARRAY_RESIZE (&bctx->frames, frames); bctx->frames.grow = 0; - bctx->main = Vulkan_CreatePipeline (ctx, "quakebsp.main"); - bctx->sky = Vulkan_CreatePipeline (ctx, "quakebsp.skysheet"); - bctx->layout = QFV_GetPipelineLayout (ctx, "quakebsp.layout"); - QFV_duSetObjectName (device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, bctx->layout, - va (ctx->va_ctx, "layout:%s", "quakebsp.layout")); - bctx->sampler = QFV_GetSampler (ctx, "quakebsp.sampler"); - QFV_duSetObjectName (device, VK_OBJECT_TYPE_SAMPLER, bctx->sampler, - va (ctx->va_ctx, "sampler:%s", "quakebsp.sampler")); + bctx->main = Vulkan_CreatePipeline (ctx, "quakebsp_main"); + bctx->sky = Vulkan_CreatePipeline (ctx, "quakebsp_skysheet"); + bctx->layout = Vulkan_CreatePipelineLayout (ctx, "quakebsp_layout"); + bctx->sampler = Vulkan_CreateSampler (ctx, "quakebsp_sampler"); __auto_type cmdBuffers = QFV_AllocCommandBufferSet (3 * frames, alloca); QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, cmdBuffers); diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index 16b563600..ff7e6ed15 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -64,7 +64,6 @@ #include "r_internal.h" #include "vid_vulkan.h" -#include "vkparse.h" typedef struct { float xy[2]; @@ -371,7 +370,7 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx) ctx->cmdpool); dctx->scrap = QFV_CreateScrap (device, "draw_atlas", 2048, tex_rgba, dctx->stage); - dctx->sampler = QFV_GetSampler (ctx, "quakepic"); + dctx->sampler = Vulkan_CreateSampler (ctx, "quakepic"); qpic_t *charspic = Draw_Font8x8Pic (); @@ -384,13 +383,13 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx) dctx->pipeline = Vulkan_CreatePipeline (ctx, "twod"); - dctx->layout = QFV_GetPipelineLayout (ctx, "twod.layout"); + dctx->layout = Vulkan_CreatePipelineLayout (ctx, "twod_layout"); __auto_type layouts = QFV_AllocDescriptorSetLayoutSet (frames, alloca); for (size_t i = 0; i < layouts->size; i++) { - layouts->a[i] = QFV_GetDescriptorSetLayout (ctx, "twod.set"); + layouts->a[i] = Vulkan_CreateDescriptorSetLayout (ctx, "twod_set"); } - __auto_type pool = QFV_GetDescriptorPool (ctx, "twod.pool"); + __auto_type pool = Vulkan_CreateDescriptorPool (ctx, "twod_pool"); VkDescriptorBufferInfo bufferInfo = { ctx->matrices.buffer_2d, 0, VK_WHOLE_SIZE diff --git a/libs/video/renderer/vulkan/vulkan_vid_common.c b/libs/video/renderer/vulkan/vulkan_vid_common.c index ff026331a..979d30a7c 100644 --- a/libs/video/renderer/vulkan/vulkan_vid_common.c +++ b/libs/video/renderer/vulkan/vulkan_vid_common.c @@ -224,21 +224,25 @@ Vulkan_CreateSwapchain (vulkan_ctx_t *ctx) } } -static void -qfv_load_pipeline (vulkan_ctx_t *ctx) +static plitem_t * +qfv_load_pipeline (vulkan_ctx_t *ctx, const char *name) { if (!ctx->pipelineDef) { ctx->pipelineDef = PL_GetPropertyList (quakeforge_pipeline); - if (ctx->pipelineDef) { - QFV_ParseResources (ctx, ctx->pipelineDef); - } } + + plitem_t *item = ctx->pipelineDef; + if (!item || !(item = PL_ObjectForKey (item, name))) { + Sys_Printf ("error loading %s\n", name); + } else { + Sys_Printf ("Found %s def\n", name); + } + return item; } void Vulkan_CreateRenderPass (vulkan_ctx_t *ctx) { - qfv_load_pipeline (ctx); const char *name = "renderpass";//FIXME qfv_device_t *device = ctx->device; VkDevice dev = device->dev; @@ -249,15 +253,13 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx) ctx->msaaSamples = min ((VkSampleCountFlagBits) msaaSamples->int_val, QFV_GetMaxSampleCount (device->physDev)); if (ctx->msaaSamples > 1) { - name = "renderpass.msaa"; + name = "renderpass_msaa"; } - plitem_t *item = ctx->pipelineDef; - if (!item || !(item = PL_ObjectForKey (item, name))) { - Sys_Printf ("error loading renderpass: %s\n", name); + //FIXME a tad inconsistent + plitem_t *item = qfv_load_pipeline (ctx, name); + if (!item) { return; - } else { - Sys_Printf ("Found renderpass def: %s\n", name); } qfv_imageresource_t *colorImage = malloc (sizeof (*colorImage)); @@ -375,15 +377,7 @@ Vulkan_DestroyRenderPass (vulkan_ctx_t *ctx) VkPipeline Vulkan_CreatePipeline (vulkan_ctx_t *ctx, const char *name) { - qfv_load_pipeline (ctx); - - plitem_t *item = ctx->pipelineDef; - if (!item || !(item = PL_ObjectForKey (item, "pipelines"))) { - Sys_Printf ("error loading pipelines\n"); - return 0; - } else { - Sys_Printf ("Found pipelines def\n"); - } + plitem_t *item = qfv_load_pipeline (ctx, "pipelines"); if (!(item = PL_ObjectForKey (item, name))) { Sys_Printf ("error loading pipeline %s\n", name); return 0; @@ -396,6 +390,70 @@ Vulkan_CreatePipeline (vulkan_ctx_t *ctx, const char *name) return pipeline; } +VkDescriptorPool +Vulkan_CreateDescriptorPool (vulkan_ctx_t *ctx, const char *name) +{ + plitem_t *item = qfv_load_pipeline (ctx, "descriptorPools"); + if (!(item = PL_ObjectForKey (item, name))) { + Sys_Printf ("error loading descriptor pool %s\n", name); + return 0; + } else { + Sys_Printf ("Found descriptor pool def %s\n", name); + } + VkDescriptorPool pool = QFV_ParseDescriptorPool (ctx, item); + QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_DESCRIPTOR_POOL, pool, + va (ctx->va_ctx, "descriptor_pool:%s", name)); + return pool; +} + +VkPipelineLayout +Vulkan_CreatePipelineLayout (vulkan_ctx_t *ctx, const char *name) +{ + plitem_t *item = qfv_load_pipeline (ctx, "pipelineLayouts"); + if (!(item = PL_ObjectForKey (item, name))) { + Sys_Printf ("error loading pipeline layout %s\n", name); + return 0; + } else { + Sys_Printf ("Found pipeline layout def %s\n", name); + } + VkPipelineLayout layout = QFV_ParsePipelineLayout (ctx, item); + QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, layout, + va (ctx->va_ctx, "pipeline_layout:%s", name)); + return layout; +} + +VkSampler +Vulkan_CreateSampler (vulkan_ctx_t *ctx, const char *name) +{ + plitem_t *item = qfv_load_pipeline (ctx, "samplers"); + if (!(item = PL_ObjectForKey (item, name))) { + Sys_Printf ("error loading sampler %s\n", name); + return 0; + } else { + Sys_Printf ("Found sampler def %s\n", name); + } + VkSampler sampler = QFV_ParseSampler (ctx, item); + QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_SAMPLER, sampler, + va (ctx->va_ctx, "sampler:%s", name)); + return sampler; +} + +VkDescriptorSetLayout +Vulkan_CreateDescriptorSetLayout(vulkan_ctx_t *ctx, const char *name) +{ + plitem_t *item = qfv_load_pipeline (ctx, "setLayouts"); + if (!(item = PL_ObjectForKey (item, name))) { + Sys_Printf ("error loading descriptor set %s\n", name); + return 0; + } else { + Sys_Printf ("Found descriptor set def %s\n", name); + } + VkDescriptorSetLayout set = QFV_ParseDescriptorSetLayout (ctx, item); + QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, + set, va (ctx->va_ctx, "descriptor_set:%s", name)); + return set; +} + void Vulkan_CreateFramebuffers (vulkan_ctx_t *ctx) {