[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.
This commit is contained in:
Bill Currie 2021-01-05 14:15:35 +09:00
parent d8261ade9e
commit e5708100bb
13 changed files with 257 additions and 186 deletions

View file

@ -10,10 +10,5 @@ VkShaderModule QFV_CreateShaderModule (struct qfv_device_s *device,
const char *path); const char *path);
void QFV_DestroyShaderModule (struct qfv_device_s *device, void QFV_DestroyShaderModule (struct qfv_device_s *device,
VkShaderModule module); 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 #endif//__QF_Vulkan_shader_h

View file

@ -44,11 +44,10 @@ typedef struct vulkan_ctx_s {
VkSampleCountFlagBits msaaSamples; // FIXME not here? VkSampleCountFlagBits msaaSamples; // FIXME not here?
struct hashlink_s *hashlinks; //FIXME want per thread struct hashlink_s *hashlinks; //FIXME want per thread
VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain
struct hashtab_s *shadermodules; struct hashtab_s *shaderModules;
struct hashtab_s *setLayouts; struct hashtab_s *setLayouts;
struct hashtab_s *pipelineLayouts; struct hashtab_s *pipelineLayouts;
struct hashtab_s *renderPasses; struct hashtab_s *renderPasses;
struct shadermodule_s *shadermodule_freelist;
VkCommandPool cmdpool; VkCommandPool cmdpool;
VkCommandBuffer cmdbuffer; VkCommandBuffer cmdbuffer;

View file

@ -1,19 +1,13 @@
{ {
modules = ( shaderModules = {
// specify shader modules to load into memory // specify shader modules to load into memory
{ // key is the name of the module for referecy by the pipeline
// the name of the module for referecy by the pipeline // value the path to the spv file to load
name = passthrough;
// the path to the spv file to load
// $shader refers to the shader install path // $shader refers to the shader install path
// $builtin refers to compiled-in shaders // $builtin refers to compiled-in shaders
file = $builtin/passthrough.vert; passthrough = $builtin/passthrough.vert;
}, pushcolor = $builtin/pushcolor.frag;
{ };
name = pushcolor;
file = $builtin/pushcolor.frag;
},
);
setLayouts = { setLayouts = {
something = { something = {
flags = 0; flags = 0;

View file

@ -65,14 +65,6 @@ typedef struct shaderdata_s {
size_t size; size_t size;
} shaderdata_t; } shaderdata_t;
typedef struct shadermodule_s {
char *name;
union {
VkShaderModule module;
struct shadermodule_s *next;
};
} shadermodule_t;
static shaderdata_t builtin_shaders[] = { static shaderdata_t builtin_shaders[] = {
{ "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) }, { "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) },
{ "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) }, { "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) },
@ -122,6 +114,9 @@ QFV_CreateShaderModule (qfv_device_t *device, const char *shader_path)
} }
if (data) { if (data) {
Sys_MaskPrintf (SYS_VULKAN,
"QFV_CreateShaderModule: creating shader module %s\n",
shader_path);
VkShaderModuleCreateInfo createInfo = { VkShaderModuleCreateInfo createInfo = {
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, 0, VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, 0,
0, data->size, data->data 0, data->size, data->data
@ -151,63 +146,3 @@ QFV_DestroyShaderModule (qfv_device_t *device, VkShaderModule module)
dfunc->vkDestroyShaderModule (dev, module, 0); 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));
}

View file

@ -14,6 +14,7 @@ vkgen_dat_src= \
libs/video/renderer/vulkan/vkgen/vkfieldtype.r \ libs/video/renderer/vulkan/vkgen/vkfieldtype.r \
libs/video/renderer/vulkan/vkgen/vkgen.r \ libs/video/renderer/vulkan/vkgen/vkgen.r \
libs/video/renderer/vulkan/vkgen/vkhandle.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/vkstruct.r \
libs/video/renderer/vulkan/vkgen/vktype.r \ libs/video/renderer/vulkan/vkgen/vktype.r \
libs/video/renderer/vulkan/vkgen/vulkan.r libs/video/renderer/vulkan/vkgen/vulkan.r

View file

@ -11,6 +11,7 @@
#include "vkstruct.h" #include "vkstruct.h"
#include "vkenum.h" #include "vkenum.h"
#include "vkhandle.h" #include "vkhandle.h"
#include "vkresource.h"
static AutoreleasePool *autorelease_pool; static AutoreleasePool *autorelease_pool;
static void static void
@ -150,6 +151,7 @@ main(int argc, string *argv)
PLItem *plist; PLItem *plist;
PLItem *search; PLItem *search;
PLItem *handles; PLItem *handles;
PLItem *resources;
arp_start (); arp_start ();
@ -174,6 +176,7 @@ main(int argc, string *argv)
} }
search = [[plist getObjectForKey: "search"] retain]; search = [[plist getObjectForKey: "search"] retain];
handles = [[plist getObjectForKey: "handles"] retain]; handles = [[plist getObjectForKey: "handles"] retain];
resources = [[plist getObjectForKey: "resources"] retain];
parse = [[plist getObjectForKey: "parse"] retain]; parse = [[plist getObjectForKey: "parse"] retain];
encodings = PR_FindGlobal (".type_encodings"); encodings = PR_FindGlobal (".type_encodings");
@ -259,6 +262,19 @@ main(int argc, string *argv)
string key = [[handle_keys getObjectAtIndex:i] string]; string key = [[handle_keys getObjectAtIndex:i] string];
output_handle (key, [handles getObjectForKey: key]); 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, "static void\n");
fprintf (output_file, "vkgen_init_symtabs (exprctx_t *context)\n"); fprintf (output_file, "vkgen_init_symtabs (exprctx_t *context)\n");
fprintf (output_file, "{\n"); fprintf (output_file, "{\n");

View file

@ -10,6 +10,8 @@ output_handle (string name, PLItem *handle)
string symtab = str_hold ([[handle getObjectForKey:"symtab"] string]); string symtab = str_hold ([[handle getObjectForKey:"symtab"] string]);
string class = str_hold ([[handle getObjectForKey:"class"] string]); string class = str_hold ([[handle getObjectForKey:"class"] string]);
string create = str_hold ([[handle getObjectForKey:"create"] 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 plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context)\n", name); 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, "{\n");
fprintf (output_file, "\t__auto_type handle = (%s *) data;\n", name); fprintf (output_file, "\t__auto_type handle = (%s *) data;\n", name);
@ -40,16 +42,22 @@ output_handle (string name, PLItem *handle)
fprintf (output_file, "\t}\n"); fprintf (output_file, "\t}\n");
fprintf (output_file, "\treturn 1;\n"); fprintf (output_file, "\treturn 1;\n");
fprintf (output_file, "}\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, "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, "{\n");
fprintf (output_file, "\thandleref_t *handleref = data;\n"); fprintf (output_file, "\thandleref_t *handleref = data;\n");
fprintf (output_file, "\thandleref->name = strdup (field->name);\n"); fprintf (output_file, "\thandleref->name = strdup (field->name);\n");
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, "\treturn parse_%s (field, item, &handleref->handle, messages, context);\n", name);
}
fprintf (output_file, "}\n"); 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, "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); 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 (symtab);
str_free (class); str_free (class);
str_free (create); str_free (create);

View file

@ -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

View file

@ -0,0 +1,44 @@
#include <string.h>
#include <PropertyList.h>
#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);
}

View file

@ -207,6 +207,9 @@ parse_enum (const plfield_t *field, const plitem_t *item,
// field->name, field->offset, field->type, field->parser, // field->name, field->offset, field->type, field->parser,
// field->data, valstr); // field->data, valstr);
ret = !cexpr_parse_enum (enm, valstr, &ectx, data); 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); //Sys_Printf (" %d\n", *(int *)data);
return ret; return ret;
} }
@ -347,24 +350,37 @@ parse_RGBA (const plitem_t *item, void **data,
} }
static int static int
parse_VkShaderModule (const plitem_t *item, void **data, parse_VkShaderModule (const plfield_t *field, const plitem_t *item, void *data,
plitem_t *messages, parsectx_t *context) 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); const char *name = PL_String (item);
__auto_type mptr = (VkShaderModule *)data[0]; handleref_t *hr = Hash_Find (ctx->shaderModules, name);
VkShaderModule module = QFV_FindShaderModule (ctx, name); if (!hr) {
if (module) { PL_Message (messages, item, "undefined shader module %s", name);
*mptr = module;
return 1;
}
return 0; return 0;
} }
*handle = (VkShaderModule) hr->handle;
return 1;
}
typedef struct handleref_s { static int
char *name; parse_VkShaderModule_resource (const plfield_t *field, const plitem_t *item,
uint64_t handle; void *data, plitem_t *messages, void *context)
} handleref_t; {
__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 * static const char *
handleref_getkey (const void *hr, void *unused) handleref_getkey (const void *hr, void *unused)
@ -393,6 +409,45 @@ setLayout_free (void *hr, void *_ctx)
handleref_free (handleref, 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 hashtab_t *enum_symtab;
static int static int
@ -406,16 +461,6 @@ parse_BasePipeline (const plitem_t *item, void **data,
#include "libs/video/renderer/vulkan/vkparse.cinc" #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 { typedef struct qfv_renderpass_s {
qfv_attachmentdescription_t *attachments; qfv_attachmentdescription_t *attachments;
qfv_subpassparametersset_t *subpasses; qfv_subpassparametersset_t *subpasses;
@ -509,27 +554,46 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist)
} }
void void
QFV_ParseDescriptorSetLayouts (vulkan_ctx_t *ctx, plitem_t *sets) QFV_ParseResources (vulkan_ctx_t *ctx, plitem_t *pipelinedef)
{ {
plitem_t *messages = PL_NewArray (); plitem_t *messages = PL_NewArray ();
exprctx_t exprctx = {}; exprctx_t exprctx = {};
parsectx_t parsectx = { &exprctx, ctx }; parsectx_t parsectx = { &exprctx, ctx };
int ret = 1;
exprctx.memsuper = new_memsuper (); exprctx.memsuper = new_memsuper ();
exprctx.messages = messages; exprctx.messages = messages;
exprctx.hashlinks = ctx->hashlinks; exprctx.hashlinks = ctx->hashlinks;
if (!ctx->setLayouts) { 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->setLayouts = Hash_NewTable (23, handleref_getkey, setLayout_free,
ctx, &exprctx.hashlinks); 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); for (parseres_t *res = parse_resources; res->name; res++) {
if (!res || developer->int_val & SYS_VULKAN) { 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++) { for (int i = 0; i < PL_A_NumObjects (messages); i++) {
Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i))); Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i)));
} }
} }
PL_Free (messages); PL_Free (messages);
delete_memsuper (exprctx.memsuper); delete_memsuper (exprctx.memsuper);
ctx->hashlinks = exprctx.hashlinks; ctx->hashlinks = exprctx.hashlinks;

