[vulkan] Support Vulkan's pNext in vkparse/vkgen

The real reason for the delay in implementing support for pNext is I
didn't know how to approach it at the time, but with the experience I've
gained using and modifying vkparse, the solution turned out to be fairly
simple. This allows for the use of various extensions (eg, multiview,
which was used for testing, though none of the hookup is in this
commit). No checking is done on the struct type being valid other than
it must be of a chainable type (ie, have its own pNext).
This commit is contained in:
Bill Currie 2022-05-29 21:53:38 +09:00
parent 125821fcdd
commit e5932d1f92
8 changed files with 134 additions and 18 deletions

View file

@ -183,6 +183,8 @@ pipeline_src = libs/video/renderer/vulkan/qfpipeline.plist
pipeline_gen = libs/video/renderer/vulkan/qfpipeline.plc pipeline_gen = libs/video/renderer/vulkan/qfpipeline.plc
deferred_src = libs/video/renderer/vulkan/deferred.plist deferred_src = libs/video/renderer/vulkan/deferred.plist
deferred_gen = libs/video/renderer/vulkan/deferred.plc deferred_gen = libs/video/renderer/vulkan/deferred.plc
shadow_src = libs/video/renderer/vulkan/shadow.plist
shadow_gen = libs/video/renderer/vulkan/shadow.plc
forward_src = libs/video/renderer/vulkan/forward.plist forward_src = libs/video/renderer/vulkan/forward.plist
forward_gen = libs/video/renderer/vulkan/forward.plc forward_gen = libs/video/renderer/vulkan/forward.plc
@ -236,7 +238,13 @@ libs/video/renderer/vulkan/vkparse.lo: libs/video/renderer/vulkan/vkparse.c $(vk
libs/video/renderer/vulkan/shader.lo: libs/video/renderer/vulkan/shader.c $(vkshader_c) libs/video/renderer/vulkan/shader.lo: libs/video/renderer/vulkan/shader.c $(vkshader_c)
libs/video/renderer/vulkan/vulkan_vid_common.lo: libs/video/renderer/vulkan/vulkan_vid_common.c $(vkparse_src) $(pipeline_gen) ${deferred_gen} $(forward_gen) libs/video/renderer/vulkan/vulkan_vid_common.lo: \
libs/video/renderer/vulkan/vulkan_vid_common.c \
$(vkparse_src) \
$(pipeline_gen) \
${deferred_gen} \
${shadow_gen} \
$(forward_gen)
qwaq_cmd = $(top_builddir)/ruamoko/qwaq/qwaq-cmd$(EXEEXT) qwaq_cmd = $(top_builddir)/ruamoko/qwaq/qwaq-cmd$(EXEEXT)
@ -315,8 +323,6 @@ fstriangle_src = $(vkshaderpath)/fstriangle.vert
fstriangle_c = $(vkshaderpath)/fstriangle.vert.spvc fstriangle_c = $(vkshaderpath)/fstriangle.vert.spvc
pushcolor_src = $(vkshaderpath)/pushcolor.frag pushcolor_src = $(vkshaderpath)/pushcolor.frag
pushcolor_c = $(vkshaderpath)/pushcolor.frag.spvc pushcolor_c = $(vkshaderpath)/pushcolor.frag.spvc
shadow_src = $(vkshaderpath)/shadow.geom
shadow_c = $(vkshaderpath)/shadow.geom.spvc
$(partphysicsc_c): $(partphysicsc_src) $(partphysicsc_c): $(partphysicsc_src)
$(partupdatec_c): $(partupdatec_src) $(partupdatec_c): $(partupdatec_src)
@ -378,8 +384,6 @@ $(fstriangle_c): $(fstriangle_src)
$(pushcolor_c): $(pushcolor_src) $(pushcolor_c): $(pushcolor_src)
$(shadow_c): $(shadow_src)
vkshader_c = \ vkshader_c = \
$(partphysicsc_c) \ $(partphysicsc_c) \
$(partupdatec_c) \ $(partupdatec_c) \
@ -446,6 +450,7 @@ BUILT_SOURCES += $(shader_gen)
EXTRA_DIST += \ EXTRA_DIST += \
$(deferred_src) \ $(deferred_src) \
$(shadow_src) \
$(forward_src) \ $(forward_src) \
$(pipeline_src) \ $(pipeline_src) \
libs/video/renderer/vulkan/vkparse.plist \ libs/video/renderer/vulkan/vkparse.plist \

View file

@ -102,8 +102,6 @@ static
#include "libs/video/renderer/vulkan/shader/fstriangle.vert.spvc" #include "libs/video/renderer/vulkan/shader/fstriangle.vert.spvc"
static static
#include "libs/video/renderer/vulkan/shader/pushcolor.frag.spvc" #include "libs/video/renderer/vulkan/shader/pushcolor.frag.spvc"
static
#include "libs/video/renderer/vulkan/shader/shadow.geom.spvc"
typedef struct shaderdata_s { typedef struct shaderdata_s {
const char *name; const char *name;
@ -144,7 +142,6 @@ static shaderdata_t builtin_shaders[] = {
{ "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) }, { "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) },
{ "fstriangle.vert", fstriangle_vert, sizeof (fstriangle_vert) }, { "fstriangle.vert", fstriangle_vert, sizeof (fstriangle_vert) },
{ "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) }, { "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) },
{ "shadow.geom", shadow_geom, sizeof (shadow_geom) },
{} {}
}; };

