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