mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
[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:
parent
d8261ade9e
commit
e5708100bb
13 changed files with 257 additions and 186 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
9
libs/video/renderer/vulkan/vkgen/vkresource.h
Normal file
9
libs/video/renderer/vulkan/vkgen/vkresource.h
Normal 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
|
44
libs/video/renderer/vulkan/vkgen/vkresource.r
Normal file
44
libs/video/renderer/vulkan/vkgen/vkresource.r
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue