diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index b1196dc2f..d6ae44226 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -219,12 +219,25 @@ libs_video_renderer_vid_render_vulkan_la_SOURCES = \ libs/video/renderer/vulkan/vulkan_draw.c \ libs/video/renderer/vulkan/vulkan_vid_common.c +libs/video/renderer/vulkan/vulkan_vid_common.c: $(vkparse_src) + qwaq_curses = ruamoko/qwaq/qwaq-curses$(EXEEXT) -BUILT_SOURCES += libs/video/renderer/vulkan/vkenum.inc +vkparse_src = \ + libs/video/renderer/vulkan/vkenum.inc \ + libs/video/renderer/vulkan/vkstruct.inc + +V_VKGEN = $(V_VKGEN_@AM_V@) +V_VKGEN_ = $(V_VKGEN_@AM_DEFAULT_V@) +V_VKGEN_0 = @echo " VKGEN " $@; +V_VKGEN_1 = + libs/video/renderer/vulkan/vkenum.inc: $(vkgen) $(qwaq_curses) - $(qwaq_curses) $(vkgen) -- $@ + $(V_VKGEN)$(qwaq_curses) $(vkgen) -- enum $@ +libs/video/renderer/vulkan/vkstruct.inc: $(vkgen) $(qwaq_curses) + $(V_VKGEN)$(qwaq_curses) $(vkgen) -- struct $@ CLEANFILES += \ libs/video/renderer/glsl/*.vc \ libs/video/renderer/glsl/*.fc \ - libs/video/renderer/glsl/*.slc + libs/video/renderer/glsl/*.slc \ + $(vkparse_src) diff --git a/libs/video/renderer/vulkan/vkgen/Makemodule.am b/libs/video/renderer/vulkan/vkgen/Makemodule.am index 5eb099c9c..66971a2c3 100644 --- a/libs/video/renderer/vulkan/vkgen/Makemodule.am +++ b/libs/video/renderer/vulkan/vkgen/Makemodule.am @@ -2,6 +2,7 @@ vkgen = libs/video/renderer/vulkan/vkgen.dat$(EXEEXT) noinst_PROGRAMS += $(vkgen) vkgen_dat_src= \ + libs/video/renderer/vulkan/vkgen/vkalias.r \ libs/video/renderer/vulkan/vkgen/vkenum.r \ libs/video/renderer/vulkan/vkgen/vkgen.r \ libs/video/renderer/vulkan/vkgen/vkstruct.r \ @@ -33,6 +34,7 @@ libs/video/renderer/vulkan/vkgen/vulkan.o: $(top_srcdir)/libs/video/renderer/vul EXTRA_DIST += \ libs/video/renderer/vulkan/vkgen/stddef.h \ libs/video/renderer/vulkan/vkgen/stdint.h \ + libs/video/renderer/vulkan/vkgen/vkalias.h \ libs/video/renderer/vulkan/vkgen/vkenum.h \ libs/video/renderer/vulkan/vkgen/vkgen.h \ libs/video/renderer/vulkan/vkgen/vkstruct.h \ diff --git a/libs/video/renderer/vulkan/vkgen/vkalias.h b/libs/video/renderer/vulkan/vkgen/vkalias.h new file mode 100644 index 000000000..fadf6619f --- /dev/null +++ b/libs/video/renderer/vulkan/vkgen/vkalias.h @@ -0,0 +1,11 @@ +#ifndef __renderer_vulkan_vkgen_vkalias_h +#define __renderer_vulkan_vkgen_vkalias_h + +#include "vktype.h" + +@interface Alias: Type +{ +} +@end + +#endif//__renderer_vulkan_vkgen_vkalias_h diff --git a/libs/video/renderer/vulkan/vkgen/vkalias.r b/libs/video/renderer/vulkan/vkgen/vkalias.r new file mode 100644 index 000000000..f37396097 --- /dev/null +++ b/libs/video/renderer/vulkan/vkgen/vkalias.r @@ -0,0 +1,52 @@ +#include + +#include "vkalias.h" +#include "vkenum.h" +#include "vkgen.h" +#include "vkstruct.h" + +@implementation Alias +-(string) name +{ + return type.alias.name; +} + +-(Type *) resolveType +{ + return [Type findType: type.alias.aux_type]; +} + +-(void)addToQueue +{ + Type *alias = [Type findType:type.alias.full_type]; + string name = [self name]; + + if ([alias name] == "VkFlags") { + if (str_mid (name, -5) == "Flags") { + string tag = str_mid (name, 0, -1) + "Bits"; + id enumObj = [(id) Hash_Find (available_types, tag) resolveType]; + [enumObj addToQueue]; + } + } else if (name == "VkBool32") { + // drop + } else if ([alias class] == [Enum class] + || [alias class] == [Struct class]) { + [alias addToQueue]; + } else if (alias.type.meta == ty_basic && alias.type.type == ev_pointer) { + Type *type = [Type findType:alias.type.fldptr.aux_type]; + if (!type) { + // pointer to opaque struct. Probably VK_DEFINE_NON_DISPATCHABLE_HANDLE or VK_DEFINE_HANDLE + string createInfo = name + "CreateInfo"; + id structObj = (id) Hash_Find (available_types, createInfo); + if (structObj) { + [structObj addToQueue]; + } + } else if ([type class] == [Alias class]) { + type = [type resolveType]; + if ([type class] == [Struct class]) { + [type addToQueue]; + } + } + } +} +@end diff --git a/libs/video/renderer/vulkan/vkgen/vkenum.r b/libs/video/renderer/vulkan/vkgen/vkenum.r index 898ef5c58..10a476432 100644 --- a/libs/video/renderer/vulkan/vkgen/vkenum.r +++ b/libs/video/renderer/vulkan/vkgen/vkenum.r @@ -40,6 +40,16 @@ return str_mid(type.strct.tag, 4); } +-(void) addToQueue +{ + string name = [self name]; + if (!Hash_Find (processed_types, name)) { + printf (" +%s\n", name); + Hash_Add (processed_types, (void *) name); + [queue addObject: self]; + } +} + -(void) writeTable { int strip_bit = 0; diff --git a/libs/video/renderer/vulkan/vkgen/vkgen.h b/libs/video/renderer/vulkan/vkgen/vkgen.h index 3612a048f..0d488abe8 100644 --- a/libs/video/renderer/vulkan/vkgen/vkgen.h +++ b/libs/video/renderer/vulkan/vkgen/vkgen.h @@ -14,5 +14,6 @@ extern Array *queue; extern Array *output_types; extern QFile output_file; extern hashtab_t *processed_types; +extern hashtab_t *available_types; #endif//__renderer_vulkan_vkgen_vkgen_h diff --git a/libs/video/renderer/vulkan/vkgen/vkgen.r b/libs/video/renderer/vulkan/vkgen/vkgen.r index 7ef9f3ff6..183ba591b 100644 --- a/libs/video/renderer/vulkan/vkgen/vkgen.r +++ b/libs/video/renderer/vulkan/vkgen/vkgen.r @@ -13,7 +13,6 @@ void printf (string fmt, ...) = #0; void fprintf (QFile file, string format, ...) { - printf("fprintf %d\n", @args.count); Qputs (file, vsprintf (format, va_copy (@args))); } @@ -87,97 +86,8 @@ void print_type (qfot_type_t *type) void struct_func (qfot_var_t *var) { - qfot_type_t *alias; - if (var.type.meta == ty_enum) { - printf("%s a\n", var.name); - } else if (var.type.meta == ty_struct) { - printf("%s b\n", var.name); - } else if (var.type.meta == ty_union) { - printf("%s c\n", var.name); - } else if (var.type.meta == ty_alias) { - //printf("%s d\n", var.name); - // typedef fun ;) - alias = var.type.alias.full_type; - if (alias.meta == ty_alias) { - // double(+) typedef - if (alias.alias.name == "VkFlags") { - // enum flag fun :P - string tag = var.type.alias.name; - if (str_mid (tag, -5) == "Flags") { - tag = str_mid (tag, 0, -1) + "Bits"; - id enumObj = (id) Hash_Find (available_types, tag); - if (enumObj) { - [enumObj addToQueue]; - } - } - } else { - if (var.type.alias.name == "VkBool32") { - // drop - } else { - printf ("%s =%s\n", var.name, var.type.alias.name); - } - } - } else if (alias.meta == ty_enum) { - string tag = str_mid(alias.strct.tag, 4); - id enumObj = (id) Hash_Find (available_types, tag); - if (enumObj) { - [enumObj addToQueue]; - } - } else if (alias.meta == ty_basic && alias.type == ev_pointer) { - //printf("e\n"); - qfot_type_t *type = alias.fldptr.aux_type; - if (type.meta == ty_alias) { - id structObj = (id) Hash_Find (available_types, type.alias.name); - //printf (" a:%s %p\n", type.alias.name, structObj); - if (structObj) { - [structObj addToQueue]; - } - } else if (type_is_null (type)) { - // pointer to opaque struct. Probably VK_DEFINE_NON_DISPATCHABLE_HANDLE or VK_DEFINE_HANDLE - //drop - string createInfo = var.type.alias.name + "CreateInfo"; - id structObj = (id) Hash_Find (available_types, createInfo); - if (structObj) { - [structObj addToQueue]; - } else { - //printf(" b:%s\n", var.type.alias.name); - } - } else { - print_type (type); - printf("%s c:%s:%s\n", var.name, var.type.alias.name, pr_type_name[alias.type]); - } - } else if (alias.meta == ty_basic) { - //drop - //printf(" d:%s:%s\n", var.type.alias.name, pr_type_name[alias.type]); - } else if (alias.meta == ty_struct) { - string tag = str_mid(alias.strct.tag, 4); - id structObj = (id) Hash_Find (available_types, tag); - if (structObj) { - [structObj addToQueue]; - } - } else { - printf(" d:%s:%s\n", var.type.alias.name, ty_meta_name[alias.meta]); - } - } else if (var.type.meta == ty_basic && var.type.type == ev_pointer) { - qfot_type_t *type = var.type.fldptr.aux_type; - if (type.meta == ty_struct || type.meta == ty_union) { - printf("%s f\n", var.name); - } else if (type.meta == ty_alias) { - printf("%s --- %s\n", var.name, type.alias.name); - id obj = (id) Hash_Find (available_types, type.alias.name); - if (obj && [obj class] == [Struct class]) { - [obj forEachFieldCall:struct_func]; - } - } else if (type.meta == ty_basic && type.type == ev_void) { - //drop - } else { - printf("%s g\n", var.name); - print_type (var.type); - } - } else { - //drop - //printf(" %s:%s:%s\n", var.name, ty_meta_name[var.type.meta], pr_type_name[var.type.type]); - } + Type *type = [Type findType:var.type]; + [type addToQueue]; } void @@ -188,30 +98,14 @@ scan_types (void) for (type = encodings.types; ((int *)type - (int *) encodings.types) < encodings.size; type = next_type (type)) { - if (!type.size - || (type.meta != ty_enum - && type.meta != ty_struct - && type.meta != ty_union)) { - continue; + if (type.size) { + string tag = str_mid(type.strct.tag, 4); + Type *avail_type = [Type fromType: type]; + if (avail_type) { + Hash_Add (available_types, avail_type); + } } - string tag = str_mid(type.strct.tag, 4); - switch (type.meta) { - case ty_enum: - Hash_Add (available_types, [[Enum alloc] initWithType: type]); - //printf ("+ enum %s\n", tag); - break; - case ty_struct: - case ty_union: - Hash_Add (available_types, [[Struct alloc] initWithType: type]); - //printf ("+ struct %s\n", tag); - break; - case ty_basic: - case ty_array: - case ty_class: - case ty_alias: - break; - } - } + } } static string @@ -226,9 +120,33 @@ get_object_key (void *obj, void *unused) return [(id)obj name]; } +void +usage (string name) +{ + printf ("%s [struct|enum] [output file]\n", name); +} + int main(int argc, string *argv) { + int do_struct = 0; + int do_enum = 0; + + if (argc != 3) { + usage (argv[0]); + return 1; + } + switch (argv[1]) { + case "struct": + do_struct = 1; + break; + case "enum": + do_enum = 1; + break; + default: + usage (argv[0]); + return 1; + } encodings = PR_FindGlobal (".type_encodings"); if (!encodings) { printf ("Can't find encodings\n"); @@ -243,6 +161,8 @@ main(int argc, string *argv) for (int i = 0; i < sizeof (search_names) / sizeof (search_names[0]); i++) { id obj = (id) Hash_Find (available_types, search_names[i]); + obj = [obj resolveType]; + printf("obj: %d %s\n", obj, class_get_class_name([obj class])); if (obj && [obj class] == [Struct class]) { [obj addToQueue]; } @@ -261,13 +181,17 @@ main(int argc, string *argv) printf ("vkgen %d %s\n", i, argv[i]); } - output_file = Qopen (argv[1], "wt"); + output_file = Qopen (argv[2], "wt"); for (int i = [output_types count]; i-- > 0; ) { id obj = [output_types objectAtIndex:i]; if ([obj name] == "VkStructureType") { continue; } - if ([obj class] == [Struct class]) { + printf("obj: %d %s\n", obj, class_get_class_name([obj class])); + if (do_struct && [obj class] != [Struct class]) { + continue; + } + if (do_enum && [obj class] != [Enum class]) { continue; } [obj writeTable]; diff --git a/libs/video/renderer/vulkan/vkgen/vkstruct.r b/libs/video/renderer/vulkan/vkgen/vkstruct.r index fa5193b11..939f9094e 100644 --- a/libs/video/renderer/vulkan/vkgen/vkstruct.r +++ b/libs/video/renderer/vulkan/vkgen/vkstruct.r @@ -15,6 +15,16 @@ return str_mid(type.strct.tag, 4); } +-(void) addToQueue +{ + string name = [self name]; + if (!Hash_Find (processed_types, name)) { + printf (" +%s\n", name); + Hash_Add (processed_types, (void *) name); + [queue addObject: self]; + } +} + -(void) forEachFieldCall: (varfunc) func { qfot_struct_t *strct =&type.strct; diff --git a/libs/video/renderer/vulkan/vkgen/vktype.h b/libs/video/renderer/vulkan/vkgen/vktype.h index a4ffb83c4..834bd1896 100644 --- a/libs/video/renderer/vulkan/vkgen/vktype.h +++ b/libs/video/renderer/vulkan/vkgen/vktype.h @@ -8,11 +8,16 @@ { qfot_type_t *type; } --initWithType: (qfot_type_t *) type; ++fromType: (qfot_type_t *) type; +/** \warning returned string is ephemeral +*/ +-(string) key; /** \warning returned string is ephemeral */ -(string) name; -(void) addToQueue; +-(Type *) resolveType; ++(Type *) findType: (qfot_type_t *) type; @end #endif//__renderer_vulkan_vkgen_vktype_h diff --git a/libs/video/renderer/vulkan/vkgen/vktype.r b/libs/video/renderer/vulkan/vkgen/vktype.r index b3a7bcf2c..c5a678c48 100644 --- a/libs/video/renderer/vulkan/vkgen/vktype.r +++ b/libs/video/renderer/vulkan/vkgen/vktype.r @@ -1,19 +1,72 @@ #include +#include "vkalias.h" +#include "vkenum.h" #include "vkgen.h" +#include "vkstruct.h" #include "vktype.h" @implementation Type +static hashtab_t *registered_types; + +static string get_type_key (void *type, void *unused) +{ + return ((Type *) type).type.encoding; +} + ++(void)initialize +{ + registered_types = Hash_NewTable (127, get_type_key, nil, nil); +} + -initWithType: (qfot_type_t *) type { if (!(self = [super init])) { return nil; } self.type = type; + Hash_Add (registered_types, self); return self; } ++(Type *) findType: (qfot_type_t *) type +{ + if (type.meta == ty_alias && !type.alias.name) { + type = type.alias.full_type; + } + return (Type *) Hash_Find (registered_types, type.encoding); +} + ++fromType: (qfot_type_t *) type +{ + if (type.size == 0) { + return nil; + } + switch (type.meta) { + case ty_basic: + case ty_array: + case ty_class: + return [[Type alloc] initWithType: type]; + case ty_enum: + return [[Enum alloc] initWithType: type]; + case ty_struct: + case ty_union: + return [[Struct alloc] initWithType: type]; + case ty_alias: + if (type.alias.name) { + return [[Alias alloc] initWithType: type]; + } + break; + } + return nil; +} + +-(string) key +{ + return type.encoding; +} + -(string) name { //FIXME extract alias name and return proper type name @@ -23,11 +76,14 @@ -(void) addToQueue { string name = [self name]; - //printf (" +%s\n", name); - if (!Hash_Find (processed_types, name)) { - Hash_Add (processed_types, (void *) name); - [queue addObject: self]; + if (type.meta == ty_basic && type.type == ev_pointer) { + [[Type findType: type.fldptr.aux_type] addToQueue]; } } +-(Type *) resolveType +{ + return self; +} + @end