mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[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:
parent
125821fcdd
commit
e5932d1f92
8 changed files with 134 additions and 18 deletions
|
@ -183,6 +183,8 @@ pipeline_src = libs/video/renderer/vulkan/qfpipeline.plist
|
|||
pipeline_gen = libs/video/renderer/vulkan/qfpipeline.plc
|
||||
deferred_src = libs/video/renderer/vulkan/deferred.plist
|
||||
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_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/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)
|
||||
|
@ -315,8 +323,6 @@ fstriangle_src = $(vkshaderpath)/fstriangle.vert
|
|||
fstriangle_c = $(vkshaderpath)/fstriangle.vert.spvc
|
||||
pushcolor_src = $(vkshaderpath)/pushcolor.frag
|
||||
pushcolor_c = $(vkshaderpath)/pushcolor.frag.spvc
|
||||
shadow_src = $(vkshaderpath)/shadow.geom
|
||||
shadow_c = $(vkshaderpath)/shadow.geom.spvc
|
||||
|
||||
$(partphysicsc_c): $(partphysicsc_src)
|
||||
$(partupdatec_c): $(partupdatec_src)
|
||||
|
@ -378,8 +384,6 @@ $(fstriangle_c): $(fstriangle_src)
|
|||
|
||||
$(pushcolor_c): $(pushcolor_src)
|
||||
|
||||
$(shadow_c): $(shadow_src)
|
||||
|
||||
vkshader_c = \
|
||||
$(partphysicsc_c) \
|
||||
$(partupdatec_c) \
|
||||
|
@ -446,6 +450,7 @@ BUILT_SOURCES += $(shader_gen)
|
|||
|
||||
EXTRA_DIST += \
|
||||
$(deferred_src) \
|
||||
$(shadow_src) \
|
||||
$(forward_src) \
|
||||
$(pipeline_src) \
|
||||
libs/video/renderer/vulkan/vkparse.plist \
|
||||
|
|
|
@ -102,8 +102,6 @@ static
|
|||
#include "libs/video/renderer/vulkan/shader/fstriangle.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/pushcolor.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/shader/shadow.geom.spvc"
|
||||
|
||||
typedef struct shaderdata_s {
|
||||
const char *name;
|
||||
|
@ -144,7 +142,6 @@ static shaderdata_t builtin_shaders[] = {
|
|||
{ "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) },
|
||||
{ "fstriangle.vert", fstriangle_vert, sizeof (fstriangle_vert) },
|
||||
{ "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) },
|
||||
{ "shadow.geom", shadow_geom, sizeof (shadow_geom) },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,10 +23,7 @@
|
|||
viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
format = $properties.images.shadow.format;
|
||||
components = {
|
||||
r = identity;
|
||||
g = identity;
|
||||
b = identity;
|
||||
a = identity;
|
||||
r = identity; g = identity; b = identity; a = identity;
|
||||
};
|
||||
subresourceRange = {
|
||||
aspectMask = depth;
|
||||
|
@ -37,7 +34,7 @@
|
|||
};
|
||||
framebuffer = {
|
||||
renderPass = $properties.renderpass;
|
||||
attachments = (shadown);
|
||||
attachments = (shadow);
|
||||
width = $properties.images.shadow.extent.width;
|
||||
height = $properties.images.shadow.extent.height;
|
||||
layers = $properties.images.shadow.arrayLayers;
|
||||
|
@ -46,9 +43,12 @@
|
|||
{ depthStencil = { depth = 1; stencil = 0; }; },
|
||||
);
|
||||
renderpass = {
|
||||
@next = (VkRenderPassMultiviewCreateInfo, {
|
||||
viewMasks = (0xffffffff);
|
||||
});
|
||||
attachments = (
|
||||
{
|
||||
format = $properties.images.depth.format;
|
||||
format = $properties.images.shadow.format;
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = store;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
@interface Struct: Type
|
||||
{
|
||||
string outname;
|
||||
int write_symtab;
|
||||
}
|
||||
-(void) queueFieldTypes;
|
||||
-(qfot_var_t *)findField:(string) fieldName;
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
PLItem *new_name = [field_dict getObjectForKey:".name"];
|
||||
Array *field_defs = [Array array];
|
||||
int have_sType = 0;
|
||||
int have_pNext = 0;
|
||||
|
||||
if ([parse string] == "skip") {
|
||||
return;
|
||||
|
@ -97,6 +98,10 @@
|
|||
if (field.name == "sType") {
|
||||
have_sType = 1;
|
||||
}
|
||||
if (field.name == "pNext") {
|
||||
have_pNext = 1;
|
||||
write_symtab = 1;
|
||||
}
|
||||
}
|
||||
if (field_dict) {
|
||||
PLItem *field_keys = [field_dict allKeys];
|
||||
|
@ -133,6 +138,11 @@
|
|||
fprintf (output_file,
|
||||
"\t{\"@inherit\", 0, QFString, parse_inherit, &%s_fields},\n",
|
||||
[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; ) {
|
||||
FieldDef *field_def = [field_defs objectAtIndex:i];
|
||||
[field_def writeField];
|
||||
|
@ -140,14 +150,14 @@
|
|||
fprintf (output_file, "\t{ }\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,"
|
||||
" void *context);\n",
|
||||
[self outname]);
|
||||
fprintf (output_file, "int parse_%s (const plfield_t *field,"
|
||||
[self parseFunc]);
|
||||
fprintf (output_file, "int %s (const plfield_t *field,"
|
||||
" const plitem_t *item, void *data, plitem_t *messages,"
|
||||
" void *context)\n",
|
||||
[self outname]);
|
||||
[self parseFunc]);
|
||||
fprintf (output_file, "{\n");
|
||||
if (have_sType) {
|
||||
fprintf (output_file, "\t((%s *) data)->sType", [self outname]);
|
||||
|
@ -162,6 +172,12 @@
|
|||
" context);\n",
|
||||
[self outname], [self outname]);
|
||||
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]);
|
||||
if (field_defs) {
|
||||
|
@ -216,6 +232,12 @@
|
|||
|
||||
-(void) writeSymtabEntry
|
||||
{
|
||||
if (!write_symtab || [parse string] == "skip") {
|
||||
return;
|
||||
}
|
||||
fprintf (output_file,
|
||||
"\tHash_Add (parser_table, &%s_parser);\n",
|
||||
[self outname]);
|
||||
}
|
||||
|
||||
-(string) outname
|
||||
|
|
|
@ -56,6 +56,12 @@ typedef struct parseres_s {
|
|||
size_t offset;
|
||||
} parseres_t;
|
||||
|
||||
typedef struct parseref_s {
|
||||
const char *name;
|
||||
plparser_t parse;
|
||||
size_t size;
|
||||
} parserref_t;
|
||||
|
||||
typedef struct handleref_s {
|
||||
char *name;
|
||||
uint64_t handle;
|
||||
|
@ -169,6 +175,33 @@ parse_basic (const plfield_t *field, const plitem_t *item,
|
|||
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
|
||||
parse_uint32_t (const plfield_t *field, const plitem_t *item,
|
||||
void *data, plitem_t *messages, void *context)
|
||||
|
@ -393,6 +426,33 @@ parse_inherit (const plfield_t *field, const plitem_t *item,
|
|||
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
|
||||
parse_RGBA (const plitem_t *item, void **data,
|
||||
plitem_t *messages, parsectx_t *context)
|
||||
|
@ -971,6 +1031,13 @@ enum_symtab_getkey (const void *e, void *unused)
|
|||
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 = {
|
||||
.symbols = cexpr_lib_symbols,
|
||||
};
|
||||
|
@ -988,6 +1055,7 @@ QFV_InitParse (vulkan_ctx_t *ctx)
|
|||
{
|
||||
exprctx_t context = {};
|
||||
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;
|
||||
vkgen_init_symtabs (&context);
|
||||
cexpr_init_symtab (&qfv_output_t_symtab, &context);
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
VkFramebufferCreateInfo,
|
||||
VkClearValue,
|
||||
VkPhysicalDeviceLimits,
|
||||
VkRenderPassCreateInfo,
|
||||
VkRenderPassMultiviewCreateInfo,
|
||||
);
|
||||
parse = {
|
||||
VkSubpassDescription = {
|
||||
|
@ -359,5 +361,22 @@
|
|||
};
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,10 @@ static exprsym_t builtin_plist_syms[] = {
|
|||
.value = (void *)
|
||||
#include "libs/video/renderer/vulkan/deferred.plc"
|
||||
},
|
||||
{ .name = "shadow",
|
||||
.value = (void *)
|
||||
#include "libs/video/renderer/vulkan/shadow.plc"
|
||||
},
|
||||
{ .name = "forward",
|
||||
.value = (void *)
|
||||
#include "libs/video/renderer/vulkan/forward.plc"
|
||||
|
|
Loading…
Reference in a new issue