View file

@ -12,9 +12,19 @@ typedef struct parsectx_s {
struct vulkan_ctx_s *vctx; struct vulkan_ctx_s *vctx;
} parsectx_t; } 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); VkRenderPass QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist);
void QFV_ParseResources (vulkan_ctx_t *ctx, plitem_t *plist);
void QFV_InitParse (void); void QFV_InitParse (void);
exprenum_t *QFV_GetEnum (const char *name); exprenum_t *QFV_GetEnum (const char *name);

View file

@ -21,6 +21,11 @@
qfv_swapchain_t, qfv_swapchain_t,
); );
handles = { handles = {
VkShaderModule = {
symtab = shaderModules;
class = "shader module";
custom = parse_VkShaderModule_resource;
};
VkDescriptorSetLayout = { VkDescriptorSetLayout = {
symtab = setLayouts; symtab = setLayouts;
class = "set layout"; class = "set layout";
@ -37,6 +42,29 @@
create = vkCreatePipelineLayout; 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 = { parse = {
qfv_swapchain_s = { qfv_swapchain_s = {
.name = qfv_swapchain_t; .name = qfv_swapchain_t;
@ -108,8 +136,12 @@
string = pName; string = pName;
}; };
module = { module = {
type = (custom, QFString, parse_VkShaderModule); type = (single, {
fields = (module); parse_type = QFString;
type = VkShaderModule;
parser = parse_VkShaderModule;
});
value = module;
}; };
specializationInfo = { specializationInfo = {
type = (single, VkSpecializationInfo); type = (single, VkSpecializationInfo);

View file

@ -403,46 +403,10 @@ void
Vulkan_CreatePipelines (vulkan_ctx_t *ctx) Vulkan_CreatePipelines (vulkan_ctx_t *ctx)
{ {
plitem_t *pipeline_def = qfv_load_pipeline (); plitem_t *pipeline_def = qfv_load_pipeline ();
plitem_t *item;
item = pipeline_def; if (pipeline_def) {
if (!item || !(item = PL_ObjectForKey (item, "modules"))) { QFV_ParseResources (ctx, pipeline_def);
Sys_Printf ("error loading modules\n");
} else {
Sys_Printf ("Found modules def\n");
} }
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 void