Changed sType init logic and implement it for arrays.
authorNot Zed <notzed@gmail.com>
Fri, 29 Apr 2022 04:16:47 +0000 (13:46 +0930)
committerNot Zed <notzed@gmail.com>
Fri, 29 Apr 2022 04:16:47 +0000 (13:46 +0930)
Implement accessor for embedded handle[].
General cleanup.

src/notzed.vulkan.test/classes/vulkan/test/TestCube.java
src/notzed.vulkan.test/classes/vulkan/test/TestMandelbrot.java
src/notzed.vulkan/gen/command-types.api
src/notzed.vulkan/gen/generate-vulkan
src/notzed.vulkan/gen/struct-types.api
src/notzed.vulkan/gen/vulkan.pm

index 5fce884..60a1274 100644 (file)
@@ -543,7 +543,7 @@ public class TestCube {
                                uniformInfo,
                                null);
 
-                       device.vkUpdateDescriptorSets(writes, null);
+                       device.vkUpdateDescriptorSets(1, writes, 0, null);
                }
        }
 
@@ -785,7 +785,7 @@ public class TestCube {
                                null,
                                0);
 
-                       res = device.vkCreateGraphicsPipelines(null, pipeline, this.pipeline);
+                       res = device.vkCreateGraphicsPipelines(null, 1, pipeline, this.pipeline);
 
                        VkSemaphoreCreateInfo seminfo = VkSemaphoreCreateInfo.create(frame, 0);
                        chainSemaphore = device.vkCreateSemaphore(seminfo, scope);
@@ -831,10 +831,10 @@ public class TestCube {
                                cmd,
                                null);
 
-                       graphics_queue.vkQueueSubmit(submit_info, drawFence);
+                       graphics_queue.vkQueueSubmit(1, submit_info, drawFence);
 
                        do {
-                               res = device.vkWaitForFences(fences, 1, FENCE_TIMEOUT);
+                               res = device.vkWaitForFences(1, fences, 1, FENCE_TIMEOUT);
                        } while (res == VK_TIMEOUT);
 
                        device.vkDestroyFence(fences.getAtIndex(0));
@@ -923,13 +923,13 @@ public class TestCube {
                        fences.setAtIndex(0, drawFence);
 
                        // Queue the command buffer for execution
-                       device.vkResetFences(fences);
+                       device.vkResetFences(1, fences);
 
-                       graphics_queue.vkQueueSubmit(submit_info, drawFence);
+                       graphics_queue.vkQueueSubmit(1, submit_info, drawFence);
 
                        // Make sure command buffer is finished before presenting
                        do {
-                               res = device.vkWaitForFences(fences, VK_TRUE, FENCE_TIMEOUT);
+                               res = device.vkWaitForFences(1, fences, VK_TRUE, FENCE_TIMEOUT);
                        } while (res == VK_TIMEOUT);
 
                        // Now present the image in the window
index 5f5f5c0..323b1e6 100755 (executable)
@@ -303,7 +303,7 @@ public class TestMandelbrot {
 
                        System.out.println(writeSet);
 
-                       device.vkUpdateDescriptorSets(writeSet, null);
+                       device.vkUpdateDescriptorSets(1, writeSet, 0, null);
                }
        }
 
@@ -345,7 +345,7 @@ public class TestMandelbrot {
                        stage.setModule(mandelbrotShader);
                        stage.setName(mandelbrot_entry, frame);
 
-                       device.vkCreateComputePipelines(null, pipeline, computePipeline);
+                       device.vkCreateComputePipelines(null, 1, pipeline, computePipeline);
                }
        }
 
