Yet another attempt at a vulkan binding generator.
[panamaz] / src / notzed.vulkan / gen / struct-types.api
1 # -*- Mode:text; tab-width:4; electric-indent-mode: nil; indent-line-function:insert-tab; -*-
2
3 # types for structs and unions
4
5 #accessor=code template
6 # {type} - java type
7 # {java-get}
8 # {java-set}
9 # {init}*
10
11 code value {
12   get {{
13         /* {deref} */
14         public {type} get{Name}() {
15                 return {java-get};
16         }
17   }}
18   set {{
19         /* {deref} */
20         public void set{Name}({type} {name}) {
21                 {java-set};
22         }
23   }}
24
25   # FIXME: only handles single element arrays
26   init  {{ {name}$VH.set(this.segment, VkConstants.{values}); }}
27
28   # for complex constructors?
29   setall-arg {{ {type} {name} /* value */ }}
30   setall {{ self$.set{Name}({name}); }}
31 }
32
33 code value-array {
34   getorset {{
35         /* value-array {deref} */
36         public {type} get{Name}() {
37                 try {
38                         return {java-get};
39                 } catch (Throwable t) {
40                         throw new RuntimeException(t);
41                 }
42         }
43         public {typei} get{Name}Element(int i$) {
44                 return {java-geti};
45         }
46         public void set{Name}Element(int i$, {typei} {name}) {
47                 {java-seti};
48         }
49   }}
50 }
51
52 code value-array2d {
53   getorset {{
54         /* value-array2d {deref} */
55         public {type} get{Name}() {
56                 try {
57                         return {java-get};
58                 } catch (Throwable t) {
59                         throw new RuntimeException(t);
60                 }
61         }
62         public {typei} get{Name}Element(int i$, int j$) {
63                 return {java-geti};
64         }
65         public void set{Name}Element(int i$, int j$, {typei} {name}) {
66                 {java-seti};
67         }
68   }}
69 }
70
71 code inline {
72   getorset {{
73         /* inline {deref} */
74         public {type} get{Name}() {
75                 try {
76                         return {java-get};
77                 } catch (Throwable t) {
78                         throw new RuntimeException(t);
79                 }
80         }
81   }}
82 }
83
84 # value with a SegmentAllocator passed to set()
85 code value-alloc {
86   get {{
87         /* {deref} */
88         public {type} get{Name}() {
89                 return {java-get};
90         }
91   }}
92   set {{
93         /* {deref} */
94         public void set{Name}({type} {name}, SegmentAllocator alloc$) {
95                 {java-set};
96         }
97   }}
98   setall-arg {{ {type} {name} }}
99   setall {{ self$.set{Name}({name}, alloc$); }}
100 }
101
102 # implied accessors are ignored in constructors
103 code value-implied {
104   get {{
105         /* {deref} */
106         public {type} get{Name}() {
107                 return {java-get};
108         }
109   }}
110   set {{
111         /* {deref} */
112         public void set{Name}({type} {name}) {
113                 {java-set};
114         }
115   }}
116
117   # supposed to be handled in set of the target, but ...?
118   setall {{ self$.set{Name}(({type})Memory.length({lengthfor})); }}
119 }
120
121 # ###################################################################### #
122
123 code dispatch {
124   class {{
125         // template: dispatch:class
126         package {package};
127         import jdk.incubator.foreign.*;
128         import java.lang.invoke.*;
129         import au.notzed.nativez.*;
130         class {Name} {
131
132                 {field-init}
133
134                 {Name}(VkInstance instance$, ResourceScope scope$) {
135                         {init}
136                 }
137         }
138   }}
139   field-init {{ final NativeSymbol {name}$NS; }}
140   init {{ {name}$NS = instance$.vkGetInstanceProcAddr("{name}", scope$); }}
141
142 }
143
144 # non-dispatchable handle
145 code handle {
146   class {{
147         // template: handle:class
148         package {package};
149         import jdk.incubator.foreign.*;
150         import java.lang.invoke.*;
151         import au.notzed.nativez.*;
152
153         public class {name} implements Pointer {
154                 final NativeSymbol self;
155
156                 private {name}(MemoryAddress address, ResourceScope scope) {
157                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
158                         {init}
159                 }
160
161                 public static {name} create(MemoryAddress address, ResourceScope scope) {
162                         return new {name}(address, scope);
163                 }
164
165                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc) {
166                         return HandleArray.createArray(1, alloc, {name}::create);
167                 }
168
169                 public MemoryAddress address() {
170                         return self.address();
171                 }
172
173                 public ResourceScope scope() {
174                         return self.scope();
175                 }
176         }
177   }}
178 }
179
180 # VkInstance
181 code handle-instance {
182   class {{
183         // template: handle-instance:class
184         package {package};
185         import jdk.incubator.foreign.*;
186         import java.lang.invoke.*;
187         import au.notzed.nativez.*;
188
189         public class {name} implements Pointer {
190                 final NativeSymbol self;
191                 final DispatchInstance dispatch;
192
193                 private {name}(MemoryAddress address, ResourceScope scope) {
194                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
195                         this.dispatch = new DispatchInstance(this, scope);
196                         {init}
197                 }
198
199                 public static {name} create(MemoryAddress address, ResourceScope scope) {
200                         return new {name}(address, scope);
201                 }
202
203                 public MemoryAddress address() {
204                         return self.address();
205                 }
206
207                 public ResourceScope scope() {
208                         return self.scope();
209                 }
210
211                 {commands}
212         }
213   }}
214 }
215
216 # dispatchable handle
217 code handle-dispatch {
218   class {{
219         // template: handle-dispatch:class
220         package {package};
221         import jdk.incubator.foreign.*;
222         import java.lang.invoke.*;
223         import au.notzed.nativez.*;
224
225         public class {name} implements Pointer {
226                 final NativeSymbol self;
227                 final DispatchInstance dispatch;
228
229                 private {name}(MemoryAddress address, DispatchInstance dispatch, ResourceScope scope) {
230                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
231                         this.dispatch = dispatch;
232                         {init}
233                 }
234
235                 public static {name} create(MemoryAddress address, DispatchInstance dispatch, ResourceScope scope) {
236                         return new {name}(address, dispatch, scope);
237                 }
238
239                 // TODO: evaluate how scope fits here
240                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, DispatchInstance dispatch, ResourceScope scope) {
241                         return HandleArray.createArray(1, alloc, (a, s) -> create(a, dispatch, s), scope);
242                 }
243
244                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, VkInstance instance, ResourceScope scope) {
245                         return HandleArray.createArray(1, alloc, (a, s) -> create(a, instance.dispatch, s), scope);
246                 }
247
248                 public MemoryAddress address() {
249                         return self.address();
250                 }
251
252                 public ResourceScope scope() {
253                         return self.scope();
254                 }
255
256                 {commands}
257         }
258   }}
259 }
260
261 # FIXME: unimplemented
262 code funcpointer {
263   class {{
264         package {package};
265         import jdk.incubator.foreign.*;
266         import java.lang.invoke.*;
267         import au.notzed.nativez.*;
268
269         public interface {name} {
270
271                 void call();
272
273                 {upcall}
274                 {downcall}
275         }
276   }}
277   upcall {{
278         public static FunctionPointer<{Name}> upcall({Name} target$, ResourceScope scope$) {
279                 throw new UnsupportedOperationException();
280         }
281   }}
282   downcall {{
283         public static FunctionPointer<{Name}> downcall(MemoryAddress target$, ResourceScope scope$) {
284                 throw new UnsupportedOperationException();
285         }
286   }}
287 }
288
289 # shared struct components
290 code struct {
291   header {{
292                 public MemorySegment segment;
293
294                 public static final GroupLayout LAYOUT = {layout};
295
296                 private {Name}(MemorySegment segment) {
297                         this.segment = segment;
298                         {init}
299                 }
300
301                 public static {Name} create(MemorySegment segment) {
302                         return new {Name}(segment);
303                 }
304
305                 public static {Name} create(MemoryAddress address, ResourceScope scope) {
306                         return new {Name}(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope));
307                 }
308
309                 public static {Name} create(SegmentAllocator alloc) {
310                         return new {Name}(alloc.allocate(LAYOUT));
311                 }
312
313                 // Pointer
314                 @Override
315                 public MemoryAddress address() {
316                         return segment.address();
317                 }
318
319                 // Pointer
320                 @Override
321                 public ResourceScope scope() {
322                         return segment.scope();
323                 }
324
325                 @Override
326                 public String toString() {
327                         return Memory.toString(segment, LAYOUT);
328                 }
329   }}
330   create-all {{
331                 public static {Name} {create}({java-setall-arguments}) {
332                         {Name} self$ = create(alloc$.allocate(LAYOUT));
333
334                         {java-setall}
335
336                         return self$;
337                 }
338   }}
339   set-all {{
340                 public void init({java-setall-arguments}) {
341                         {Name} self$ = this;
342
343                         {java-setall}
344                 }
345   }}
346   array {{
347                 static {Name} createArray(MemoryAddress addr, long length, ResourceScope scope) {
348                         return new {Name}(MemorySegment.ofAddress(addr, length * LAYOUT.byteSize(), scope));
349                 }
350
351                 public static {Name} createArray(long length, SegmentAllocator alloc) {
352                         return new {Name}(alloc.allocateArray(LAYOUT, length));
353                 }
354
355                 public final static MethodHandle LAYOUT$SH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement());
356
357                 // Array
358                 @Override
359                 public long length() {
360                         return segment.byteSize() / LAYOUT.byteSize();
361                 }
362
363                 // Array
364                 #Override
365                 public {Name} getAtIndex(long index$) {
366                         try {
367                                 return create((MemorySegment)LAYOUT$SH.invokeExact(this.segment, index$));
368                         } catch (Throwable t) {
369                                 throw new RuntimeException(t);
370                         }
371                 }
372   }}
373 }
374
375 # default - writeonly struct
376 code struct-writeonly insert=struct:header,struct:create-all {
377   class {{
378         // template: struct-writeonly:class
379         package {package};
380         import jdk.incubator.foreign.*;
381         import java.lang.invoke.*;
382         import au.notzed.nativez.*;
383
384         public class {Name} implements Pointer {
385                 {header}
386
387                 {create-all}
388
389                 {set}
390                 {getorset}
391
392                 {varhandle}
393         }
394   }}
395 }
396
397 code struct-writeonly-array insert=struct:header,struct:create-all,struct:array {
398   class {{
399         // template: struct-writeonly-array:class
400         package {package};
401         import jdk.incubator.foreign.*;
402         import java.lang.invoke.*;
403         import au.notzed.nativez.*;
404
405         public class {Name} implements Pointer, Array<{Name}> {
406                 {header}
407                 {array}
408
409                 {create-all}
410
411                 {set}
412                 {getorset}
413
414                 {varhandle}
415         }
416   }}
417 }
418
419 code struct-readonly insert=struct:header {
420   class {{
421         // template: struct-readonly:class
422         package {package};
423         import jdk.incubator.foreign.*;
424         import java.lang.invoke.*;
425         import au.notzed.nativez.*;
426
427         public class {Name} implements Pointer {
428                 {header}
429
430                 {get}
431                 {getorset}
432
433                 {varhandle}
434         }
435   }}
436 }
437
438 code struct-readonly-array insert=struct:header,struct:array {
439   class {{
440         // template: struct-readonly-array:class
441         package {package};
442         import jdk.incubator.foreign.*;
443         import java.lang.invoke.*;
444         import au.notzed.nativez.*;
445
446         public class {Name} implements Pointer, Array<{Name}> {
447                 {header}
448                 {array}
449
450                 {get}
451                 {getorset}
452
453                 {varhandle}
454         }
455   }}
456 }
457
458 code struct-readwrite insert=struct:header,struct:create-all {
459   class {{
460         // template: struct-readwrite:class
461         package {package};
462         import jdk.incubator.foreign.*;
463         import java.lang.invoke.*;
464         import au.notzed.nativez.*;
465
466         public class {Name} implements Pointer {
467                 {header}
468
469                 {create-all}
470
471                 {get}
472                 {set}
473                 {getorset}
474
475                 {varhandle}
476         }
477   }}
478 }
479
480 code struct-readwrite-array insert=struct:header,struct:create-all,struct:array {
481   class {{
482         // template: struct-readwrite-array:class
483         package {package};
484         import jdk.incubator.foreign.*;
485         import java.lang.invoke.*;
486         import au.notzed.nativez.*;
487
488         public class {Name} implements Pointer,Array<{Name}> {
489                 {header}
490                 {array}
491
492                 {create-all}
493
494                 {get}
495                 {set}
496                 {getorset}
497
498                 {varhandle}
499         }
500   }}
501 }
502
503 # how to arrays?  in code?
504 # how to lengths?
505
506 type value accessor=value {
507         java-get        {{ ({type}){name}$VH.get(this.segment) }}
508         java-set        {{ {name}$VH.set(this.segment, {name}) }}
509         handle          {{ final static VarHandle {name}$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
510 }
511
512 type value-array accessor=value-array {
513         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
514         java-get        {{ {type}.create({native-get}) }}
515         java-geti       {{ ({typei}){name}$EH.get(i$) }}
516         java-seti       {{ {name}$EH.set(i$, {name}) }}
517         handle          {{
518                 final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
519                 final static VarHandle {name}$EH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}"), MemoryLayout.PathElement.sequenceElement());
520         }}
521 }
522
523 type value-array2d accessor=value-array2d {
524         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
525         java-get        {{ {type}.create({native-get}) }}
526         java-geti       {{ ({typei}){name}$EH.get(i$, j$) }}
527         java-seti       {{ {name}$EH.set(i$, j$, {name}) }}
528         handle          {{
529                 final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
530                 final static VarHandle {name}$EH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}"), MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement());
531         }}
532 }
533
534 type inline accessor=inline {
535         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
536         java-get        {{ {type}.create({native-get}) }}
537         handle          {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
538 }
539
540 type inline-array accessor=inline {
541 #       type            {{ MemorySegment }}
542         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
543 #       java-get        {{ {native-get} }}
544         java-get        {{ {type}.create({native-get}) }}
545         handle          {{
546                 final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
547         }}
548 }
549
550 type uint8_t,char value {
551         type    {{ byte }}
552         layout  {{ Memory.BYTE }}
553 }
554
555 type uint16_t value {
556         type    {{ short }}
557         layout  {{ Memory.SHORT }}
558 }
559
560 type uint32_t,int,int32_t value {
561         type    {{ int }}
562         layout  {{ Memory.INT }}
563 }
564
565 type uint64_t,int64_t,size_t value {
566         type    {{ long }}
567         layout  {{ Memory.LONG }}
568 }
569
570 type float value {
571         type    {{ float }}
572         layout  {{ Memory.FLOAT }}
573 }
574
575 type double value {
576         type    {{ double }}
577         layout  {{ Memory.DOUBLE }}
578 }
579
580 # ###################################################################### #
581 # implied length types
582 type uint64_t-implied,size_t-implied uint64_t accessor=value-implied {
583
584 }
585
586 type uint32_t-implied uint32_t accessor=value-implied {
587 }
588
589 # ###################################################################### #
590
591 type uint8_t[],char[] value-array {
592         type    {{ ByteArray }}
593         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.BYTE) }}
594         typei   {{ byte }}
595 }
596
597 type uint32_t[],int32_t[] value-array {
598         type    {{ IntArray }}
599         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.INT) }}
600         typei   {{ int }}
601 }
602
603 type uint64_t[] value-array {
604         type    {{ LongArray }}
605         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.LONG) }}
606         typei   {{ long }}
607 }
608
609 type float[] value-array {
610         type    {{ FloatArray }}
611         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.FLOAT) }}
612         typei   {{ float }}
613 }
614
615 type struct[] inline-array {
616         type    {{ {baseType} }}
617         layout  {{ MemoryLayout.sequenceLayout({len1}, {baseType}.LAYOUT) }}
618 }
619
620 type float[][] value-array2d {
621         type    {{ FloatArray }}
622         typei   {{ float }}
623         layout  {{ MemoryLayout.sequenceLayout({len1}, MemoryLayout.sequenceLayout({len2}, Memory.FLOAT)) }}
624 }
625
626 # select=len?  or what?
627
628 type pointer value {
629         layout  {{ Memory.POINTER }}
630         type    {{ MemoryAddress }}
631
632         native-get      {{ (MemoryAddress){name}$VH.get(this.segment) }}
633
634         java-get        {{ {native-get} }}
635         java-set        {{ {name}$VH.set(this.segment, Memory.address({name})) }}
636 }
637
638 type void* pointer;
639
640 type value-pointer pointer {
641         java-get        {{ {type}.create((MemoryAddress){name}$VH.get(this.segment), segment.scope()) }}
642 }
643
644 type uint8_t* value-pointer {
645         type    ByteArray;
646 }
647
648 type uint32_t*,int32_t*,int* value-pointer {
649         type    IntArray;
650 }
651
652 type uint64_t* value-pointer {
653         type    LongArray;
654 }
655
656 type float* value-pointer {
657         type    FloatArray;
658 }
659
660 type size_t* value-pointer {
661         type    LongArray;
662 }
663
664 type pointer-length pointer {
665         java-get        {{ {type}.createArray({native-get}, {length}, this.segment.scope()) }}
666 }
667
668 type void*-length pointer-length {
669         type            MemorySegment;
670         java-get        {{ MemorySegment.ofAddress({native-get}, {length}, this.segment.scope()) }}
671 }
672
673 type uint8_t*-length pointer-length {
674         type    ByteArray;
675 }
676
677 type uint32_t*-length,int32_t*-length pointer-length {
678         type    IntArray;
679 }
680
681 type uint64_t*-length pointer-length {
682         type    LongArray;
683 }
684
685 type float*-length pointer-length {
686         type    FloatArray;
687 }
688
689 # special handling for strings, will fail if it isn't
690 type char* pointer accessor=value-alloc {
691         type            {{ String }}
692
693         java-get        {{ ({native-get}).getUtf8String(0) }}
694         java-set        {{ {name}$VH.set(this.segment, alloc$.allocateUtf8String({name}).address()) }}
695
696         # this just verifies it's a string type
697         length eval     {{
698                 if ($v->{len} =~ m/null-terminated/) {
699                         1;
700                 } else {
701                         die Dumper($v, $s);
702                 }
703         }}
704
705 }
706
707 type char**-length pointer-length accessor=value-alloc {
708         type    {{ String[] }}
709
710         java-set        {{ {name}$VH.set(this.segment, Memory.copyStringArray({name}, alloc$).address()); {set-length} }}
711         java-get        {{ Memory.copyStringArray((MemoryAddress){name}$VH.get(this.segment), {length}) }}
712
713 #       set-length eval {{
714 #               if ($v->{len} =~ m/(.*),null-terminated/) {
715 #                       'set'.ucfirst($1).'({name}.length)';
716 #               } else {
717 #                       die Dumper($v, $s);
718 #               }
719 #       }}
720 }
721
722 # FIXME: wrong
723 type uint32_t** pointer {
724         type    {{ HandleArray<IntArray> }}
725 }
726
727 type funcpointer pointer {
728         type            {{ FunctionPointer<{baseType}> }}
729         typei           {{ {baseType} }}
730         java-get        {{ {baseType}.downcall({native-get}, this.segment.scope()) }}
731 }
732
733 type void** pointer {
734 }
735
736 type void**-length pointer-length {
737         type    PointerArray;
738 }
739
740 type handle pointer {
741         type            {{ {baseType} }}
742         java-get        {{ {type}.create({native-get}, this.segment.scope()) }}
743 }
744
745 # FIXME: wrong
746 type handle[] {
747         type    {{ HandleArray<{typei}> }}
748         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.POINTER) }}
749         #java-get       {{ HandleArray.create({get}, {typei}::create) }}
750         java-get        {{ error }}
751         typei   {{ {baseType} }}
752 }
753
754 type handle* pointer {
755         type            {{ HandleArray<{typei}> }}
756         typei           {{ {baseType} }}
757         java-get        {{ HandleArray.create({native-get}, {typei}::create) }}
758 }
759
760 type handle*-length pointer-length {
761         type            {{ HandleArray<{baseType}> }}
762         typei           {{ {baseType} }}
763         java-get        {{ HandleArray.createArray({native-get}, {length}, {typei}::create, this.segment.scope()) }}
764         java-set        {{ {name}$VH.set(this.segment, Memory.address({name})); {set-length} }}
765 }
766
767 type struct inline {
768         type    {{ {baseType} }}
769         layout  {{ {baseType}.LAYOUT }}
770 }
771
772 # how?  length?
773 type struct* pointer {
774         type            {{ {baseType} }}
775         java-get        {{ {baseType}.create({native-get}, this.segment.scope()) }}
776 }
777
778 type struct*-length pointer-length {
779         type    {{ {baseType} }}
780         typei   {{ {baseType} }}
781 }
782
783 type struct** pointer {
784 }
785
786 # xlib
787 type XID,Window,VisualID uint64_t;
788
789 type Display* handle {
790         type    xlib.XDisplay;
791 }
792
793 # xcb
794 type xcb_window_t uint32_t;
795 type xcb_visualid_t uint32_t;
796 type xcb_connection_t* handle {
797         type    xcb.Connection;
798 }
799
800 override structs {
801         VkInstance                      template=handle-instance;
802         VkPhysicalDevice        template=handle-dispatch;
803         VkDevice                        template=handle-dispatch;
804         VkCommandBuffer         template=handle-dispatch;
805         VkQueue                         template=handle-dispatch;
806
807         #VkQueueFamilyProperties        template=struct-readwrite;
808
809         # TODO: fill these in, there's a good number of them
810         #VkPhysicalDeviceMemoryProperties template=struct-readonly;
811         #VkMemoryRequirements template=struct-readonly;
812         #VkPipelineExecutableInternalRepresentationKHR template=struct-readonly;
813
814         # override default array-length behaviours, some of these are independent of the array pointer
815         VkAccelerationStructureBuildGeometryInfoKHR geometryCount=type:uint32_t;
816         VkDescriptorSetLayoutBinding pImmutableSamplers=type:handle* descriptorCount=type:uint32_t;
817         VkPipelineViewportStateCreateInfo scissorCount=type:uint32_t viewportCount=type:uint32_t;
818
819 # can't really work out what this is it's a void ** but it stays it's a pointer to uint8_t * in the spec
820         VkCuLaunchInfoNVX       pParams=type:pointer pExtras=type:pointer;
821 }