Now includes aliases for constants. Fixes some issues with the vulkan 1.3 registry.
authorNot Zed <notzed@gmail.com>
Sun, 8 May 2022 13:22:28 +0000 (22:52 +0930)
committerNot Zed <notzed@gmail.com>
Sun, 8 May 2022 13:25:48 +0000 (22:55 +0930)
src/notzed.vulkan/gen/generate-vulkan
src/notzed.vulkan/gen/vulkan.pm

index 02edd41..8a2a4c3 100755 (executable)
@@ -62,7 +62,7 @@ $sys->{verbose} = 0;
 my $vk = new vulkan($sys);
 
 my $api = $vk->buildFeatures(
-       [ 'VK_VERSION_1_0', 'VK_VERSION_1_1', 'VK_VERSION_1_2' ],
+       [ 'VK_VERSION_1_0', 'VK_VERSION_1_1', 'VK_VERSION_1_2', 'VK_VERSION_1_3' ],
        [ 'xlib',
          #'wayland',
          'xcb' ]);
@@ -211,7 +211,6 @@ foreach my $s (values %{$api->{commands}}) {
        my $templates = $structTypes->{templates};
 
        foreach my $k (keys %defaultTemplate) {
-               print "what?: ".Dumper($overrides->{$k}->{template}) if defined($overrides->{$k}) && defined($overrides->{$k}->{template});
                next if defined($overrides->{$k}) && defined($overrides->{$k}->{template});
 
                my $t = $defaultTemplate{$k};
@@ -240,7 +239,8 @@ if (0) {
        open(my $f, '>', 'api.pm');
        print $f Dumper($api);
        close $f;
-       die;
+       print "Dumped api.pm\n";
+       exit 1;
 }
 
 if (0) {
@@ -614,6 +614,9 @@ sub exportVulkan {
                push @constants, "";
                push @constants, "// $s->{name} $type";
 
+               my $index = {};
+               map { $index->{$_->{name}} = $_ } (@{$s->{items}});
+
                foreach my $m (@{$s->{items}}) {
                        next if defined($m->{alias});
                        next if $seen->{$m->{name}}++;
@@ -625,6 +628,13 @@ sub exportVulkan {
                        die Dumper("Ca't work out value", $m, $s) if !defined($v);
                        push @constants, "public final static $i->{type} $m->{name} = $v$i->{suffix};";
                }
+               foreach my $m (@{$s->{items}}) {
+                       next if !defined($m->{alias});
+                       next if $seen->{$m->{name}}++;
+                       next if !defined($index->{$m->{alias}});
+
+                       push @constants, "public final static $i->{type} $m->{name} = $m->{alias};";
+               }
        }
 
        my $v = {
@@ -733,7 +743,7 @@ sub analyseFields {
                                $m->{baseType} = $t->{name};
                        }
 
-                       if ($t->{category} =~ m/enum|bitmask/on) {
+                       if ($t->{category} eq 'enum') {
                                $t = $vk->{data}->{$t->{fullType}};
                                $type = $t->{type} if ($nstar == 0);
                                $type = "$t->{type}*" if ($nstar == 1);
@@ -903,7 +913,7 @@ sub analyseTypes {
        map { $base->{$_} = 1 } values %$seen;
 
        foreach my $k (sort keys %$base) {
-               print "$k\n";
+               print " $k\n";
        }
 }
 
index e405e8e..fe85338 100644 (file)
@@ -59,6 +59,25 @@ sub new {
                }
        }
 
+       # Link up bitmask base types
+       foreach my $s (grep { $_->{category} eq 'enum' } values %{$data}) {
+               if ($s->{requires}) {
+                       my $t = $data->{$s->{requires}};
+                       die Dumper($s) if !defined $t;
+                       die Dumper($s) if !defined $s->{fullType};
+                       $t->{uses} = $s;
+                       $t->{fullType} = $s->{fullType};
+               } elsif ($s->{bitvalues}) {
+                       my $t = $data->{$s->{bitvalues}};
+                       die Dumper($s) if !defined $t;
+                       die Dumper($s) if !defined $s->{fullType};
+                       $t->{uses} = $s;
+                       $t->{fullType} = $s->{fullType};
+               } elsif (!defined $s->{fullType}) {
+                       $s->{fullType} = 'VkFlags';
+               }
+       }
+
        $self;
 }
 
@@ -70,19 +89,24 @@ sub buildRequirement {
        my $outconst = $data->{'API Constants'};
        my $allconst = $vk->{data}->{'API Constants'};
 
-       # add a couple of constants that the api's dont reference
-       push @{$outconst->{items}}, grep { $_->{name} =~ m/VK_UUID_SIZE/ } @{$allconst->{items}};
-
        # Find included types in this requirement
        foreach my $c (@{$req->{commands}}, @{$req->{types}}) {
                my $d = $vk->{data}->{$c};
 
                if (defined $d) {
-                       if ($d->{category} eq 'enum' && !defined($d->{alias})) {
+                       # for format change?
+                       if ($d->{category} eq 'enum') {
+                               # Copy all aliases across to data
+                               while ($d->{alias}) {
+                                       $data->{$d->{name}} = $d;
+                                       $d = $vk->{data}->{$d->{alias}};
+                               }
                                $d = { %$d };
                                $d->{items} = [ @{$d->{items}} ] if defined($d->{items});
+                               $data->{$d->{name}} = $d;
+                       } else {
+                               $data->{$d->{name}} = $d;
                        }
-                       $data->{$c} = $d;
                } else {
                        $data->{$c} = {
                                name => $c,
@@ -114,18 +138,34 @@ sub buildRequirement {
                        push @{$d->{items}}, $c;
                } elsif ($c->{value}) {
                        if ($c->{value} =~ m/^"/) {
-                               push @{$outconst->{items}}, { %$c, type=>'const char *' };
+                               if (!defined $outconst->{index}->{$c->{name}}) {
+                                       my $v = { %$c, type=>'const char *' };
+                                       push @{$outconst->{items}}, $v;
+                                       $outconst->{index}->{$v->{name}} = $v;
+                               }
                        } else {
-                               push @{$outconst->{items}}, { %$c, type=>'uint32_t' };
+                               if (!defined $outconst->{index}->{$c->{name}}) {
+                                       my $v = { %$c, type=>'uint32_t' };
+                                       push @{$outconst->{items}}, $v;
+                                       $outconst->{index}->{$v->{name}} = $v;
+                               }
                        }
                } elsif (!$c->{alias}) {
-                       my @list = grep { $_->{name} eq $c->{name} } @{$allconst->{items}};
-                       die "Can't find constant '$c->{name}'".Dumper($c) if ($#list < 0);
-                       push @{$outconst->{items}}, @list;
+                       if (!defined $outconst->{index}->{$c->{name}}) {
+                               my $v = $allconst->{index}->{$c->{name}};
+
+                               die Dumper($c) if !defined $v;
+
+                               push @{$outconst->{items}}, $v;
+                               $outconst->{index}->{$c->{name}} = $v;
+                       }
                }
        }
 }
 
+# Ideally this builds a 'view' of the features
+# But it doesn't work properly if something is promoted and uses new names
+
 sub buildFeatures {
        my $vk = shift;
        my $vers = shift;
@@ -140,10 +180,20 @@ sub buildFeatures {
        #print Dumper($vk->{features});
 
        $data->{'API Constants'} = {
+               name => 'API Constants',
                category => 'define',
                items => [],
+               index => {},
        };
 
+       # add constants that the api's dont reference (only 1 so far)
+       my $outconst = $data->{'API Constants'};
+       my $allconst = $vk->{data}->{'API Constants'};
+       foreach my $v (map {$allconst->{index}->{$_}} qw(VK_UUID_SIZE)) {
+               push @{$outconst->{items}}, $v;
+               $outconst->{index}->{$v->{name}} = $v;
+       }
+
        foreach my $feature (grep { $versions->{$_->{name}} } @{$vk->{features}}) {
                print "Feature $feature->{name}\n" if ($vk->{sys}->{verbose});
                foreach my $req (@{$feature->{require}}) {
@@ -168,7 +218,6 @@ sub buildFeatures {
        my $types = {};
        my $commands = {};
        my $enums = {};
-       my $bitmasks = {};
        my $funcpointers = {};
        my $defines = {};
 
@@ -178,38 +227,18 @@ sub buildFeatures {
                $types->{$v->{name}} = $v if $v->{category} =~ m/struct|union/on;
                $commands->{$v->{name}} = $v if $v->{category} eq 'command';
                $enums->{$v->{name}} = $v if $v->{category} eq 'enum';
-               $bitmasks->{$v->{name}} = $v if $v->{category} eq 'bitmask';
                $funcpointers->{$v->{name}} = $v if $v->{category} eq 'funcpointer';
                $defines->{$v->{name}} = $v if $v->{category} eq 'define';
        }
 
-       # link enums to their type(s)
-       foreach my $s (values %$bitmasks) {
-               my $t;
+       if (1) {
+               open(my $f, '>', 'features.pm');
+               print $f Dumper($data);
+               close $f;
 
-               if ($s->{requires}) {
-                       $t = $data->{$s->{requires}};
-                       while ($t && $t->{alias}) {
-                               $t = $data->{$t->{alias}};
-                       }
-                       die if !defined($t);
-                       $t->{uses} = $s;
-                       $t->{fullType} = $s->{baseType};
-               } elsif ($s->{name} =~ m/(.*)Flags([0-9A-Z]*)/o && defined $data->{"$1FlagBits$2"}) {
-                       print "> $s->{name} $1FlagBits$2\n";
-                       $t = $data->{"$1FlagBits$2"};
-                       while ($t && $t->{alias}) {
-                               $t = $data->{$t->{alias}};
-                       }
-                       die if !defined($t);
-                       $t->{uses} = $s;
-                       $t->{fullType} = $s->{baseType};
-               } else {
-                       $t->{fullType} = 'VkFlags';
-               }
-       }
-       foreach my $s (values %$enums) {
-               $s->{fullType} = 'VkFlags' if !defined $s->{fullType};
+               open(my $f, '>', 'vk.pm');
+               print $f Dumper($vk);
+               close $f;
        }
 
        my $api = {
@@ -219,7 +248,6 @@ sub buildFeatures {
                commands => $commands,
                funcpointers => $funcpointers,
                enums => $enums,
-               bitmasks => $bitmasks,
                defines => $defines,
        };
 
@@ -458,10 +486,12 @@ sub loadRegistry {
                                                $s->{name} = $info->{name};
                                                $s->{type} = $info->{baseType} if defined $info->{baseType};
 
+                                               $s->{category} = 'enum' if $s->{category} eq 'bitmask';
                                                analyseFunctionPointer($s) if ($s->{category} eq 'funcpointer');
 
                                                $data->{$s->{name}} = $s;
                                        } else {
+                                               $ya->{category} = 'enum' if $ya->{category} eq 'bitmask';
                                                $alias->{$ya->{name}} = $ya->{alias};
                                                $data->{$ya->{name}} = $ya;
                                        }
@@ -477,11 +507,11 @@ sub loadRegistry {
                        }
                } elsif ($xt eq 'enums') {
                        if ($xa->{type} =~ m/enum|bitmask/o) {
+                               #print "enum: $xa->{name}\n";
                                # these are forward referenced from <types> block so re-use, or just overwrite?
                                my $e = $data->{$xa->{name}};
 
-                               $e = { category => "enum", name => $xa->{name} } if (!defined($e));
-
+                               $e = { %{$xa}, category => "enum" } if (!defined($e));
                                $e->{items} = [];
 
                                while ($#{$xn} >= 0) {
@@ -497,7 +527,7 @@ sub loadRegistry {
                                        push @{$e->{items}}, $ya;
                                }
 
-                               $data->{$xa->{name}} = $e;
+                               $data->{$e->{name}} = $e;
                        } elsif ($xa->{name} eq 'API Constants') {
                                my $d = { category => "define", name => $xa->{name}, items =>[], index=>{} };