@@ -409,12 +409,12 @@ public class TestMandelbrot {
                        fences.set(0, fence);
 
                        /* Await completion */
-                       computeQueue.vkQueueSubmit(submitInfo, fence);
+                       computeQueue.vkQueueSubmit(1, submitInfo, fence);
 
                        int VK_TRUE = 1;
                        int res;
                        do {
-                               res = device.vkWaitForFences(fences, VK_TRUE, 1000000);
+                               res = device.vkWaitForFences(1, fences, VK_TRUE, 1000000);
                        } while (res == VK_TIMEOUT);
 
                        device.vkDestroyFence(fence);
index c651800..2a07c65 100644 (file)
@@ -183,6 +183,20 @@ code funcpointer-readwrite insert=funcpointer:common,funcpointer:upcall,funcpoin
 
 # ###################################################################### #
 
+# values required
+
+#  java-arg                    java parameter type and and name
+#  invoke-arg          native value for invokeExact argument
+#  native-arg          native parameter type and name
+#  trampoline-arg      java value for upcall invocation
+#  layout                      MemoryLayout
+#  sig                         JNI signature string
+
+# parameterisation values
+#  type                                java type
+#  carrier                     native (jdk.foriegn) type
+#  length                      array length
+
 type value {
        java-arg        {{ {type} {name} }}
        invoke-arg      {{ {name} }}
@@ -247,12 +261,12 @@ type double value {
 
 # ###################################################################### #
 # implied length types
-type uint64_t-length,size_t-length uint64_t {
+type uint64_t-implied,size_t-implied uint64_t {
        java-arg        {{ }}
        invoke-arg      {{ Memory.length({lengthfor}) }}
 }
 
-type uint32_t-length uint32_t {
+type uint32_t-implied uint32_t {
        java-arg        {{ }}
        invoke-arg      {{ (int)Memory.length({lengthfor}) }}
 }
@@ -347,8 +361,7 @@ type pointer-length pointer {
 }
 
 type void*-length pointer-length {
-       type            MemorySegment;
-       java-get        {{ MemorySegment.ofAddress({native-get}, {length}, this.segment.scope()) }}
+       type    MemorySegment;
 }
 
 type uint8_t*-length pointer-length {
@@ -652,21 +665,11 @@ type vkMapMemory-output void**-output {
 
 # some tweaks that the auto-discovery code misses/isn't worth adding to
 override commands {
-       vkGetPhysicalDeviceQueueFamilyProperties template=method-query
-               physicalDevice=type:instance
-               pQueueFamilyPropertyCount=type:uint32_t*-querylen
-               pQueueFamilyProperties=type:struct*-length-query;
-
        vkAllocateCommandBuffers device=type:instance pCommandBuffers=type:VkCommandBuffer-alloc;
        vkAllocateDescriptorSets device=type:instance pDescriptorSets=type:VkDescriptorSet-alloc;
 
        vkMapMemory device=type:instance ppData=type:vkMapMemory-output;
 
-       # forces ignoring of lengths, maybe need to do it for all vkCmd
-       #vkCmdSetScissor commandBuffer=type:instance;
-       #vkCmdSetViewport commandBuffer=type:instance;
-       #vkCmdBindDescriptorSets commandBuffer=type:instance;
-
        # Don't need userData
        PFN_vkDebugUtilsMessengerCallbackEXT pUserData=type:void*-ignore;
        PFN_vkDebugReportCallbackEXT pUserData=type:void*-ignore;
index fd859ad..e1c7d1a 100755 (executable)
@@ -58,7 +58,16 @@ my $commandTypes = loadTypes($api, 'command-types.api');
 
 analyseTypes($vk, $api);
 
-# for structs
+# Use some heuristics to create overrides for improving the api
+
+# - object constructor functions return values rather take pointer* values
+# - array query functions perform the query and return the array
+# - extension functions use a different invocation mechanism
+# - drop any 'ignore' types from argument lists
+
+# - [attempt to] determine which types need to be read/write/arrays
+
+# Scan structs
 my %defaultTemplate;
 
 foreach my $s (values %{$api->{types}}) {
@@ -73,14 +82,13 @@ foreach my $s (values %{$api->{types}}) {
        foreach my $m (@{$s->{items}}) {
                my $nstar = $m->{deref} =~ tr/*/*/;
 
-               # FIXME: this belongs in analyse
-               if ($m->{lengthfrom} && $lengths{$m->{lengthfrom}} != 1) {
-                       $m->{'set-length'} = '';
-               }
-
                if ($m->{lengthfor} && $nstar == 0 && $lengths{$m->{name}} == 1) {
-                       $overrides->{$s->{name}}->{$m->{name}}->{type} = $m->{deref}.'-implied';
+                       die "No type '$m->{deref}-implied'" if !defined($types->{"$m->{deref}-implied"});
+
+                       $overrides->{$s->{name}}->{$m->{name}}->{type} = "$m->{deref}-implied";
+                       print "implied: $s->{name} $m->{name} $m->{deref} $s->{index}->{$m->{lengthfor}}->{deref}\n" if $sys->{verbose};
                }
+
                if ($m->{deref} eq 'struct*-length') {
                        $defaultTemplate{$m->{baseType}}->{array} = 1;
                } elsif ($m->{deref} eq 'struct[]') {
@@ -88,20 +96,23 @@ foreach my $s (values %{$api->{types}}) {
                }
        }
 
-       if ($s->{returnedonly} eq 'true') {
-               $defaultTemplate{$s->{name}}->{name} = 'struct-readonly';
-       }
+       $defaultTemplate{$s->{name}}->{name} = 'struct-readonly' if ($s->{returnedonly} eq 'true');
 }
 
 # build default overrides for commands
 foreach my $s (values %{$api->{commands}}) {
        my $overrides = $commandTypes->{overrides};
        my $types = $commandTypes->{types};
+       my $first = $s->{items}->[0];
+       my $last = $s->{items}->[$#{$s->{items}}];
+       my $llast = $s->{items}->[$#{$s->{items}}-1];
+       my $result = $s->{proto};
+       my $index = $s->{index};
 
        # check type updates anyway
        foreach my $m (@{$s->{items}}) {
                if ($m->{deref} eq 'struct*-length') {
-                       $defaultTemplate{$m->{baseType}}->{name} = 'struct-readwrite' if !($m->{fullType} =~ m/const/n);
+                       $defaultTemplate{$m->{baseType}}->{name} = 'struct-readwrite' if !($m->{fullType} =~ m/const/n) && $api->{types}->{$m->{baseType}}->{returnedonly} ne 'true';
                        $defaultTemplate{$m->{baseType}}->{array} = 1;
                } elsif ($m->{deref} eq 'struct*') {
                        $defaultTemplate{$m->{baseType}}->{name} = 'struct-readwrite' if !($m->{fullType} =~ m/const/n);
@@ -110,13 +121,6 @@ foreach my $s (values %{$api->{commands}}) {
 
        next if (defined($overrides->{$s->{name}}));
 
-       my $first = $s->{items}->[0];
-       my $last = $s->{items}->[$#{$s->{items}}];
-       my $result = $s->{proto};
-       my $index = $s->{index};
-
-       #map { $index->{$_->{name}} = $_ } @{$s->{items}};
-
        my $override = {};
 
        # force handles to be instance types
@@ -124,11 +128,12 @@ foreach my $s (values %{$api->{commands}}) {
                $override->{$first->{name}}->{type} = 'instance';
        }
 
-       # extension functions
+       # extension function default template
        if (defined($s->{extensions})) {
-               $override->{template} = $commandTypes->{templates}->{'method-extension'};
+               $override->{template} = 'method-extension';
        }
 
+       # Constructor
        if ($last->{deref} eq 'handle*') {
                if (!$last->{len}) {
                        my $t = $api->{handles}->{$last->{baseType}};
@@ -144,43 +149,30 @@ foreach my $s (values %{$api->{commands}}) {
                }
        }
 
+       # turn array-query functions into auto-allocate/return types
        # ones we care about with output
        #       handle*-length
        #       struct*-length
        #       uint32_t*-length
        #       void*-length
 
-       if ($s->{successcodes} =~ m/VK_INCOMPLETE/ && $last->{deref} =~ m/-length$/) {
-               my $protoa = "$result->{fullType} $s->{name}("
-                       .join(', ', map { "$_->{fullType}" } @{$s->{items}})
-                       .")";
-               my $protob = "$result->{deref} $s->{name}("
-                       .join(', ', map { $_->{len} ? "$_->{deref} \[$_->{len}\]" : $_->{deref} } @{$s->{items}})
-                       .")";
-
-               print "array-constructor: $protoa\n" if $sys->{verbose} > 1;
-               print "array-constructor: $protob\n" if $sys->{verbose} > 1;
-
-               $override->{template} =
-                       defined($s->{extensions}) ?
-                       $commandTypes->{templates}->{'method-extension-query'} :
-                       $commandTypes->{templates}->{'method-query'};
-               foreach my $m (@{$s->{items}}) {
-                       if ($m->{deref} =~ m/-length$/ && (my $len = $index->{$m->{len}})) {
-                               my $type;
+       if ($last->{deref} =~ m/-length$/ && (my $len = $index->{$last->{len}})) {
+               if (index($len->{deref}, '*') >= 0) {
+                       my $protoa = "$result->{fullType} $s->{name}("
+                               .join(', ', map { "$_->{fullType}" } @{$s->{items}})
+                               .")";
+                       print "array-constructor: $protoa\n" if $sys->{verbose} > 1;
 
-                               if ($m->{deref} eq 'handle*-length' && $api->{handles}->{$last->{baseType}}->{type} eq 'VK_DEFINE_HANDLE') {
-                                       $type = 'dispatch*-length-query';
-                               } else {
-                                       $type = $m->{deref}.'-query';
-                               }
+                       my $otype = ($last->{deref} eq 'handle*-length' && $api->{handles}->{$last->{baseType}}->{type} eq 'VK_DEFINE_HANDLE')
+                               ? 'dispatch*-length-query' : $last->{deref}.'-query';
+                       my $ltype = $len->{deref}.'-querylen';
 
-                               die "no template $m->{deref}-query" if !defined($commandTypes->{types}->{$type});
-                               $override->{$m->{name}}->{type} = $type;
+                       die "no template $otype" if !defined($commandTypes->{types}->{$otype});
+                       die "no template $ltype" if !defined($commandTypes->{types}->{$ltype});
 
-                               die "no template $len->{deref}-querysize" if !defined($commandTypes->{types}->{$len->{deref}.'-querylen'});
-                               $override->{$len->{name}}->{type} = $len->{deref}.'-querylen';
-                       }
+                       $override->{template} = defined($s->{extensions}) ? 'method-extension-query' : 'method-query';
+                       $override->{$last->{name}}->{type} = $otype;
+                       $override->{$len->{name}}->{type} = $ltype;
                }
        }
 
@@ -189,30 +181,8 @@ foreach my $s (values %{$api->{commands}}) {
                my $so = $structTypes->{overrides}->{$m->{baseType}};
 
                if ($so->{ignore}) {
-                       $m->{deref} .= '-ignore';
-               }
-
-               # All the vkCmd commands shouldn't imply any array lengths, maybe nothing should really?
-               if ($first->{baseType} ne 'VkCommandBuffer' && $m->{lengthfor}) {
-                       my $nstar = $m->{deref} =~ tr/*/*/;
-                       if ($nstar == 0) {
-                               die "No '$m->{deref}-length' type ".Dumper($s) if !defined $types->{$m->{deref}.'-length'};
-                               $override->{$m->{name}}->{type} = $m->{deref}.'-length';
-                       } else {
-                               if (defined($s->{extensions})) {
-                                       #$overrides->{$s->{name}}->{template} = $commandTypes->{templates}->{'method-extension'};
-                                       print "length-extension: $m->{deref} $s->{name} $m->{name} $m->{lengthfor}\n" if $sys->{verbose};
-                               } else {
-                                       #die "No '$m->{deref}-output' type ".Dumper($s) if !defined $types->{$m->{deref}.'-otuput'};
-
-                                       #$overrides->{$s->{name}}->{template} = $commandTypes->{templates}->{'method-query'};
-                                       #$overrides->{$s->{name}}->{$m->{name}}->{type} = $types->{$m->{deref}.'-output'};
-
-                                       print "length: $m->{deref} $s->{name} $m->{name} $m->{lengthfor}\n" if $sys->{verbose};
-                               }
-
-                       }
-                       # TODO: implied return things
+                       die "No type '$m->{deref}-ignore'" if !defined($types->{$m->{deref}.'-ignore'});
+                       $override->{$m->{name}}->{type} = $m->{deref}.'-ignore';
                }
        }
 
@@ -234,16 +204,10 @@ foreach my $s (values %{$api->{commands}}) {
 
                print "$name: $k\n" if $sys->{verbose} > 1;
                die "No override $k $name" if !$templates->{$name};
-               $overrides->{$k}->{template} = $templates->{$name};
+               $overrides->{$k}->{template} = $name;
        }
 }
 
-
-#$overrides->{$s->{name}}->{template} = $structTypes->{templates}->{'struct-readonly'};
-
-#print Dumper({ types=>$types, templates=>$templates });
-#print Dumper($vk);
-
 if (0) {
        open(my $f, '>', 'types.pm');
        print $f Dumper($commandTypes, $structTypes);
@@ -257,20 +221,9 @@ if (0) {
        die;
 }
 
-if (0) {
-       open(my $f, '>', 'data.pm');
-       print $f Dumper({
-               'handles' => $api->{handles},
-                       'types' => $api->{types},
-                       'commands' => $api->{commands},
-                       'funcpointers' => $api->{funcpointers},
-                                       });
-       close $f;
-}
-
 exportEnums($vk, $api, 'VkConstants');
 
-# dump out the extension function tables
+# dump out the extension function-pointer tables
 {
        my $f = openOutput($sys, 'DispatchInstance');
        my $template = $structTypes->{templates}->{dispatch};
@@ -386,14 +339,15 @@ sub loadTypes {
 
                        # Load the fields
                        foreach my $s (@{$t->{items}}) {
-                               # FIXME: maybe i don't want  struct here, as with templates
-                               my $x = {
-                                       code => defined($s->{literal}) ? $s->{literal} : $s->{options}->[$#{$s->{options}}]
-                               };
-
-                               $x->{eval} = 1 if config::optionFlag('eval', $s);
+                               if (defined $s->{literal}) {
+                                       $type->{$s->{match}} = $s->{literal};
+                               } elsif ($#{$s->{options}} >= 0) {
+                                       $type->{$s->{match}} = $s->{options}->[$#{$s->{options}}];
+                               } else {
+                                       $type->{$s->{match}} = 0;
+                               }
 
-                               $type->{$s->{match}} = $x;
+                               $type->{"$s->{match}:eval"} = 1 if config::optionFlag('eval', $s);
                        }
 
                        # Write to all aliases
@@ -407,25 +361,32 @@ sub loadTypes {
 
                        foreach my $o (@{$t->{options}}) {
                                if ($o =~ m/insert=(.*)/) {
-                                       foreach my $t (split /,/,$1) {
-                                               if ($t =~ m/(.*):(.*)/) {
-                                                       die if !defined $templates->{$1}->{$2};
+                                       foreach my $x (split /,/,$1) {
+                                               if ($x =~ m/(.*):(.*)/) {
+                                                       die "$x $t->{name} ".Dumper($templates->{$1}) if !defined $templates->{$1}->{$2};
                                                        $code->{insert}->{$2} = $templates->{$1}->{$2};
                                                }
                                        }
                                } elsif ($o =~ m/^fields=(.*)/) {
                                        $code->{fields} = $1;
+                               } elsif (defined($templates->{$o})) {
+                                       $code = { %$code, %{$templates->{$o}} };
                                } else {
-                                       die ("Unknown option $o");
+                                       die ("Unknown option '$o'");
                                }
                        }
 
                        foreach my $s (@{$t->{items}}) {
-                               $code->{$s->{match}} = $s->{literal};
-                               $code->{$s->{match}} =~ s/^\t//gm;
+                               if (defined  $s->{literal}) {
+                                       my $t = $s->{literal};
+
+                                       $t =~ s/^\t//gm;
+                                       $code->{$s->{match}} = $t;
+                               } else {
+                                       delete $code->{$s->{match}};
+                               }
 
-                               # hack since the template is a string
-                               $code->{"$s->{match}:eval"}->{eval} = 1 if config::optionFlag('eval', $s);
+                               $code->{"$s->{match}:eval"} = 1 if config::optionFlag('eval', $s);
                        }
 
                        $templates->{$t->{name}} = $code;
@@ -441,7 +402,7 @@ sub loadTypes {
                                                $c->{$1}->{accessor} = $templates->{$2};
                                        } elsif ($o =~ m/^template=(.*)/) {
                                                die "No template $o" if !defined($templates->{$1});
-                                               $c->{template} = $templates->{$1};
+                                               $c->{template} = $1;
                                        } elsif ($o eq 'ignore') {
                                                $c->{ignore} = 1;
                                        }
@@ -671,7 +632,6 @@ sub analyseFields {
                                                $m->{length} = "get$len->{Name}()";
                                                $m->{lengthfrom} = $len->{name};
                                                $len->{lengthfor} = $m->{name};
-                                               $m->{'set-length'} = "set$len->{Name}((int)Memory.length($m->{name}))";
                                        }
                                } elsif ($m->{len} eq 'null-terminated') {
                                        # ignore
@@ -686,7 +646,6 @@ sub analyseFields {
                                                $m->{length} = "get$len->{Name}()";
                                                $m->{lengthfrom} = $len->{name};
                                                $len->{lengthfor} = $m->{name};
-                                               $m->{'set-length'} = "set$len->{Name}($cast"."Memory.length($m->{name}))";
                                        } else {
                                                die "what?".Dumper($m);
                                        }
@@ -800,17 +759,14 @@ sub buildVars {
        my $type = shift;
        my $v = { %{$m} };
 
-       foreach my $k (keys %$type) {
+       foreach my $k (grep { index($_, ':') == -1 } keys %$type) {
                my $t = $type->{$k};
 
-               if (ref($t) eq '') {
+               if ($type->{"$k:eval"}) {
                        $v->{$k} = $t;
-               } elsif ($t->{eval}) {
-                       $v->{$k} = eval $t->{code};
-
                        die "Eval failed: $! $@: ".Dumper($m, $type) if !defined($v->{$k});
-               } elsif (defined($t->{code})) {
-                       $v->{$k} = $t->{code};
+               } elsif ($t) {
+                       $v->{$k} = $t;
                }
        }
 
@@ -891,7 +847,8 @@ sub formatStruct {
        my $overrides = $structTypes->{overrides};
 
        my $override = $overrides->{$s->{name}};
-       my $template = $override->{template} ? $override->{template} : $templates->{'struct-writeonly'};
+       my $tempname = $override->{template} ? $override->{template} : 'struct-writeonly';
+       my $template = $templates->{$tempname};
        my @fields = split(/,/, $template->{fields});
        my $info;
 
@@ -899,6 +856,7 @@ sub formatStruct {
 
        my $setall = defined $info->{'java-setall'};
 
+       # unions need multiple constructors
        if ($setall) {
                if ($s->{category} eq 'struct') {
                        $info->{create}->{create} = {
@@ -917,10 +875,7 @@ sub formatStruct {
                }
        }
 
-       #map { $_->{typeInfo} = buildVars($s, $_, $types->{$_->{deref}}) } @{$s->{items}};
-
-       # FIXME: unions need multiple constructors!
-
+       # Collect all fields
        foreach my $m (@{$s->{items}}) {
                my $nstar = $m->{deref} =~ tr/*/*/;
                my $deref = defined($override->{$m->{name}}) && defined($override->{$m->{name}}->{type}) ? $override->{$m->{name}}->{type} : $m->{deref};
@@ -933,15 +888,12 @@ sub formatStruct {
                        my @todump;
 
                        if ($m->{values}) {
-                               @todump = qw(init initat set setat);
+                               @todump = qw(init initat init-array set setat);
                        } else {
                                @todump = qw(get getat set setat getorset getorsetat);
 
-                               # FIXME: something here is adding length parameters which are already handled by the setXX() calls
                                if ($setall && !$m->{'no-setall'}) {
                                        my $create = $s->{category} eq 'struct' ? $info->{create}->{create} : $info->{create}->{"create$m->{Name}"};
-                                       #push @{$create->{setallArgs}}, code::formatTemplate($type->{accessor}->{'setall-arg'}, $v) if $type->{accessor}->{'setall-arg'};
-                                       #push @{$create->{setall}}, code::formatTemplate($type->{accessor}->{setall}, $v) if $type->{accessor}->{setall};
                                        formatAccessorIf($s, $m, $create, $type, 'setall-arg', $v);
                                        formatAccessorIf($s, $m, $create, $type, 'setall', $v);
                                }
@@ -951,7 +903,14 @@ sub formatStruct {
                        push @{$info->{handleat}}, code::formatTemplate($v->{handleat}, $v) if $info->{handleat} && $v->{handleat};
 
                        foreach my $field (@todump) {
-                               push @{$info->{$field}}, code::formatTemplate($type->{accessor}->{$field}, $v) if $info->{$field} && $type->{accessor}->{$field};
+                               if ($info->{$field} && $type->{accessor}->{$field}) {
+                                       my $t = $type->{accessor}->{$field};
+
+                                       $t = eval $t if $type->{accessor}->{"$field:eval"};
+                                       die "$@" if !defined($t);
+
+                                       push @{$info->{$field}}, code::formatTemplate($t, $v);
+                               }
                        }
                }
        }
@@ -962,13 +921,6 @@ sub formatStruct {
                name => $s->{name},
                Name => $s->{Name},
                layout => formatStructLayout($types, $s),
-               #init => join ("\n", @{$info->{init}}),
-               #get => join ("\n", @{$info->{get}}),
-               #set => join ("\n", @{$info->{set}}),
-               #getorset => join ("\n", @{$info->{getorset}}),
-               ##'java-setall-arguments' => join (",", @{$info->{setallArgs}}),
-               ##'java-setall' => join ("\n", @{$info->{setall}}),
-               #varhandle => join ("\n", @{$info->{varhandle}}),
        };
 
        foreach my $field (@fields) {
@@ -1017,7 +969,8 @@ sub formatHandle {
        my $templates = $structTypes->{templates};
        my $overrides = $structTypes->{overrides};
        my $override = $overrides->{$s->{name}};
-       my $template = $override->{template} ? $override->{template} : $templates->{handle};
+       my $tempname = $override->{template} ? $override->{template} : 'handle';
+       my $template = $templates->{$tempname};
 
        my $info = {
                init => [],
@@ -1052,22 +1005,21 @@ sub formatSignature {
 
                die "No sig defined ".Dumper($m) if !defined($x) || !defined($x->{sig});
 
-               $d .= $x->{sig}->{code};
+               $d .= $x->{sig};
        }
        $d .= ')';
 
        my $m = $s->{proto};
        my $x = $types->{$m->{deref}};
        die "No sig defined ".Dumper($m) if !defined($x) || !defined($x->{sig});
-       $d .= $x->{sig}->{code};
+       $d .= $x->{sig};
 }
 
-# TODO: only collect shit we need
+# Forms all the parameter templates
 sub collectFunctionInfo {
        my $api = shift;
        my $ct = shift;
        my $s = shift;
-       my $templates = $ct->{templates};
        my $types = $ct->{types};
        my $overrides = $ct->{overrides};
        my $void = $s->{proto}->{fullType} eq 'void';
@@ -1108,14 +1060,12 @@ sub collectFunctionInfo {
        my $needScope = 0;
        my $trampScope = 0;
 
-       #return if !defined($override->{template});
-       #return if ($s->{name} ne 'vkCmdUpdateBuffer');
-
        my @arrayFields = qw(java-arg invoke-arg native-init query-init query-arg native-arg trampoline-arg);
        my @fixedFields = qw(java-result java-result-return java-result-assign);
 
        map { $info->{$_} = [] } @arrayFields;
 
+       # Calculate parameters
        foreach my $m (@{$s->{items}}) {
                my $deref = defined($override->{$m->{name}}) && defined($override->{$m->{name}}->{type}) ? $override->{$m->{name}}->{type} : $m->{deref};
                my $type = $types->{$deref};
@@ -1136,27 +1086,6 @@ sub collectFunctionInfo {
                        $info->{$field} = code::formatTemplate($v->{$field}, $v) if ($v->{$field});
                }
 
-               if (0) {
-                       push @javaArgs, "/* $m->{name} $m->{deref} */ ".code::formatTemplate($v->{'java-arg'}, $v) if ($v->{'java-arg'});
-                       push @invokeArgs, code::formatTemplate($v->{'invoke-arg'}, $v) if ($v->{'invoke-arg'});
-
-                       push @nativeInit, code::formatTemplate($v->{'native-init'}, $v) if ($v->{'native-init'});
-                       push @queryInit, code::formatTemplate($v->{'query-init'}, $v) if ($v->{'query-init'});
-
-                       if ($v->{'query-arg'}) {
-                               push @queryArgs, code::formatTemplate($v->{'query-arg'}, $v);
-                       } elsif ($v->{'invoke-arg'}) {
-                               push @queryArgs, code::formatTemplate($v->{'invoke-arg'}, $v);
-                       }
-
-                       push @nativeArgs, code::formatTemplate($v->{'native-arg'}, $v) if ($v->{'native-arg'});
-                       push @trampArgs, code::formatTemplate($v->{'trampoline-arg'}, $v) if ($v->{'trampoline-arg'});
-
-                       $info->{'java-result'} = code::formatTemplate($v->{'java-result'}, $v) if ($v->{'java-result'});
-                       $info->{'java-result-return'} = code::formatTemplate($v->{'java-result-return'}, $v) if ($v->{'java-result-return'});
-                       $info->{'java-result-assign'} = code::formatTemplate($v->{'java-result-assign'}, $v) if ($v->{'java-result-assign'});
-               }
-
                $needScope = 1 if $type->{'need-scope'};
                $needFrame = 1 if $type->{'need-frame'};
                $needAlloc = 1 if $type->{'need-alloc'};
@@ -1166,6 +1095,7 @@ sub collectFunctionInfo {
 
        $info->{'static'} = $hasInstance ? '' : 'static ';
 
+       # Handle default return types, others are handled by the fixedFields above
        if ($s->{successcodes}) {
                my @codes = split(/,/,$s->{successcodes});
 
@@ -1178,7 +1108,6 @@ sub collectFunctionInfo {
                        $info->{'java-result'} = 'int';
                        $info->{'java-result-return'} = 'return result$;';
                }
-
        } elsif ($s->{proto}->{fullType} ne 'void') {
                my $m = $s->{proto};
                my $type = defined($override->{$m->{name}}) ? $override->{$m->{name}}->{type} : $types->{$m->{deref}.'-return'};
@@ -1213,17 +1142,6 @@ sub collectFunctionInfo {
                $info->{$field} = join $with, @{$info->{$field}};
        }
 
-       if (0) {
-               $info->{'java-arguments'} = join ",\n\t", @javaArgs;
-               $info->{'native-init'} = join "\n\t", @nativeInit;
-               $info->{'invoke-arguments'} = join ", ", @invokeArgs;
-               $info->{'query-init'} = join "\n\t\t\t", @queryInit;
-               $info->{'query-arguments'} = join ", ", @queryArgs;
-
-               $info->{'native-arguments'} = join ",\n\t", @nativeArgs;
-               $info->{'trampoline-arguments'} = join ",\n\t", @trampArgs;
-       }
-
        $info->{successcodes} = $s->{successcodes} ? $s->{successcodes} : '';
        $info->{errorcodes} = $s->{errorcodes} ? $s->{errorcodes}: '';
 
@@ -1259,14 +1177,10 @@ sub formatFunctionPointer {
 sub formatFunctionDescriptor {
        my $ct = shift;
        my $s = shift;
-
-       my $templates = $ct->{templates};
        my $types = $ct->{types};
-       my $overrides = $ct->{overrides};
-
        my @fields = ();
        my $void = $s->{proto}->{fullType} eq 'void';
-       my $override = $overrides->{$s->{name}};
+       my $override = $ct->{overrides}->{$s->{name}};
 
        foreach my $m ($void ? () : $s->{proto}, @{$s->{items}}) {
                my $deref = defined($override->{$m->{name}}) && defined($override->{$m->{name}}->{type}) ? $override->{$m->{name}}->{type} : $m->{deref};
@@ -1287,15 +1201,14 @@ sub formatFunction {
        my $api = shift;
        my $ct = shift;
        my $s = shift;
-       my $templates = $ct->{templates};
-       my $types = $ct->{types};
-       my $overrides = $ct->{overrides};
        my $void = $s->{proto}->{fullType} eq 'void';
-       my $override = $overrides->{$s->{name}};
-       my $template = $override->{template} ? $override->{template} : $templates->{method};
+       my $override = $ct->{overrides}->{$s->{name}};
+       my $tempname = $override->{template} ? $override->{template} : 'method';
+       my $template = $ct->{templates}->{$tempname};
 
        my $info = collectFunctionInfo($api, $ct, $s);
 
        #join("\n", map { '// '.$_ } split(/\n/,Dumper($s)))."\n".
-       code::formatTemplate($template->{invoke}, $info);
+       " /* template: $tempname */\n".
+               code::formatTemplate($template->{invoke}, $info);
 }
index 25414fa..96a49f0 100644 (file)
@@ -9,6 +9,9 @@
 # {java-get}
 # {java-set}
 # {init}*
+# {init-array}*
+# {setall-arg}
+# {setall}
 
 code value {
   get {{
@@ -34,12 +37,47 @@ code value {
        }
   }}
 
-  # FIXME: only handles single element arrays
-  init {{ {name}$VH.set(this.segment, VkConstants.{values}); }}
+  # Initialise the sType field if it has one, also include sub-
+  init eval    {{
+       if ($tempname =~ m/write/) {
+               my $init = "{name}\$VH.set(self\$.segment, VkConstants.{values});\n";
+               foreach my $x (@{$s->{items}}) {
+                       if ($x->{deref} eq 'struct') {
+                               my $y = $api->{types}->{$x->{baseType}};
+                               if ($#{$y->{items}} >= 0 && $y->{items}->[0]->{values}) {
+                                       my $z = $y->{items}->[0];
+                                       $init .= "self\$.get$x->{Name}().set$z->{Name}(VkConstants.$z->{values});\n";
+                               }
+                       }
+               }
+               return $init;
+       } else {
+               ''
+       }
+  }}
 
-  # for complex constructors?
-  setall-arg {{ {type} {name} /* value */ }}
-  setall {{ self$.set{Name}({name}); }}
+  init-array eval      {{
+       if ($tempname =~ m/write.*array/n) {
+               my $init = "{name}\$AH.set(self\$.segment, i, VkConstants.{values});\n";
+               foreach my $x (@{$s->{items}}) {
+                       if ($x->{deref} eq 'struct') {
+                               my $y = $api->{types}->{$x->{baseType}};
+                               if ($#{$y->{items}} >= 0 && $y->{items}->[0]->{values}) {
+                                       my $z = $y->{items}->[0];
+                                       $init .= "self\$.get$x->{Name}AtIndex(i).set$z->{Name}(VkConstants.$z->{values});\n";
+                               }
+                       }
+               }
+
+               "for (long i=0; i<length; i++) {\n\t$init\n\t}\n";
+       } else {
+               ''
+       }
+  }}
+
+  # for complex constructors
+  setall-arg   {{ {type} {name} }}
+  setall               {{ self$.set{Name}({name}); }}
 }
 
 code value-array {
@@ -84,6 +122,26 @@ END
   }}
 }
 
+# don't like having to pass scope here, not sure what else to do though
+code handle-array {
+  getorset {{
+       /* value-array {deref} */
+       public {type} get{Name}(VkInstance instance$, ResourceScope scope$) {
+               try {
+                       return {java-get};
+               } catch (Throwable t) {
+                       throw new RuntimeException(t);
+               }
+       }
+       public {typei} get{Name}Element(int i$, VkInstance instance$, ResourceScope scope$) {
+               return {java-geti};
+       }
+       public void set{Name}Element(int i$, {typei} {name}) {
+               {java-seti};
+       }
+  }}
+}
+
 code value-array2d {
   getorset {{
        /* value-array2d {deref} */
@@ -114,55 +172,40 @@ code inline {
                }
        }
   }}
+  getorsetat {{
+       /* inline {deref} */
+       public {type} get{Name}AtIndex(long i$) {
+               try {
+                       return {java-getat};
+               } catch (Throwable t) {
+                       throw new RuntimeException(t);
+               }
+       }
+  }}
 }
 
 # value with a SegmentAllocator passed to set()
-code value-alloc {
-  get {{
-       /* {deref} */
-       public {type} get{Name}() {
-               return {java-get};
-       }
-  }}
+code value-alloc value {
   set {{
        /* {deref} */
        public void set{Name}({type} {name}, SegmentAllocator alloc$) {
                {java-set};
        }
   }}
-  getat {{
-       /* {deref} */
-       public {type} get{Name}AtIndex(long i$) {
-               return {java-getat};
-       }
-  }}
   setat {{
        /* {deref} */
        public void set{Name}AtIndex(long i$, {type} {name}, SegmentAllocator alloc$) {
                {java-setat};
        }
   }}
-  setall-arg {{ {type} {name} }}
-  setall {{ self$.set{Name}({name}, alloc$); }}
+
+  setall               {{ self$.set{Name}({name}, alloc$); }}
 }
 
 # implied accessors are ignored in constructors
-code value-implied {
-  get {{
-       /* {deref} */
-       public {type} get{Name}() {
-               return {java-get};
-       }
-  }}
-  set {{
-       /* {deref} */
-       public void set{Name}({type} {name}) {
-               {java-set};
-       }
-  }}
-
-  # supposed to be handled in set of the target, but ...?
-  setall {{ self$.set{Name}(({type})Memory.length({lengthfor})); }}
+code value-implied value {
+  setall-arg;
+  setall               {{ self$.set{Name}(({type})Memory.length({lengthfor})); }}
 }
 
 # ###################################################################### #
@@ -316,7 +359,6 @@ code struct {
 
                private {Name}(MemorySegment segment) {
                        this.segment = segment;
-                       {init}
                }
 
                public static {Name} create(MemorySegment segment) {
@@ -324,11 +366,13 @@ code struct {
                }
 
                public static {Name} create(MemoryAddress address, ResourceScope scope) {
-                       return new {Name}(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope));
+                       return create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope));
                }
 
                public static {Name} create(SegmentAllocator alloc) {
-                       return new {Name}(alloc.allocate(LAYOUT));
+                       var self$ = create(alloc.allocate(LAYOUT));
+                       {init}
+                       return self$;
                }
 
                // Pointer
@@ -350,7 +394,7 @@ code struct {
   }}
   create-all {{
                public static {Name} {create}({java-setall-arguments}) {
-                       {Name} self$ = create(alloc$.allocate(LAYOUT));
+                       {Name} self$ = create(alloc$);
 
                        {java-setall}
 
@@ -366,11 +410,13 @@ code struct {
   }}
   array {{
                static {Name} createArray(MemoryAddress addr, long length, ResourceScope scope) {
-                       return new {Name}(MemorySegment.ofAddress(addr, length * LAYOUT.byteSize(), scope));
+                       return create(MemorySegment.ofAddress(addr, length * LAYOUT.byteSize(), scope));
                }
 
                public static {Name} createArray(long length, SegmentAllocator alloc) {
-                       return new {Name}(alloc.allocateArray(LAYOUT, length));
+                       var self$ = create(alloc.allocateArray(LAYOUT, length));
+                       {init-array}
+                       return self$;
                }
 
                public final static MethodHandle LAYOUT$SH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement());
@@ -417,7 +463,7 @@ code struct-writeonly insert=struct:header,struct:create-all
 }
 
 code struct-writeonly-array insert=struct:header,struct:create-all,struct:array
-       fields=init,set,getorset,setat,getorsetat,handle,handleat,java-setall {
+       fields=init,init-array,set,getorset,setat,getorsetat,handle,handleat,java-setall {
   class {{
        // template: struct-writeonly-array:class
        package {package};
@@ -464,7 +510,7 @@ code struct-readonly insert=struct:header
 }
 
 code struct-readonly-array insert=struct:header,struct:array
-       fields=init,get,getorset,getat,getorsetat,handle,handleat {
+       fields=init,init-array,get,getorset,getat,getorsetat,handle,handleat {
   class {{
        // template: struct-readonly-array:class
        package {package};
@@ -512,7 +558,7 @@ code struct-readwrite insert=struct:header,struct:create-all
 }
 
 code struct-readwrite-array insert=struct:header,struct:create-all,struct:array
-       fields=init,get,getat,set,setat,getorset,getorsetat,handle,handleat,java-setall {
+       fields=init,init-array,get,getat,set,setat,getorset,getorsetat,handle,handleat,java-setall {
   class {{
        // template: struct-readwrite-array:class
        package {package};
@@ -563,7 +609,10 @@ type value accessor=value {
 type value-array accessor=value-array {
        native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
        java-get        {{ {type}.create({native-get}) }}
-       java-geti       {{ ({typei}){name}$EH.get(this.segment, i$) }}
+
+       native-geti     {{ {name}$EH.get(this.segment, i$) }}
+
+       java-geti       {{ ({typei}){native-geti} }}
        java-seti       {{ {name}$EH.set(this.segment, i$, {name}) }}
        handle          {{
                final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
@@ -586,16 +635,20 @@ type inline accessor=inline {
        native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
        java-get        {{ {type}.create({native-get}) }}
        handle          {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
+
+       native-getat {{ (MemorySegment){name}$SA.invokeExact(this.segment, i$) }}
+       java-getat      {{ {type}.create({native-getat}) }}
+       handleat        {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
 }
 
 type inline-array accessor=inline {
-#      type            {{ MemorySegment }}
        native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
-#      java-get        {{ {native-get} }}
        java-get        {{ {type}.create({native-get}) }}
-       handle          {{
-               final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
-       }}
+       handle          {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
+
+       native-getat {{ (MemorySegment){name}$SA.invokeExact(this.segment, i$) }}
+       java-getat      {{ {type}.create({native-getat}) }}
+       handleat        {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
 }
 
 type uint8_t,char value {
@@ -758,21 +811,8 @@ type char* pointer accessor=value-alloc {
 type char**-length pointer-length accessor=value-alloc {
        type    {{ String[] }}
 
-       java-set        {{ {name}$VH.set(this.segment, Memory.copyStringArray({name}, alloc$).address()); {set-length} }}
+       java-set        {{ {name}$VH.set(this.segment, Memory.copyStringArray({name}, alloc$).address()); }}
        java-get        {{ Memory.copyStringArray((MemoryAddress){name}$VH.get(this.segment), {length}) }}
-
-#      set-length eval {{
-#              if ($v->{len} =~ m/(.*),null-terminated/) {
-#                      'set'.ucfirst($1).'({name}.length)';
-#              } else {
-#                      die Dumper($v, $s);
-#              }
-#      }}
-}
-
-# FIXME: wrong
-type uint32_t** pointer {
-       type    {{ HandleArray<IntArray> }}
 }
 
 type funcpointer pointer {
@@ -793,13 +833,13 @@ type handle pointer {
        java-get        {{ {type}.create({native-get}, this.segment.scope()) }}
 }
 
-# FIXME: wrong
-type handle[] {
-       type    {{ HandleArray<{typei}> }}
-       layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.POINTER) }}
-       #java-get       {{ HandleArray.create({get}, {typei}::create) }}
-       java-get        {{ error }}
-       typei   {{ {baseType} }}
+type handle[] value-array accessor=handle-array {
+       type            {{ HandleArray<{typei}> }}
+       typei           {{ {baseType} }}
+       layout          {{ MemoryLayout.sequenceLayout({len1}, Memory.POINTER) }}
+       java-get        {{ HandleArray.create({native-get}, (a, s) -> {typei}.create(a, instance$.dispatch, s), scope$) }}
+
+       java-geti       {{ {typei}.create((MemoryAddress){native-geti}, instance$.dispatch, scope$) }}
 }
 
 type handle* pointer {
@@ -812,7 +852,7 @@ type handle*-length pointer-length {
        type            {{ HandleArray<{baseType}> }}
        typei           {{ {baseType} }}
        java-get        {{ HandleArray.createArray({native-get}, {length}, {typei}::create, this.segment.scope()) }}
-       java-set        {{ {name}$VH.set(this.segment, Memory.address({name})); {set-length} }}
+       java-set        {{ {name}$VH.set(this.segment, Memory.address({name})); }}
 }
 
 type struct inline {
@@ -820,7 +860,6 @@ type struct inline {
        layout  {{ {baseType}.LAYOUT }}
 }
 
-# how?  length?
 type struct* pointer {
        type            {{ {baseType} }}
        java-get        {{ {baseType}.create({native-get}, this.segment.scope()) }}
@@ -857,8 +896,6 @@ override structs {
 
        VkAllocationCallbacks   ignore;
 
-       #VkQueueFamilyProperties        template=struct-readwrite;
-
        # Override default read/write
        VkDebugUtilsMessengerCallbackDataEXT template=struct-readonly;
        VkDebugUtilsLabelEXT template=struct-readonly-array;
index 6f3a0bf..a337d4c 100644 (file)
@@ -55,18 +55,10 @@ sub new {
 
                        die if !defined($r);
 
-                       push @{$r->{extensions}}, $e;
+                       push @{$r->{extensions}}, $e->{name};
                }
        }
 
-       #print Dumper($self->{types});
-
-       # FIXME: link extensions up
-       # my $r = findData($data, $alias, "type:$ma->{name}");
-       # die "cann't find $ma->{name}" if !defined $r;
-       # push @{$r->{extensions}}, $ext;
-       # push @{$r->{commands}}, $ma->{name};
-
        $self;
 }