From 3498d8b2aee915510f1a722a4f1e8a9ef96a569e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 10 Feb 2023 19:36:53 +0900 Subject: [PATCH] [vkgen] Add support for labeled array elements This treats dictionary items as arrays ordered by key creation (ie, the order of the key/value pairs in the dictionary is preserved). The label is written to the specified field when parsing the struct. Both actual arrays and single element "arrays" are supported. --- .../video/renderer/vulkan/vkgen/Makemodule.am | 4 + libs/video/renderer/vulkan/vkgen/vkfielddef.r | 6 ++ .../vulkan/vkgen/vkfieldlabeledarray.h | 11 +++ .../vulkan/vkgen/vkfieldlabeledarray.r | 37 +++++++++ .../vulkan/vkgen/vkfieldlabeledsingle.h | 11 +++ .../vulkan/vkgen/vkfieldlabeledsingle.r | 37 +++++++++ libs/video/renderer/vulkan/vkgen/vkstruct.h | 2 + libs/video/renderer/vulkan/vkgen/vkstruct.r | 18 ++++- libs/video/renderer/vulkan/vkparse.c | 78 ++++++++++++++++++- 9 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.h create mode 100644 libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.r create mode 100644 libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.h create mode 100644 libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.r diff --git a/libs/video/renderer/vulkan/vkgen/Makemodule.am b/libs/video/renderer/vulkan/vkgen/Makemodule.am index 83fab1eee..dd2d82a63 100644 --- a/libs/video/renderer/vulkan/vkgen/Makemodule.am +++ b/libs/video/renderer/vulkan/vkgen/Makemodule.am @@ -12,6 +12,8 @@ vkgen_dat_src= \ libs/video/renderer/vulkan/vkgen/vkfielddata.r \ libs/video/renderer/vulkan/vkgen/vkfielddef.r \ libs/video/renderer/vulkan/vkgen/vkfieldignore.r \ + libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.r \ + libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.r \ libs/video/renderer/vulkan/vkgen/vkfieldreadonly.r \ libs/video/renderer/vulkan/vkgen/vkfieldsingle.r \ libs/video/renderer/vulkan/vkgen/vkfieldstring.r \ @@ -57,6 +59,8 @@ EXTRA_DIST += \ libs/video/renderer/vulkan/vkgen/vkfielddata.h \ libs/video/renderer/vulkan/vkgen/vkfielddef.h \ libs/video/renderer/vulkan/vkgen/vkfieldignore.h \ + libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.h \ + libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.h \ libs/video/renderer/vulkan/vkgen/vkfieldreadonly.h \ libs/video/renderer/vulkan/vkgen/vkfieldsingle.h \ libs/video/renderer/vulkan/vkgen/vkfieldstring.h \ diff --git a/libs/video/renderer/vulkan/vkgen/vkfielddef.r b/libs/video/renderer/vulkan/vkgen/vkfielddef.r index 71e82e57f..9638dd109 100644 --- a/libs/video/renderer/vulkan/vkgen/vkfielddef.r +++ b/libs/video/renderer/vulkan/vkgen/vkfielddef.r @@ -7,6 +7,8 @@ #include "vkfielddata.h" #include "vkfielddef.h" #include "vkfieldignore.h" +#include "vkfieldlabeledarray.h" +#include "vkfieldlabeledsingle.h" #include "vkfieldreadonly.h" #include "vkfieldsingle.h" #include "vkfieldstring.h" @@ -44,6 +46,10 @@ return [[[SingleField alloc] init:item struct:strct field:fname] autorelease]; case "array": return [[[ArrayField alloc] init:item struct:strct field:fname] autorelease]; + case "labeledarray": + return [[[LabeledArrayField alloc] init:item struct:strct field:fname] autorelease]; + case "labeledsingle": + return [[[LabeledSingleField alloc] init:item struct:strct field:fname] autorelease]; case "readonly": return [[[ReadOnlyField alloc] init:item struct:strct field:fname] autorelease]; case "ignore": diff --git a/libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.h b/libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.h new file mode 100644 index 000000000..db3ec6b15 --- /dev/null +++ b/libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.h @@ -0,0 +1,11 @@ +#ifndef __renderer_vulkan_vkgen_vkfieldlabeledarray_h +#define __renderer_vulkan_vkgen_vkfieldlabeledarray_h + +#include "vkfieldarray.h" + +@interface LabeledArrayField: ArrayField +{ +} +@end + +#endif//__renderer_vulkan_vkgen_vkfieldlabeledarray_h diff --git a/libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.r b/libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.r new file mode 100644 index 000000000..efb02f782 --- /dev/null +++ b/libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.r @@ -0,0 +1,37 @@ +#include + +#include "vkfieldlabeledarray.h" +#include "vkfieldtype.h" +#include "vkgen.h" +#include "vkstruct.h" +#include "vktype.h" + +@implementation LabeledArrayField + +-init:(PLItem *) item struct:(Struct *)strct field:(string)fname +{ + self = [super init:item struct:strct field:fname]; + if (!self) { + return self; + } + + PLItem *desc = [item getObjectForKey:"type"]; + string label_field = [[desc getObjectAtIndex:2] string]; + Type *t = [[Type lookup:[type type]] resolveType]; + if ([t isKindOfClass:[Struct class]]) { + Struct *s = (Struct *) t; + [s setLabelField:label_field]; + } + + return self; +} + +-writeField +{ + fprintf (output_file, "\t{\"%s\", 0, %s, parse_%s, &parse_%s_%s_data},\n", + field_name, "QFDictionary", "labeledarray", struct_name, + field_name); + return self; +} + +@end diff --git a/libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.h b/libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.h new file mode 100644 index 000000000..7685c366c --- /dev/null +++ b/libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.h @@ -0,0 +1,11 @@ +#ifndef __renderer_vulkan_vkgen_vkfieldlabeledsingle_h +#define __renderer_vulkan_vkgen_vkfieldlabeledsingle_h + +#include "vkfieldsingle.h" + +@interface LabeledSingleField: SingleField +{ +} +@end + +#endif//__renderer_vulkan_vkgen_vkfieldlabeledsingle_h diff --git a/libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.r b/libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.r new file mode 100644 index 000000000..fe3fd9dce --- /dev/null +++ b/libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.r @@ -0,0 +1,37 @@ +#include + +#include "vkfieldlabeledsingle.h" +#include "vkfieldtype.h" +#include "vkgen.h" +#include "vkstruct.h" +#include "vktype.h" + +@implementation LabeledSingleField + +-init:(PLItem *) item struct:(Struct *)strct field:(string)fname +{ + self = [super init:item struct:strct field:fname]; + if (!self) { + return self; + } + + PLItem *desc = [item getObjectForKey:"type"]; + string label_field = [[desc getObjectAtIndex:2] string]; + Type *t = [[Type lookup:[type type]] resolveType]; + if ([t isKindOfClass:[Struct class]]) { + Struct *s = (Struct *) t; + [s setLabelField:label_field]; + } + + return self; +} + +-writeField +{ + fprintf (output_file, "\t{\"%s\", 0, %s, parse_%s, &parse_%s_%s_data},\n", + field_name, "QFDictionary", "labeledsingle", struct_name, + field_name); + return self; +} + +@end diff --git a/libs/video/renderer/vulkan/vkgen/vkstruct.h b/libs/video/renderer/vulkan/vkgen/vkstruct.h index 9ff3137e4..095c22629 100644 --- a/libs/video/renderer/vulkan/vkgen/vkstruct.h +++ b/libs/video/renderer/vulkan/vkgen/vkstruct.h @@ -11,10 +11,12 @@ @interface Struct: Type { string outname; + string label_field; int write_symtab; } -(void) queueFieldTypes; -(qfot_var_t *)findField:(string) fieldName; +-(void) setLabelField:(string) label_field; -(void) writeForward; -(void) writeTable; -(void) writeSymtabInit; diff --git a/libs/video/renderer/vulkan/vkgen/vkstruct.r b/libs/video/renderer/vulkan/vkgen/vkstruct.r index 85309f011..11818209f 100644 --- a/libs/video/renderer/vulkan/vkgen/vkstruct.r +++ b/libs/video/renderer/vulkan/vkgen/vkstruct.r @@ -12,6 +12,12 @@ @implementation Struct +-(void) dealloc +{ + str_free (outname); + str_free (label_field); +} + -(string) name { return str_mid(type.strct.tag, 4); @@ -67,7 +73,7 @@ -(string)sTypeName { string s = "VK_STRUCTURE_TYPE"; - string name = str_hold ([self outname]); + string name = [self outname]; int length = strlen (name); int start, end, c; for (start = 2; start < length; start = end) { @@ -83,6 +89,11 @@ return str_upper (s); } +-(void) setLabelField:(string)label_field +{ + self.label_field = label_field; +} + -(void) writeForward { PLItem *field_dict = [parse getObjectForKey:[self name]]; @@ -183,6 +194,11 @@ fprintf (output_file, "\t((%s *) data)->sType", [self outname]); fprintf (output_file, " = %s;\n", [self sTypeName]); } + if (label_field) { + fprintf (output_file, "\t((%s *) data)->%s", [self outname], + label_field); + fprintf (output_file, " = vkstrdup (context, field->name);\n"); + } fprintf (output_file, "\tif (PL_Type (item) == QFString\n" "\t\t&& !(item = parse_reference (item, \"%s\", messages, context))) {\n" diff --git a/libs/video/renderer/vulkan/vkparse.c b/libs/video/renderer/vulkan/vkparse.c index 49ff4d182..3d7d3298a 100644 --- a/libs/video/renderer/vulkan/vkparse.c +++ b/libs/video/renderer/vulkan/vkparse.c @@ -303,6 +303,34 @@ parse_ignore (const plfield_t *field, const plitem_t *item, return 1; } +static int __attribute__((used)) +parse_labeledsingle (const plfield_t *field, const plitem_t *item, + void *data, plitem_t *messages, void *context) +{ + __auto_type single = (parse_single_t *) field->data; + void *flddata = (byte *)data + single->value_offset; + + //Sys_MaskPrintf (SYS_vulkan_parse,"parse_labeledsingle: %s %zd %d %p %p\n", + // field->name, field->offset, + // field->type, field->parser, field->data); + + if (!PL_CheckType (single->type, PL_Type (item))) { + PL_TypeMismatch (messages, item, field->name, single->type, + PL_Type (item)); + return 0; + } + + plfield_t f = { 0, 0, single->type, single->parser, 0 }; + void *value = vkparse_alloc (context, single->stride); + memset (value, 0, single->stride); + if (!single->parser (&f, item, value, messages, context)) { + return 0; + } + + *(void **) flddata = value; + return 1; +} + static int parse_single (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context) @@ -331,6 +359,43 @@ parse_single (const plfield_t *field, const plitem_t *item, return 1; } +static int __attribute__((used)) +parse_labeledarray (const plfield_t *field, const plitem_t *item, + void *data, plitem_t *messages, void *context) +{ + __auto_type array = (parse_array_t *) field->data; + __auto_type value = (void **) ((byte *)data + array->value_offset); + __auto_type size = (uint32_t *) ((byte *)data + array->size_offset); + + plelement_t element = { + array->type, + array->stride, + vkparse_alloc, + array->parser, + array->data, + }; + plfield_t f = { 0, 0, 0, 0, &element }; + + typedef struct arr_s DARRAY_TYPE(byte) arr_t; + arr_t *arr; + + //Sys_MaskPrintf (SYS_vulkan_parse, "parse_array: %s %zd %d %p %p %p\n", + // field->name, field->offset, field->type, field->parser, + // field->data, data); + //Sys_MaskPrintf (SYS_vulkan_parse, " %d %zd %p %zd %zd\n", array->type, + // array->stride, array->parser, array->value_offset, + // array->size_offset); + if (!PL_ParseLabeledArray (&f, item, &arr, messages, context)) { + return 0; + } + *value = vkparse_alloc (context, array->stride * arr->size); + memcpy (*value, arr->a, array->stride * arr->size); + if ((void *) size >= data) { + *size = arr->size; + } + return 1; +} + static int parse_array (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context) @@ -395,6 +460,15 @@ parse_fixed_array (const plfield_t *field, const plitem_t *item, return 1; } +static char * +vkstrdup (parsectx_t *context, const char *str) +{ + size_t len = strlen (str) + 1; + char *dup = vkparse_alloc (context, len); + memcpy (dup, str, len); + return dup; +} + static int parse_string (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context) @@ -410,9 +484,7 @@ parse_string (const plfield_t *field, const plitem_t *item, //Sys_MaskPrintf (SYS_vulkan_parse, " %zd\n", string->value_offset); //Sys_MaskPrintf (SYS_vulkan_parse, " %s\n", str); - size_t len = strlen (str) + 1; - *value = vkparse_alloc (context, len); - memcpy (*value, str, len); + *value = vkstrdup (context, str); return 1; }