View file

@ -23,10 +23,7 @@
viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
format = $properties.images.shadow.format; format = $properties.images.shadow.format;
components = { components = {
r = identity; r = identity; g = identity; b = identity; a = identity;
g = identity;
b = identity;
a = identity;
}; };
subresourceRange = { subresourceRange = {
aspectMask = depth; aspectMask = depth;
@ -37,7 +34,7 @@
}; };
framebuffer = { framebuffer = {
renderPass = $properties.renderpass; renderPass = $properties.renderpass;
attachments = (shadown); attachments = (shadow);
width = $properties.images.shadow.extent.width; width = $properties.images.shadow.extent.width;
height = $properties.images.shadow.extent.height; height = $properties.images.shadow.extent.height;
layers = $properties.images.shadow.arrayLayers; layers = $properties.images.shadow.arrayLayers;
@ -46,9 +43,12 @@
{ depthStencil = { depth = 1; stencil = 0; }; }, { depthStencil = { depth = 1; stencil = 0; }; },
); );
renderpass = { renderpass = {
@next = (VkRenderPassMultiviewCreateInfo, {
viewMasks = (0xffffffff);
});
attachments = ( attachments = (
{ {
format = $properties.images.depth.format; format = $properties.images.shadow.format;
samples = 1; samples = 1;
loadOp = dont_care; loadOp = dont_care;
storeOp = store; storeOp = store;

View file

@ -11,6 +11,7 @@
@interface Struct: Type @interface Struct: Type
{ {
string outname; string outname;
int write_symtab;
} }
-(void) queueFieldTypes; -(void) queueFieldTypes;
-(qfot_var_t *)findField:(string) fieldName; -(qfot_var_t *)findField:(string) fieldName;

View file

@ -84,6 +84,7 @@
PLItem *new_name = [field_dict getObjectForKey:".name"]; PLItem *new_name = [field_dict getObjectForKey:".name"];
Array *field_defs = [Array array]; Array *field_defs = [Array array];
int have_sType = 0; int have_sType = 0;
int have_pNext = 0;
if ([parse string] == "skip") { if ([parse string] == "skip") {
return; return;
@ -97,6 +98,10 @@
if (field.name == "sType") { if (field.name == "sType") {
have_sType = 1; have_sType = 1;
} }
if (field.name == "pNext") {
have_pNext = 1;
write_symtab = 1;
}
} }
if (field_dict) { if (field_dict) {
PLItem *field_keys = [field_dict allKeys]; PLItem *field_keys = [field_dict allKeys];
@ -133,6 +138,11 @@
fprintf (output_file, fprintf (output_file,
"\t{\"@inherit\", 0, QFString, parse_inherit, &%s_fields},\n", "\t{\"@inherit\", 0, QFString, parse_inherit, &%s_fields},\n",
[self outname]); [self outname]);
if (have_pNext) {
fprintf (output_file,
"\t{\"@next\", field_offset (%s, pNext), "
"QFArray, parse_next, 0},", [self outname]);
}
for (int i = [field_defs count]; i-- > 0; ) { for (int i = [field_defs count]; i-- > 0; ) {
FieldDef *field_def = [field_defs objectAtIndex:i]; FieldDef *field_def = [field_defs objectAtIndex:i];
[field_def writeField]; [field_def writeField];
@ -140,14 +150,14 @@
fprintf (output_file, "\t{ }\n"); fprintf (output_file, "\t{ }\n");
fprintf (output_file, "};\n"); fprintf (output_file, "};\n");
fprintf (header_file, "int parse_%s (const plfield_t *field," fprintf (header_file, "int %s (const plfield_t *field,"
" const plitem_t *item, void *data, plitem_t *messages," " const plitem_t *item, void *data, plitem_t *messages,"
" void *context);\n", " void *context);\n",
[self outname]); [self parseFunc]);
fprintf (output_file, "int parse_%s (const plfield_t *field," fprintf (output_file, "int %s (const plfield_t *field,"
" const plitem_t *item, void *data, plitem_t *messages," " const plitem_t *item, void *data, plitem_t *messages,"
" void *context)\n", " void *context)\n",
[self outname]); [self parseFunc]);
fprintf (output_file, "{\n"); fprintf (output_file, "{\n");
if (have_sType) { if (have_sType) {
fprintf (output_file, "\t((%s *) data)->sType", [self outname]); fprintf (output_file, "\t((%s *) data)->sType", [self outname]);
@ -162,6 +172,12 @@
" context);\n", " context);\n",
[self outname], [self outname]); [self outname], [self outname]);
fprintf (output_file, "}\n"); fprintf (output_file, "}\n");
if (have_pNext) {
fprintf (output_file, "static parserref_t %s_parser = ",
[self outname]);
fprintf (output_file, "{\"%s\", %s, sizeof(%s)};\n",
[self outname], [self parseFunc], [self outname]);
}
fprintf (output_file, "static exprsym_t %s_symbols[] = {\n", [self outname]); fprintf (output_file, "static exprsym_t %s_symbols[] = {\n", [self outname]);
if (field_defs) { if (field_defs) {
@ -216,6 +232,12 @@
-(void) writeSymtabEntry -(void) writeSymtabEntry
{ {
if (!write_symtab || [parse string] == "skip") {
return;
}
fprintf (output_file,
"\tHash_Add (parser_table, &%s_parser);\n",
[self outname]);
} }
-(string) outname -(string) outname

View file

@ -56,6 +56,12 @@ typedef struct parseres_s {
size_t offset; size_t offset;
} parseres_t; } parseres_t;
typedef struct parseref_s {
const char *name;
plparser_t parse;
size_t size;
} parserref_t;
typedef struct handleref_s { typedef struct handleref_s {
char *name; char *name;
uint64_t handle; uint64_t handle;
@ -169,6 +175,33 @@ parse_basic (const plfield_t *field, const plitem_t *item,
return ret; return ret;
} }
static int
parse_int32_t (const plfield_t *field, const plitem_t *item,
void *data, plitem_t *messages, void *context)
{
int ret = 1;
// use size_t (and cexpr_size_t) for val so references to array sizes
// can be used
size_t val = 0;
exprval_t result = { &cexpr_size_t, &val };
exprctx_t ectx = *((parsectx_t *) context)->ectx;
ectx.result = &result;
const char *valstr = PL_String (item);
//Sys_MaskPrintf (SYS_vulkan_parse,
// "parse_int32_t: %s %zd %d %p %p %s\n",
// field->name, field->offset, field->type, field->parser,
// field->data, valstr);
ret = !cexpr_eval_string (valstr, &ectx);
if (!ret) {
PL_Message (messages, item, "error parsing %s: %s",
field->name, valstr);
}
*(int32_t *) data = val;
//Sys_MaskPrintf (SYS_vulkan_parse, " %d\n", *(int32_t *)data);
return ret;
}
static int static int
parse_uint32_t (const plfield_t *field, const plitem_t *item, parse_uint32_t (const plfield_t *field, const plitem_t *item,
void *data, plitem_t *messages, void *context) void *data, plitem_t *messages, void *context)
@ -393,6 +426,33 @@ parse_inherit (const plfield_t *field, const plitem_t *item,
return ret; return ret;
} }
static hashtab_t *parser_table;
static int
parse_next (const plfield_t *field, const plitem_t *item, void *data,
plitem_t *messages, void *context)
{
const char *type_name = PL_String (PL_ObjectAtIndex (item, 0));
plitem_t *next_def = PL_ObjectAtIndex (item, 1);
if (!type_name || PL_Type (next_def) != QFDictionary) {
PL_Message (messages, item, "invalid @next");
return 0;
}
parserref_t *parser = Hash_Find (parser_table, type_name);
if (!parser) {
PL_Message (messages, item, "Invalid type for @next: %s", type_name);
return 0;
}
void *data_ptr = vkparse_alloc (context, parser->size);
memset (data_ptr, 0, parser->size);
if (!parser->parse (field, next_def, data_ptr, messages, context)) {
return 0;
}
*(void **) data = data_ptr;
return 1;
}
static int static int
parse_RGBA (const plitem_t *item, void **data, parse_RGBA (const plitem_t *item, void **data,
plitem_t *messages, parsectx_t *context) plitem_t *messages, parsectx_t *context)
@ -971,6 +1031,13 @@ enum_symtab_getkey (const void *e, void *unused)
return enm->type->name; return enm->type->name;
} }
static const char *
parser_getkey (const void *e, void *unused)
{
__auto_type parser = (const parserref_t *) e;
return parser->name;
}
static exprtab_t root_symtab = { static exprtab_t root_symtab = {
.symbols = cexpr_lib_symbols, .symbols = cexpr_lib_symbols,
}; };
@ -988,6 +1055,7 @@ QFV_InitParse (vulkan_ctx_t *ctx)
{ {
exprctx_t context = {}; exprctx_t context = {};
enum_symtab = Hash_NewTable (61, enum_symtab_getkey, 0, 0, &ctx->hashctx); enum_symtab = Hash_NewTable (61, enum_symtab_getkey, 0, 0, &ctx->hashctx);
parser_table = Hash_NewTable (61, parser_getkey, 0, 0, &ctx->hashctx);
context.hashctx = &ctx->hashctx; context.hashctx = &ctx->hashctx;
vkgen_init_symtabs (&context); vkgen_init_symtabs (&context);
cexpr_init_symtab (&qfv_output_t_symtab, &context); cexpr_init_symtab (&qfv_output_t_symtab, &context);

View file

@ -28,6 +28,8 @@
VkFramebufferCreateInfo, VkFramebufferCreateInfo,
VkClearValue, VkClearValue,
VkPhysicalDeviceLimits, VkPhysicalDeviceLimits,
VkRenderPassCreateInfo,
VkRenderPassMultiviewCreateInfo,
); );
parse = { parse = {
VkSubpassDescription = { VkSubpassDescription = {
@ -359,5 +361,22 @@
}; };
depthStencil = auto; depthStencil = auto;
}; };
VkRenderPassMultiviewCreateInfo = {
viewMasks = {
type = (array, uint32_t);
size = subpassCount;
values = pViewMasks;
};
viewOffsets = {
type = (array, int32_t);
size = dependencyCount;
values = pViewOffsets;
};
correlationMasks = {
type = (array, uint32_t);
size = correlationMaskCount;
values = pCorrelationMasks;
};
}
} }
} }

View file

@ -75,6 +75,10 @@ static exprsym_t builtin_plist_syms[] = {
.value = (void *) .value = (void *)
#include "libs/video/renderer/vulkan/deferred.plc" #include "libs/video/renderer/vulkan/deferred.plc"
}, },
{ .name = "shadow",
.value = (void *)
#include "libs/video/renderer/vulkan/shadow.plc"
},
{ .name = "forward", { .name = "forward",
.value = (void *) .value = (void *)
#include "libs/video/renderer/vulkan/forward.plc" #include "libs/video/renderer/vulkan/forward.plc"