Update to OpenJDK 19 java.lang.foriegn. master
authorNot Zed <notzed@gmail.com>
Sun, 25 Sep 2022 12:41:43 +0000 (22:11 +0930)
committerNot Zed <notzed@gmail.com>
Sun, 25 Sep 2022 12:41:43 +0000 (22:11 +0930)
Advance tutorial to chapter 29.

17 files changed:
nbproject/project.properties
src/notzed.display/classes/au/notzed/display/Display.java
src/notzed.display/classes/au/notzed/display/Window.java
src/notzed.vulkan.test/classes/vulkan/test/Demo.java
src/notzed.vulkan.test/classes/vulkan/test/TestCube.java
src/notzed.vulkan.test/classes/vulkan/test/TestMandelbrot.java
src/notzed.vulkan.test/classes/vulkan/test/TestSDF.java
src/notzed.vulkan.test/classes/vulkan/test/Tutorial.java
src/notzed.vulkan.test/classes/vulkan/test/mat.java [new file with mode: 0644]
src/notzed.vulkan.test/classes/vulkan/test/mat4.java [new file with mode: 0644]
src/notzed.vulkan.test/classes/vulkan/test/quat.java [new file with mode: 0644]
src/notzed.vulkan.test/gen/generate-shaderio
src/notzed.vulkan.test/shaders/vulkan/test/tutorial.vert
src/notzed.vulkan/gen/command-types.api
src/notzed.vulkan/gen/generate-vulkan
src/notzed.vulkan/gen/struct-types.api
src/notzed.xcb/classes/xcb/Connection.java

index 484a1fa..b0c5f0d 100644 (file)
@@ -40,7 +40,7 @@ includes=**
 jar.compress=false
 javac.classpath=
 # Space-separated list of extra javac options
-javac.compilerargs=
+javac.compilerargs=--enable-preview
 javac.deprecation=false
 javac.external.vm=false
 javac.modulepath=\
@@ -48,8 +48,8 @@ javac.modulepath=\
 javac.processormodulepath=
 javac.processorpath=\
     ${javac.classpath}
-javac.source=18
-javac.target=18
+javac.source=19
+javac.target=19
 javac.test.classpath=\
     ${javac.classpath}
 javac.test.modulepath=\
@@ -83,7 +83,7 @@ run.classpath=
 # Space-separated list of JVM arguments used when running the project.
 # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
 # To set system properties for unit tests define test-sys-prop.name=value:
-run.jvmargs=--enable-native-access=notzed.vulkan,notzed.nativez,notzed.xlib
+run.jvmargs=--enable-native-access=notzed.vulkan,notzed.nativez,notzed.xlib --enable-preview
 run.modulepath=\
     ${javac.modulepath}:\
     ${build.modules.dir}
index 55806b8..e418279 100644 (file)
@@ -1,12 +1,6 @@
 
 package au.notzed.display;
 
-import jdk.incubator.foreign.*;
-import au.notzed.nativez.*;
-
-import vulkan.*;
-import static vulkan.Vulkan.*;
-
 import xlib.*;
 import static xlib.XLib.*;
 
index ef1106b..b2a9755 100644 (file)
@@ -1,17 +1,16 @@
 package au.notzed.display;
 
-import jdk.incubator.foreign.*;
 import au.notzed.nativez.*;
+import java.lang.foreign.MemorySession;
 
 import vulkan.*;
-import static vulkan.Vulkan.*;
 
 import xlib.*;
 import static xlib.XLib.*;
 
 public abstract class Window {
 
-       public abstract VkSurfaceKHR createVulkanSurface(VkInstance instance, ResourceScope scope);
+       public abstract VkSurfaceKHR createVulkanSurface(VkInstance instance, MemorySession scope);
 
        public abstract Event nextEvent(boolean blocking);
 
@@ -126,7 +125,7 @@ public abstract class Window {
                }
 
                @Override
-               public VkSurfaceKHR createVulkanSurface(VkInstance instance, ResourceScope scope) {
+               public VkSurfaceKHR createVulkanSurface(VkInstance instance, MemorySession scope) {
                        try ( Frame frame = Frame.frame()) {
                                VkXlibSurfaceCreateInfoKHR surfaceinfo = VkXlibSurfaceCreateInfoKHR.create(
                                        0,
index ff3cfc5..a803f13 100644 (file)
@@ -24,12 +24,7 @@ import au.notzed.nativez.Memory;
 import java.util.HashSet;
 import java.util.List;
 import java.util.stream.Stream;
-import jdk.incubator.foreign.GroupLayout;
-import jdk.incubator.foreign.MemoryLayout;
-import jdk.incubator.foreign.MemorySegment;
-import jdk.incubator.foreign.ResourceScope;
-import jdk.incubator.foreign.SegmentAllocator;
-import jdk.incubator.foreign.ValueLayout;
+import java.lang.foreign.*;
 import vulkan.PFN_vkDebugUtilsMessengerCallbackEXT;
 import vulkan.VkApplicationInfo;
 import vulkan.VkAttachmentDescription;
@@ -44,6 +39,13 @@ import vulkan.VkCommandPool;
 import vulkan.VkCommandPoolCreateInfo;
 import vulkan.VkDebugUtilsMessengerCreateInfoEXT;
 import vulkan.VkDebugUtilsMessengerEXT;
+import vulkan.VkDescriptorBufferInfo;
+import vulkan.VkDescriptorPool;
+import vulkan.VkDescriptorPoolCreateInfo;
+import vulkan.VkDescriptorPoolSize;
+import vulkan.VkDescriptorSet;
+import vulkan.VkDescriptorSetAllocateInfo;
+import vulkan.VkDescriptorSetLayout;
 import vulkan.VkDevice;
 import vulkan.VkDeviceCreateInfo;
 import vulkan.VkDeviceMemory;
@@ -95,6 +97,7 @@ import vulkan.VkSwapchainCreateInfoKHR;
 import vulkan.VkSwapchainKHR;
 import vulkan.VkVertexInputAttributeDescription;
 import vulkan.VkVertexInputBindingDescription;
+import vulkan.VkWriteDescriptorSet;
 import vulkan.Vulkan;
 import static vulkan.Vulkan.*;
 
@@ -110,7 +113,7 @@ public class Demo {
        public final static int QUEUE_PRESENT = 0x80;
        public final static int QUEUE_MASK = QUEUE_GRAPHICS | QUEUE_COMPUTE | QUEUE_TRANSFER;
 
-       public static VkInstance createInstance(int apiVersion, String[] layers, String[] extensions, ResourceScope scope) {
+       public static VkInstance createInstance(int apiVersion, String[] layers, String[] extensions, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        VkInstanceCreateInfo info = VkInstanceCreateInfo.create(
                                0,
@@ -124,7 +127,7 @@ public class Demo {
                }
        }
 
-       public static VkDebugUtilsMessengerEXT createLogger(VkInstance instance, ResourceScope scope) throws Exception {
+       public static VkDebugUtilsMessengerEXT createLogger(VkInstance instance, MemorySession scope) throws Exception {
                try ( Frame frame = Frame.frame()) {
                        var cb = PFN_vkDebugUtilsMessengerCallbackEXT.upcall((severity, flags, data) -> {
                                System.out.printf("Debug: %d: %s\n", severity, data.getMessage());
@@ -236,21 +239,21 @@ public class Demo {
                        device.vkDestroyDevice();
                }
 
-               public VkSemaphore createSemaphore(ResourceScope scope) {
+               public VkSemaphore createSemaphore(MemorySession scope) {
                        try ( Frame frame = Frame.frame()) {
                                VkSemaphoreCreateInfo info = VkSemaphoreCreateInfo.create(frame);
                                return device.vkCreateSemaphore(info, scope);
                        }
                }
 
-               public VkFence createFence(ResourceScope scope) {
+               public VkFence createFence(MemorySession scope) {
                        try ( Frame frame = Frame.frame()) {
                                VkFenceCreateInfo info = VkFenceCreateInfo.create(frame);
                                return device.vkCreateFence(info, scope);
                        }
                }
 
-               public HandleArray<VkSemaphore> createSemaphores(int count, SegmentAllocator alloc, ResourceScope scope) {
+               public HandleArray<VkSemaphore> createSemaphores(int count, SegmentAllocator alloc, MemorySession scope) {
                        HandleArray<VkSemaphore> list = VkSemaphore.createArray(count, alloc, scope);
                        try ( Frame frame = Frame.frame()) {
                                VkSemaphoreCreateInfo info = VkSemaphoreCreateInfo.create(frame);
@@ -261,7 +264,7 @@ public class Demo {
                        return list;
                }
 
-               public HandleArray<VkFence> createFences(int count, int flags, SegmentAllocator alloc, ResourceScope scope) {
+               public HandleArray<VkFence> createFences(int count, int flags, SegmentAllocator alloc, MemorySession scope) {
                        HandleArray<VkFence> list = VkFence.createArray(count, alloc, scope);
                        try ( Frame frame = Frame.frame()) {
                                VkFenceCreateInfo info = VkFenceCreateInfo.create(flags, frame);
@@ -285,7 +288,7 @@ public class Demo {
        }
 
        // TODO: alloc?
-       public static DemoDevice createDevice(VkInstance instance, VkPhysicalDeviceFeatures features, VkSurfaceKHR surface, int[] queueFlags, String[] extensions, ResourceScope scope) {
+       public static DemoDevice createDevice(VkInstance instance, VkPhysicalDeviceFeatures features, VkSurfaceKHR surface, int[] queueFlags, String[] extensions, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        HandleArray<VkPhysicalDevice> devs = instance.vkEnumeratePhysicalDevices(frame, scope);
                        VkPhysicalDeviceProperties dp = VkPhysicalDeviceProperties.create(frame);
@@ -425,7 +428,7 @@ public class Demo {
 
        }
 
-       static DemoChain createSwapchain(DemoDevice dd, ColourFormat prefFormat, int prefPresentMode, int pixWidth, int pixHeight, SegmentAllocator alloc, ResourceScope scope) {
+       static DemoChain createSwapchain(DemoDevice dd, ColourFormat prefFormat, int prefPresentMode, int pixWidth, int pixHeight, SegmentAllocator alloc, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        ColourFormat format = selectColourFormat(
                                dd.dev.vkGetPhysicalDeviceSurfaceFormatsKHR(dd.surface, frame),
@@ -520,7 +523,7 @@ public class Demo {
            + specialisation info to initialise constants per-pipeline shader stage init
 
         */
-       static VkRenderPass dumbRenderPass(VkDevice device, int format, ResourceScope scope) {
+       static VkRenderPass dumbRenderPass(VkDevice device, int format, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        VkAttachmentDescription colourAttachment = VkAttachmentDescription.create(
                                0,
@@ -557,7 +560,7 @@ public class Demo {
                }
        }
 
-       static VkShaderModule createShaderModule(VkDevice device, IntArray spirv, ResourceScope scope) {
+       static VkShaderModule createShaderModule(VkDevice device, IntArray spirv, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        VkShaderModuleCreateInfo vsInfo = VkShaderModuleCreateInfo.create(
                                0,
@@ -568,14 +571,14 @@ public class Demo {
                }
        }
 
-       static VkPipelineLayout dumbPipelineLayout(VkDevice device, ResourceScope scope) {
+       static VkPipelineLayout dumbPipelineLayout(VkDevice device, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        VkPipelineLayoutCreateInfo layoutInfo = VkPipelineLayoutCreateInfo.create(0, 0, null, 0, null, frame);
                        return device.vkCreatePipelineLayout(layoutInfo, scope);
                }
        }
 
-       static VkPipeline dumbPipeline(VkDevice device, VkShaderModule vertex, VkShaderModule fragment, VkPipelineLayout layout, VkRenderPass renderPass, ResourceScope scope) {
+       static VkPipeline dumbPipeline(VkDevice device, VkShaderModule vertex, VkShaderModule fragment, VkPipelineLayout layout, VkRenderPass renderPass, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        VkPipelineShaderStageCreateInfo shader = VkPipelineShaderStageCreateInfo.createArray(2, frame);
 
@@ -662,7 +665,7 @@ public class Demo {
                }
        }
 
-       public static HandleArray<VkFramebuffer> createFramebuffers(DemoDevice device, DemoChain chain, SegmentAllocator alloc, ResourceScope scope) {
+       public static HandleArray<VkFramebuffer> createFramebuffers(DemoDevice device, DemoChain chain, SegmentAllocator alloc, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        var frameBuffers = VkFramebuffer.createArray(chain.views.length(), alloc);
                        HandleArray<VkImageView> attachments = VkImageView.createArray(1, frame);
@@ -682,7 +685,7 @@ public class Demo {
                }
        }
 
-       public static HandleArray<VkCommandBuffer> createCommandBuffers(DemoDevice device, int appIndex, int count, SegmentAllocator alloc, ResourceScope scope) {
+       public static HandleArray<VkCommandBuffer> createCommandBuffers(DemoDevice device, int appIndex, int count, SegmentAllocator alloc, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        VkCommandBufferAllocateInfo bufferInfo = VkCommandBufferAllocateInfo.create(
                                device.pools[appIndex],
@@ -720,7 +723,7 @@ public class Demo {
        }
 
        // TODO: memory allocator?  - limited memory blocks?
-       public static Buffer createBuffer(DemoDevice device, long size, int usage, int props, int[] sharedFamilies, ResourceScope scope) {
+       public static Buffer createBuffer(DemoDevice device, long size, int usage, int props, int[] sharedFamilies, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        IntArray families = sharedFamilies != null ? IntArray.create(frame, sharedFamilies) : null;
                        VkBufferCreateInfo create = VkBufferCreateInfo.create(0, size, usage, VK_SHARING_MODE_CONCURRENT, sharedFamilies != null ? sharedFamilies.length : 0, families, frame);
@@ -744,7 +747,7 @@ public class Demo {
                }
        }
 
-       public static Buffer createBuffer(DemoDevice device, MemorySegment src, int usage, int props, int[] sharedFamilies, ResourceScope scope) {
+       public static Buffer createBuffer(DemoDevice device, MemorySegment src, int usage, int props, int[] sharedFamilies, MemorySession scope) {
                try ( Frame frame = Frame.frame()) {
                        Buffer target = createBuffer(device, src.byteSize(), usage | Vulkan.VK_BUFFER_USAGE_TRANSFER_DST_BIT, props, sharedFamilies, scope);
                        Buffer source = createBuffer(device, src.byteSize(), Vulkan.VK_BUFFER_USAGE_TRANSFER_SRC_BIT, Vulkan.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, sharedFamilies, frame.scope());
@@ -784,6 +787,67 @@ public class Demo {
 
        }
 
+       public static record UniformBuffers(
+               VkDescriptorPool descriptorPool,
+               HandleArray<VkDescriptorSet> descriptorSets,
+               Buffer[] uniformBuffers) {
+
+               public void close(VkDevice device) {
+                       Stream.of(uniformBuffers).forEach(d -> d.close(device));
+                       device.vkDestroyDescriptorPool(descriptorPool);
+               }
+
+       }
+
+       static UniformBuffers createUniformBuffers(DemoDevice device, VkDescriptorSetLayout descriptorSetLayout, MemoryLayout uniformLayout, int frameCount, SegmentAllocator alloc, MemorySession scope) {
+               try ( Frame frame = Frame.frame()) {
+                       // uniform buffers
+                       Demo.Buffer[] uniformBuffers = new Demo.Buffer[frameCount];
+                       for (int i = 0; i < uniformBuffers.length; i++) {
+                               uniformBuffers[i] = Demo.createBuffer(device, uniformLayout.byteSize(),
+                                       Vulkan.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+                                       Vulkan.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | Vulkan.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+                                       device.queueFamilies(), scope);
+                       }
+
+                       // descriptor pools for above
+                       VkDescriptorPoolSize poolSize = VkDescriptorPoolSize.create(
+                               VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+                               frameCount,
+                               frame);
+
+                       VkDescriptorPoolCreateInfo poolInfo = VkDescriptorPoolCreateInfo.create(
+                               0,
+                               frameCount,
+                               1, poolSize,
+                               frame);
+                       VkDescriptorPool descriptorPool;
+                       descriptorPool = device.device().vkCreateDescriptorPool(poolInfo, scope);
+
+                       // sets
+                       var poolSetLayout = VkDescriptorSetLayout.createArray(frameCount, frame);
+                       for (int i = 0; i < frameCount; i++)
+                               poolSetLayout.setAtIndex(i, descriptorSetLayout);
+                       VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetAllocateInfo.create(
+                               descriptorPool,
+                               frameCount, poolSetLayout,
+                               frame);
+
+                       HandleArray<VkDescriptorSet> descriptorSets = device.device().vkAllocateDescriptorSets(allocInfo, alloc, scope);
+                       for (int i = 0; i < frameCount; i++) {
+                               VkDescriptorBufferInfo bufferInfo = VkDescriptorBufferInfo.create(uniformBuffers[i].buffer(), 0, uniformLayout.byteSize(), frame);
+                               VkWriteDescriptorSet descriptorWrite = VkWriteDescriptorSet.create(
+                                       descriptorSets.get(i),
+                                       0, 0,
+                                       1, Vulkan.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+                                       null, bufferInfo, null, frame);
+                               device.device().vkUpdateDescriptorSets(1, descriptorWrite, 0, null);
+                       }
+
+                       return new UniformBuffers(descriptorPool, descriptorSets, uniformBuffers);
+               }
+       }
+
        // not worth it, its simple enough
        static VkVertexInputAttributeDescription createInputAttributes(SegmentAllocator alloc, int binding, int... loc) {
                int len = loc.length / 3;
index f68a177..b883958 100644 (file)
@@ -33,7 +33,7 @@ THE SOFTWARE.
 package vulkan.test;
 
 import au.notzed.display.Display;
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import au.notzed.nativez.*;
 
 import vulkan.*;
@@ -49,7 +49,7 @@ public class TestCube {
        final static int NUM_SAMPLES = VK_SAMPLE_COUNT_1_BIT;
        final static int NUM_DESCRIPTOR_SETS = 1;
 
-       ResourceScope scope = ResourceScope.newSharedScope();
+       MemorySession scope = MemorySession.openShared();
 
        int width = 800;
        int height = 800;
@@ -758,7 +758,8 @@ public class TestCube {
 
                /* Queue the command buffer for execution */
  /* FIXME: frame shoudl provide or take explicit scope */
-               try ( ResourceScope scope = ResourceScope.newConfinedScope();  Frame frame = Frame.frame()) {
+               try ( MemorySession scope = MemorySession.openConfined();
+                        Frame frame = Frame.frame()) {
                        IntArray pipe_stage_flags = IntArray.create(frame, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
                        VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.create(0, frame);
                        HandleArray<VkFence> fences = VkFence.createArray(1, frame);
index cc139fb..5e42462 100755 (executable)
@@ -45,7 +45,7 @@ import java.awt.Toolkit;
 import java.awt.image.MemoryImageSource;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import au.notzed.nativez.*;
 import java.util.ArrayList;
 import java.util.List;
@@ -56,7 +56,7 @@ import static vulkan.Vulkan.*;
 public class TestMandelbrot {
 
        static final boolean debug = true;
-       ResourceScope scope = ResourceScope.newSharedScope();
+       MemorySession scope = MemorySession.openShared();
 
        int WIDTH = 1920 * 1;
        int HEIGHT = 1080 * 1;
@@ -456,7 +456,7 @@ public class TestMandelbrot {
         * Accesses the gpu buffer, converts it to RGB byte, and saves it as a pam file.
         */
        void save_result() throws Exception {
-               try ( ResourceScope scope = ResourceScope.newConfinedScope()) {
+               try ( MemorySession scope = MemorySession.openConfined()) {
                        MemorySegment mem = device.vkMapMemory(dst.memory(), 0, dstBufferSize, 0, scope);
                        byte[] pixels = new byte[WIDTH * HEIGHT * 3];
 
@@ -475,7 +475,7 @@ public class TestMandelbrot {
        }
 
        void show_result() throws Exception {
-               try ( ResourceScope scope = ResourceScope.newConfinedScope()) {
+               try ( MemorySession scope = MemorySession.openConfined()) {
                        MemorySegment mem = device.vkMapMemory(dst.memory(), 0, dstBufferSize, 0, scope);
                        int[] pixels = new int[WIDTH * HEIGHT];
 
index c292253..3e56451 100644 (file)
@@ -35,7 +35,7 @@ package vulkan.test;
 import au.notzed.display.Display;
 import au.notzed.display.Event;
 import au.notzed.display.Window;
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import au.notzed.nativez.*;
 
 import vulkan.*;
@@ -50,7 +50,7 @@ public class TestSDF {
        final static int NUM_SAMPLES = VK_SAMPLE_COUNT_1_BIT;
        final static int NUM_DESCRIPTOR_SETS = 1;
 
-       ResourceScope scope = ResourceScope.newSharedScope();
+       MemorySession scope = MemorySession.openShared();
 
        int width = 800;
        int height = 800;
@@ -772,7 +772,8 @@ public class TestSDF {
 
                /* Queue the command buffer for execution */
  /* FIXME: frame shoudl provide or take explicit scope */
-               try ( ResourceScope scope = ResourceScope.newConfinedScope();  Frame frame = Frame.frame()) {
+               try ( MemorySession scope = MemorySession.openConfined();
+                        Frame frame = Frame.frame()) {
                        IntArray pipe_stage_flags = IntArray.create(frame, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
                        VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.create(0, frame);
                        HandleArray<VkFence> fences = VkFence.createArray(1, frame);
index c955de3..afc3e79 100644 (file)
@@ -1,6 +1,8 @@
 /*
        Going through the Vulkan Tutorial.
-*/
+
+       Chapter 28-29, Descriptor Layout and Buffer - Descriptor Pool Sets
+ */
 package vulkan.test;
 
 import au.notzed.display.Display;
@@ -11,17 +13,20 @@ import au.notzed.nativez.Frame;
 import au.notzed.nativez.HandleArray;
 import au.notzed.nativez.IntArray;
 import au.notzed.nativez.LongArray;
+import au.notzed.nativez.Memory;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Stream;
-import jdk.incubator.foreign.MemorySegment;
-import jdk.incubator.foreign.ResourceScope;
-import jdk.incubator.foreign.SegmentAllocator;
+import java.lang.foreign.*;
+import java.lang.invoke.MethodHandle;
 import vulkan.VkBuffer;
 import vulkan.VkClearValue;
 import vulkan.VkCommandBuffer;
 import vulkan.VkCommandBufferBeginInfo;
+import vulkan.VkDescriptorSetLayout;
+import vulkan.VkDescriptorSetLayoutBinding;
+import vulkan.VkDescriptorSetLayoutCreateInfo;
 import vulkan.VkDevice;
 import vulkan.VkFence;
 import vulkan.VkFramebuffer;
@@ -29,6 +34,7 @@ import vulkan.VkInstance;
 import vulkan.VkPhysicalDeviceFeatures;
 import vulkan.VkPipeline;
 import vulkan.VkPipelineLayout;
+import vulkan.VkPipelineLayoutCreateInfo;
 import vulkan.VkPresentInfoKHR;
 import vulkan.VkRect2D;
 import vulkan.VkRenderPassBeginInfo;
@@ -75,6 +81,40 @@ public class Tutorial {
                0, 1, 2, 2, 3, 0
        };
 
+       static final class UniformBufferObject {
+
+               final MemorySegment segment;
+
+               UniformBufferObject(MemorySegment segment) {
+                       this.segment = segment;
+               }
+
+               public static UniformBufferObject create(SegmentAllocator alloc) {
+                       return new UniformBufferObject(alloc.allocate(LAYOUT));
+               }
+
+               static final MemoryLayout LAYOUT = MemoryLayout.structLayout(
+                       mat4.LAYOUT.withName("model"),
+                       mat4.LAYOUT.withName("view"),
+                       mat4.LAYOUT.withName("proj"));
+
+               final static MethodHandle model$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("model"));
+               final static MethodHandle view$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("view"));
+               final static MethodHandle proj$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("proj"));
+
+               public MemorySegment model() {
+                       return Memory.slice(segment, model$SH);
+               }
+
+               public MemorySegment view() {
+                       return Memory.slice(segment, view$SH);
+               }
+
+               public MemorySegment proj() {
+                       return Memory.slice(segment, proj$SH);
+               }
+       }
+
        public static record RenderInfo(
                Demo.DemoDevice device,
                Demo.DemoChain chain,
@@ -82,8 +122,9 @@ public class Tutorial {
                VkPipelineLayout pipelineLayout,
                HandleArray<VkCommandBuffer> commandBuffers,
                HandleArray<VkFramebuffer> frameBuffers,
+               Demo.UniformBuffers uniformBuffers,
                Runnable[] resources,
-               ResourceScope scope) {
+               MemorySession scope) {
 
                public void close() {
                        VkDevice d = device.device();
@@ -92,6 +133,8 @@ public class Tutorial {
                        d.vkDestroyPipeline(pipeline);
                        d.vkDestroyPipelineLayout(pipelineLayout);
 
+                       uniformBuffers.close(d);
+
                        for (int i = resources.length - 1; i >= 0; i--)
                                resources[i].run();
 
@@ -104,47 +147,8 @@ public class Tutorial {
                }
        }
 
-       static void rebuildCommandBuffersx(RenderInfo info, int extWidth, int extHeight) {
-               Demo.DemoChain chain = info.chain();
-               HandleArray<VkCommandBuffer> commandBuffers = info.commandBuffers();
-               HandleArray<VkFramebuffer> frameBuffers = info.frameBuffers();
-               VkPipeline pipeline = info.pipeline;
-
-               Demo.resetCommandBuffers(info.device, 0, commandBuffers);
-
-               try ( Frame frame = Frame.frame()) {
-                       VkCommandBufferBeginInfo begin = VkCommandBufferBeginInfo.create(0, null, frame);
-                       VkClearValue clear = VkClearValue.createColour(0, 0, 0, 1, frame);
-                       VkRenderPassBeginInfo render = VkRenderPassBeginInfo.create(
-                               chain.renderPass(), null,
-                               0, 0, extWidth, extHeight,
-                               1, clear,
-                               frame);
-                       VkViewport viewports = VkViewport.create(0, 0, extWidth, extHeight, 0, 1, frame);
-                       VkRect2D scissors = VkRect2D.create(0, 0, extWidth, extHeight, frame);
-
-                       for (int i = 0; i < commandBuffers.size(); i++) {
-                               VkCommandBuffer cmd = commandBuffers.get(i);
-
-                               render.setFramebuffer(frameBuffers.get(i));
-
-                               cmd.vkBeginCommandBuffer(begin);
-                               cmd.vkCmdBeginRenderPass(render, VK_SUBPASS_CONTENTS_INLINE);   // SECONDARY... for sub-rendering?
-
-                               cmd.vkCmdSetViewport(0, 1, viewports);
-                               cmd.vkCmdSetScissor(0, 1, scissors);
-
-                               cmd.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
-                               cmd.vkCmdDraw(3, 1, 0, 0);
-
-                               cmd.vkCmdEndRenderPass();
-                               cmd.vkEndCommandBuffer();
-                       }
-               }
-       }
-
        static RenderInfo createRenderInfo(Demo.DemoDevice device, int pixWidth, int pixHeight, VkShaderModule vertex, VkShaderModule fragment) {
-               ResourceScope scope = ResourceScope.newSharedScope();
+               MemorySession scope = MemorySession.openShared();
                try ( Frame frame = Frame.frame()) {
                        SegmentAllocator alloc = SegmentAllocator.newNativeArena(scope);
                        List<Runnable> cleanup = new ArrayList<>();
@@ -156,12 +160,22 @@ public class Tutorial {
                                VK_PRESENT_MODE_FIFO_KHR,
                                pixWidth, pixHeight, alloc, scope);
 
-                       VkPipelineLayout layout = Demo.dumbPipelineLayout(device.device(), scope);
+                       int frameCount = chain.views().size();
+
+                       // or is this global scope?
+                       VkDescriptorSetLayout descriptorSetLayout = createDescriptorSetLayout(device, scope);
+
+                       var setLayouts = VkDescriptorSetLayout.createArray(1, frame);
+                       setLayouts.setAtIndex(0, descriptorSetLayout);
+                       VkPipelineLayoutCreateInfo layoutInfo = VkPipelineLayoutCreateInfo.create(0, 1, setLayouts, 0, null, frame);
+                       VkPipelineLayout layout = device.device().vkCreatePipelineLayout(layoutInfo, scope);
                        VkPipeline pipeline = Demo.dumbPipeline(device.device(), vertex, fragment, layout, chain.renderPass(), scope);
 
                        // could move to chain?
                        HandleArray<VkFramebuffer> frameBuffers = Demo.createFramebuffers(device, chain, alloc, scope);
-                       HandleArray<VkCommandBuffer> commandBuffers = Demo.createCommandBuffers(device, 0, frameBuffers.size(), alloc, scope);
+                       HandleArray<VkCommandBuffer> commandBuffers = Demo.createCommandBuffers(device, 0, frameCount, alloc, scope);
+
+                       Demo.UniformBuffers uniformBuffers = Demo.createUniformBuffers(device, descriptorSetLayout, UniformBufferObject.LAYOUT, frameCount, alloc, scope);
 
                        // could move creation to Chain?
                        VkCommandBufferBeginInfo begin = VkCommandBufferBeginInfo.create(0, null, frame);
@@ -185,6 +199,7 @@ public class Tutorial {
                        cleanup.add(() -> {
                                indexBuffer.close(device.device());
                                vertexBuffer.close(device.device());
+                               device.device().vkDestroyDescriptorSetLayout(descriptorSetLayout);
                        });
 
                        for (int i = 0; i < commandBuffers.size(); i++) {
@@ -200,21 +215,60 @@ public class Tutorial {
 
                                cmd.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
                                cmd.vkCmdBindVertexBuffers(0, 1, buffers, buffersOffset);
+                               cmd.vkCmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1, uniformBuffers.descriptorSets().asSlice(i, 1), 0, null);
                                cmd.vkCmdBindIndexBuffer(indexBuffer.buffer(), indexBuffer.offset(), Vulkan.VK_INDEX_TYPE_UINT16);
                                cmd.vkCmdDrawIndexed(indices.length, 1, 0, 0, 0);
 
                                cmd.vkCmdEndRenderPass();
                                cmd.vkEndCommandBuffer();
                        }
-                       return new RenderInfo(device, chain, pipeline, layout, commandBuffers, frameBuffers, cleanup.toArray(Runnable[]::new), scope);
+                       return new RenderInfo(device, chain, pipeline, layout, commandBuffers, frameBuffers, uniformBuffers, cleanup.toArray(Runnable[]::new), scope);
                } catch (Throwable t) {
                        scope.close();
                        throw new RuntimeException(t);
                }
        }
 
+       static VkDescriptorSetLayout createDescriptorSetLayout(Demo.DemoDevice device, MemorySession scope) {
+               try ( Frame frame = Frame.frame()) {
+                       VkDescriptorSetLayoutBinding uboLayoutBinding = VkDescriptorSetLayoutBinding.create(0, Vulkan.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, Vulkan.VK_SHADER_STAGE_VERTEX_BIT, null, frame);
+                       VkDescriptorSetLayoutCreateInfo layoutInfo = VkDescriptorSetLayoutCreateInfo.create(0, 1, uboLayoutBinding, frame);
+
+                       return device.device().vkCreateDescriptorSetLayout(layoutInfo, scope);
+               }
+       }
+
+       static long start = System.currentTimeMillis();
+
+       static void updateUniformBuffer(RenderInfo info, int currentImage) {
+               float time = (System.currentTimeMillis() - start) * 1E-3f;
+
+               float[] model;
+               float[] view = new float[16];
+               float[] proj = new float[16];
+
+               model = quat.fromAngle(time * (float)Math.toRadians(90), 0, 0, 1).toMatrix().v;
+               GLMaths.lookAt(view, new float[]{2, 2, 2}, new float[]{0, 0, 0}, new float[]{0, 0, 1});
+               GLMaths.perspective(proj, (float)Math.toRadians(45), (float)info.chain.extWidth() / info.chain.extHeight(), 0.1f, 10f);
+               //proj[5] *= -1;
+
+               try ( Frame frame = Frame.frame()) {
+                       UniformBufferObject ubo = UniformBufferObject.create(frame);
+
+                       ubo.model().copyFrom(MemorySegment.ofArray(model));
+                       ubo.view().copyFrom(MemorySegment.ofArray(view));
+                       ubo.proj().copyFrom(MemorySegment.ofArray(proj));
+
+                       var memory = info.uniformBuffers().uniformBuffers()[currentImage].memory();
+                       MemorySegment buf = info.device.device().vkMapMemory(memory, 0, UniformBufferObject.LAYOUT.byteSize(), 0, frame.scope());
+
+                       buf.copyFrom(ubo.segment);
+                       info.device.device().vkUnmapMemory(memory);
+               }
+       }
+
        public static void main(String[] args) throws IOException, InterruptedException {
-               ResourceScope scope = ResourceScope.globalScope();
+               MemorySession scope = MemorySession.global();
 
                System.loadLibrary("vulkan");
                System.loadLibrary("X11");
@@ -281,8 +335,7 @@ public class Tutorial {
 outer:      while (true) {
                                int res;
 
-                               System.out.println(currentFrame);
-                               for (Event e = window.nextEvent(true); e != null; e = window.nextEvent(false)) {
+                               for (Event e = window.nextEvent(false); e != null; e = window.nextEvent(false)) {
                                        System.out.println(e);
                                        switch (e.type) {
                                        case Event.KEY:
@@ -309,9 +362,9 @@ outer:      while (true) {
                                        }
                                }
 
-                               long next = System.nanoTime();
+                               //long next = System.nanoTime();
                                //System.out.printf(" %12.9f\n", (next - last) * 1E-9);
-                               last = next;
+                               //last = next;
 
                                res = device.device().vkAcquireNextImageKHR(chain.swapchain(), ~0, imageReady.get(currentFrame), null, imageIndex);
                                if (res == VK_SUCCESS || res == VK_SUBOPTIMAL_KHR) {
@@ -332,6 +385,8 @@ outer:      while (true) {
                                                device.device().vkResetFences(1, renderCurrent);
                                        }
 
+                                       updateUniformBuffer(render, index);
+
                                        submitDraw.setWaitSemaphores(imageReady.asSlice(currentFrame));
                                        submitDraw.setSignalSemaphores(renderDone.asSlice(currentFrame));
                                        submitDraw.setCommandBuffers(commandBuffers.asSlice(index));
diff --git a/src/notzed.vulkan.test/classes/vulkan/test/mat.java b/src/notzed.vulkan.test/classes/vulkan/test/mat.java
new file mode 100644 (file)
index 0000000..049a9d1
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2022 Michael Zucchi
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package vulkan.test;
+
+import java.io.PrintStream;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+public class mat {
+
+       public final float[] v;
+       public final int m;
+       public final int n;
+
+       public mat(int m, int n) {
+               this.m = m;
+               this.n = n;
+               this.v = new float[m * n];
+       }
+
+       public mat(int m, int n, float... v) {
+               this.m = m;
+               this.n = n;
+               this.v = v;
+       }
+
+       public float get(int i, int j) {
+               return v[i * n + j];
+       }
+
+       public void set(int i, int j, float val) {
+               v[i * n + j] = val;
+       }
+
+       public void swapRow(int a, int b) {
+               for (int j = 0; j < n; j++) {
+                       float c = v[a * n + j];
+                       float d = v[b * n + j];
+                       v[a * n + j] = d;
+                       v[b * n + j] = c;
+               }
+       }
+
+       public static mat mul(mat A, mat B) {
+               mat C = new mat(A.m, B.n);
+               float[] a = A.v;
+               float[] b = B.v;
+               float[] c = C.v;
+
+               for (int i = 0; i < C.m; i++) {
+                       for (int j = 0; j < C.n; j++) {
+                               float v = 0;
+                               //System.out.printf("[%d]\n", i * C.n + j);
+                               for (int k = 0; k < B.m; k++) {
+                                       //System.out.printf(" %8.3f * %8.3f\n",
+                                       //      a[i * A.n + k], b[j + B.n * k]);
+
+                                       v += a[i * A.n + k] * b[j + B.n * k];
+                               }
+                               //System.out.printf("  = %f\n", v);
+
+                               c[i * C.n + j] = v;
+                       }
+               }
+
+               return C;
+       }
+
+       public static mat transpose(mat A) {
+               float a[] = A.v;
+               float t[] = new float[a.length];
+               int n = A.n;
+               int m = A.m;
+
+               for (int j = 0; j < n; j++) {
+                       for (int i = 0; i < m; i++) {
+                               t[j * m + i] = a[i * n + j];
+                       }
+               }
+
+               return new mat(A.n, A.m, t);
+       }
+
+//    Copyright (C) 2009 Ed Rosten (er258@cam.ac.uk)
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//2. Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+//THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+       public static mat invert(mat A) {
+               // Augmentation is in separate matrix, this is a bit faster
+               mat m = new mat(A.m, A.n, A.v.clone());
+               mat n = new mat(A.m, A.m);
+
+               if (m.v.length < m.m * m.n || n.v.length < n.m * n.n)
+                       throw new ArrayIndexOutOfBoundsException();
+
+               for (int i = 0; i < n.m; i++) {
+                       n.v[i * n.n + i] = 1;
+               }
+
+               //Loop over columns to reduce.
+               for (int col = 0; col < m.m; col++) {
+                       //Reduce the current column to a single element
+                       {
+                               int piv = col;
+                               float max = Math.abs(m.v[piv * m.n + col]);
+                               for (int p = col + 1; p < m.m; p++)
+                                       if (Math.abs(m.v[p * m.n + col]) > max) {
+                                               piv = p;
+                                               max = Math.abs(m.v[piv * m.n + col]);
+                                       }
+
+                               if (col != piv) {
+                                       m.swapRow(col, piv);
+                                       n.swapRow(col, piv);
+                               }
+                       }
+
+                       //Reduce the current column in every row to zero, excluding elements on
+                       //the leading diagonal.
+                       for (int row = 0; row < m.m; row++) {
+                               if (row != col) {
+                                       float multiple = m.v[row * m.n + col] / m.v[col * m.n + col];
+
+                                       //Subtract the pivot row from all other rows, to make
+                                       //column col zero.
+                                       //m.v[row * m.n + col] = 0;
+                                       for (int c = col + 1; c < m.n; c++)
+                                               m.v[row * m.n + c] = m.v[row * m.n + c] - m.v[col * m.n + c] * multiple;
+                                       for (int c = 0; c < n.n; c++)
+                                               n.v[row * n.n + c] = n.v[row * n.n + c] - n.v[col * n.n + c] * multiple;
+                               }
+                       }
+               }
+
+               //Final pass to make diagonal elements one. Performing this in a final
+               //pass allows us to avoid any significant computations on the left-hand
+               //square matrix, since it is diagonal, and ends up as the identity.
+               for (int row = 0; row < m.m; row++) {
+                       float mul = 1 / m.v[row * m.n + row];
+
+                       for (int col = 0; col < n.n; col++) {
+                               n.v[row * n.n + col] *= mul;
+                       }
+               }
+
+               return n;
+       }
+
+       public void print(String name) {
+               print(name, System.out);
+       }
+
+       public void print(String name, PrintStream out) {
+               NumberFormat x = new DecimalFormat("#0.000");
+
+               out.print(name);
+               out.print(" = [");
+               out.print(m);
+               out.print(",");
+               out.print(n);
+               out.println("]");
+
+               for (int i = 0; i < m; i++) {
+                       for (int j = 0; j < n; j++) {
+                               String y = x.format(v[i * n + j]);
+                               out.print(" ");
+                               out.print("        ".substring(y.length()));
+                               out.print(y);
+                       }
+                       out.println();
+               }
+       }
+
+}
diff --git a/src/notzed.vulkan.test/classes/vulkan/test/mat4.java b/src/notzed.vulkan.test/classes/vulkan/test/mat4.java
new file mode 100644 (file)
index 0000000..cccf4ab
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2022 Michael Zucchi
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation +either version 3 of the License +or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not +see <http://www.gnu.org/licenses/>.
+ */
+package vulkan.test;
+
+import au.notzed.nativez.Memory;
+import java.lang.foreign.MemoryLayout;
+
+/**
+ * Partial mat4 implementation.
+ */
+public class mat4 extends mat {
+
+       public mat4() {
+               super(4, 4);
+       }
+
+       public mat4(float... v) {
+               super(4, 4, v);
+
+               if (v.length != 16)
+                       throw new IllegalArgumentException();
+       }
+
+       public static final MemoryLayout LAYOUT = MemoryLayout.sequenceLayout(4 * 4, Memory.FLOAT).withBitAlignment(16 * 8);
+
+       final static float I[] = {
+               1, 0, 0, 0,
+               0, 1, 0, 0,
+               0, 0, 1, 0,
+               0, 0, 0, 1
+       };
+
+       public static mat4 I() {
+               return new mat4(I.clone());
+       }
+
+       public static mat4 translate(float dx, float dy, float dz) {
+               return new mat4(
+                       1, 0, 0, dx,
+                       0, 1, 0, dy,
+                       0, 0, 1, dz,
+                       0, 0, 0, 1);
+       }
+
+       public static mat4 postTranslate(mat4 M, float dx, float dy, float dz) {
+               float[] a = M.v;
+               float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
+               float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
+               float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
+               float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
+               // 1 0 0 dx     a b c d
+               // 0 1 0 dy  x  e f g h
+               // 0 0 1 dz     i j k l
+               // 0 0 0 1      m n o p
+               return new mat4(
+                       a00 + a30 * dx, a01 + a31 * dx, a02 + a32 * dx, a03 + a33 * dx,
+                       a10 + a30 * dy, a11 + a31 * dy, a12 + a32 * dy, a13 + a33 * dy,
+                       a20 + a30 * dz, a21 + a31 * dz, a22 + a32 * dz, a23 + a33 * dz,
+                       a30, a31, a32, a33);
+       }
+
+       public static mat4 preTranslate(mat4 M, float dx, float dy, float dz) {
+               float[] a = M.v;
+               float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
+               float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
+               float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
+               float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
+               // a b c d     1 0 0 dx
+               // e f g h  x  0 1 0 dy
+               // i j k l     0 0 1 dz
+               // m n o p     0 0 0 1
+               return new mat4(
+                       a00, a01, a02, a00 * dx + a01 * dy + a02 * dz + a03,
+                       a10, a11, a12, a10 * dx + a11 * dy + a12 * dz + a13,
+                       a20, a21, a22, a20 * dx + a21 * dy + a22 * dz + a23,
+                       a30, a31, a32, a30 * dx + a31 * dy + a32 * dz + a33);
+       }
+
+       /*
+        array-of-struct (aos) version.  i.e. packed vec4 array.
+
+        This is inefficient for SIMD.
+
+        a b c d   xyzw xyzw ...
+        e f g h
+        i j k l
+        m n o p
+
+        x' = a*x+b*y+c*z+d*w
+        y' = e*x+f*y+g*z+h*w
+        z' = i*x+j*y+k*z+l*w
+        w' = m*x+n*y+o*z+p*w
+        */
+       public static void apply(mat4 A, int n, float[] vec, float[] res) {
+               float a00 = A.v[0];
+               float a01 = A.v[1];
+               float a02 = A.v[2];
+               float a03 = A.v[3];
+               float a10 = A.v[4];
+               float a11 = A.v[5];
+               float a12 = A.v[6];
+               float a13 = A.v[7];
+               float a20 = A.v[8];
+               float a21 = A.v[9];
+               float a22 = A.v[10];
+               float a23 = A.v[11];
+               float a30 = A.v[12];
+               float a31 = A.v[13];
+               float a32 = A.v[14];
+               float a33 = A.v[15];
+
+               for (int i = 0; i < n * 4; i += 4) {
+                       float v0 = vec[i + 0];
+                       float v1 = vec[i + 1];
+                       float v2 = vec[i + 2];
+                       float v3 = vec[i + 3];
+                       res[i + 0] = a00 * v0 + a01 * v1 + a02 * v2 + a03 * v3;
+                       res[i + 1] = a10 * v0 + a11 * v1 + a12 * v2 + a13 * v3;
+                       res[i + 2] = a20 * v0 + a21 * v1 + a22 * v2 + a23 * v3;
+                       res[i + 3] = a30 * v0 + a31 * v1 + a32 * v2 + a33 * v3;
+               }
+       }
+
+
+       /*
+
+       struct-of-array (soa) version
+
+        a b c d   xxxx ...
+        e f g h   yyyy ...
+        i j k l   zzzz ...
+        m n o p   wwww ...
+
+        x' = a*x+b*y+c*z+d*w
+        y' = e*x+f*y+g*z+h*w
+        z' = i*x+j*y+k*z+l*w
+        w' = m*x+n*y+o*z+p*w
+
+        */
+       public static void apply4(mat4 A, int n, float[] vec, int stride, float[] res) {
+               float a00 = A.v[0];
+               float a01 = A.v[1];
+               float a02 = A.v[2];
+               float a03 = A.v[3];
+               float a10 = A.v[4];
+               float a11 = A.v[5];
+               float a12 = A.v[6];
+               float a13 = A.v[7];
+               float a20 = A.v[8];
+               float a21 = A.v[9];
+               float a22 = A.v[10];
+               float a23 = A.v[11];
+               float a30 = A.v[12];
+               float a31 = A.v[13];
+               float a32 = A.v[14];
+               float a33 = A.v[15];
+
+               for (int i = 0; i < n; i += 1) {
+                       float v0 = vec[i + stride * 0];
+                       float v1 = vec[i + stride * 1];
+                       float v2 = vec[i + stride * 2];
+                       float v3 = vec[i + stride * 3];
+
+                       res[i + stride * 0] = a00 * v0 + a01 * v1 + a02 * v2 + a03 * v3;
+                       res[i + stride * 1] = a10 * v0 + a11 * v1 + a12 * v2 + a13 * v3;
+                       res[i + stride * 2] = a20 * v0 + a21 * v1 + a22 * v2 + a23 * v3;
+                       res[i + stride * 3] = a30 * v0 + a31 * v1 + a32 * v2 + a33 * v3;
+               }
+       }
+
+       /*
+        a b c d   x
+        e f g h   y
+        i j k l   z
+        m n o p   w
+
+        x' = a*x+b*y+c*z+d*w
+        y' = e*x+f*y+g*z+h*w
+        z' = i*x+j*y+k*z+l*w
+        w' = m*x+n*y+o*z+p*w
+
+        */
+       public static mat4 mul(mat4 A, mat4 B) {
+               float[] a = A.v;
+               float[] b = B.v;
+               float[] c = new float[16];
+
+               for (int i = 0; i < 4; i++) {
+                       for (int j = 0; j < 4; j++) {
+                               c[i * 4 + j] = a[i * 4] * b[j] + a[i * 4 + 1] * b[j + 4] + a[i * 4 + 2] * b[j + 8] + a[i * 4 + 3] * b[j + 12];
+                       }
+               }
+
+               return new mat4(c);
+       }
+
+       // calculate C' = A x B'
+       //  - B is in col-major order
+       //  - C is in col-major order
+       public static mat mul_NT_T(mat4 A, mat B) {
+               float[] a = A.v;
+               float[] b = B.v;
+               float[] c = new float[b.length];
+               float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
+               float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
+               float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
+               float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
+
+               for (int x = 0; x < c.length; x += 4) {
+                       float b0 = b[x + 0];
+                       float b1 = b[x + 1];
+                       float b2 = b[x + 2];
+                       float b3 = b[x + 3];
+
+                       c[x + 0] = a00 * b0 + a01 * b1 + a02 * b2 + a03 * b3;
+                       c[x + 1] = a10 * b0 + a11 * b1 + a12 * b2 + a13 * b3;
+                       c[x + 2] = a20 * b0 + a21 * b1 + a22 * b2 + a23 * b3;
+                       c[x + 3] = a30 * b0 + a31 * b1 + a32 * b2 + a33 * b3;
+               }
+
+               return new mat(B.m, B.n, c);
+       }
+
+       public static mat4 invert(mat4 A) {
+               // Augmentation is in separate matrix, this is a bit faster
+               // Loop bounds are constant, this is quite a bit faster
+               mat4 m = new mat4(A.v.clone());
+               //mat4 n = new mat4();
+
+               //for (int i = 0; i < 4; i++) {
+               //      n.v[i * 4 + i] = 1;
+               //}
+               mat4 n = new mat4(I.clone());
+
+               if (m.v.length < 16 || n.v.length < 16)
+                       throw new ArrayIndexOutOfBoundsException();
+
+               //Loop over columns to reduce.
+               for (int col = 0; col < 4; col++) {
+                       //Reduce the current column to a single element
+                       {
+                               int piv = col;
+                               float max = Math.abs(m.v[piv * 4 + col]);
+                               for (int p = col + 1; p < 4; p++)
+                                       if (Math.abs(m.v[p * 4 + col]) > max) {
+                                               piv = p;
+                                               max = Math.abs(m.v[piv * 4 + col]);
+                                       }
+
+                               if (col != piv) {
+                                       m.swapRow(col, piv);
+                                       n.swapRow(col, piv);
+                               }
+                       }
+
+                       //Reduce the current column in every row to zero, excluding elements on
+                       //the leading diagonal.
+                       for (int row = 0; row < 4; row++) {
+                               if (row != col) {
+                                       float multiple = m.v[row * 4 + col] / m.v[col * 4 + col];
+
+                                       //Subtract the pivot row from all other rows, to make
+                                       //column col zero.
+                                       //m.v[row * 4 + col] = 0;
+                                       for (int c = col + 1; c < 4; c++)
+                                               m.v[row * 4 + c] = m.v[row * 4 + c] - m.v[col * 4 + c] * multiple;
+                                       for (int c = 0; c < 4; c++)
+                                               n.v[row * 4 + c] = n.v[row * 4 + c] - n.v[col * 4 + c] * multiple;
+                               }
+                       }
+               }
+
+               //Final pass to make diagonal elements one. Performing this in a final
+               //pass allows us to avoid any significant computations on the left-hand
+               //square matrix, since it is diagonal, and ends up as the identity.
+               for (int row = 0; row < 4; row++) {
+                       float mul = 1 / m.v[row * 4 + row];
+
+                       for (int col = 0; col < 4; col++) {
+                               n.v[row * 4 + col] *= mul;
+                       }
+               }
+
+               return n;
+       }
+
+       // from some gl library
+       public static mat4 inverse(mat4 m) {
+               float[] v = m.v;
+               float a00 = v[0], a01 = v[1], a02 = v[2], a03 = v[3],
+                       a10 = v[4], a11 = v[5], a12 = v[6], a13 = v[7],
+                       a20 = v[8], a21 = v[9], a22 = v[10], a23 = v[11],
+                       a30 = v[12], a31 = v[13], a32 = v[14], a33 = v[15],
+                       b00 = a00 * a11 - a01 * a10,
+                       b01 = a00 * a12 - a02 * a10,
+                       b02 = a00 * a13 - a03 * a10,
+                       b03 = a01 * a12 - a02 * a11,
+                       b04 = a01 * a13 - a03 * a11,
+                       b05 = a02 * a13 - a03 * a12,
+                       b06 = a20 * a31 - a21 * a30,
+                       b07 = a20 * a32 - a22 * a30,
+                       b08 = a20 * a33 - a23 * a30,
+                       b09 = a21 * a32 - a22 * a31,
+                       b10 = a21 * a33 - a23 * a31,
+                       b11 = a22 * a33 - a23 * a32,
+                       det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
+
+               return new mat4(
+                       (a11 * b11 - a12 * b10 + a13 * b09) / det,
+                       (a02 * b10 - a01 * b11 - a03 * b09) / det,
+                       (a31 * b05 - a32 * b04 + a33 * b03) / det,
+                       (a22 * b04 - a21 * b05 - a23 * b03) / det,
+                       (a12 * b08 - a10 * b11 - a13 * b07) / det,
+                       (a00 * b11 - a02 * b08 + a03 * b07) / det,
+                       (a32 * b02 - a30 * b05 - a33 * b01) / det,
+                       (a20 * b05 - a22 * b02 + a23 * b01) / det,
+                       (a10 * b10 - a11 * b08 + a13 * b06) / det,
+                       (a01 * b08 - a00 * b10 - a03 * b06) / det,
+                       (a30 * b04 - a31 * b02 + a33 * b00) / det,
+                       (a21 * b02 - a20 * b04 - a23 * b00) / det,
+                       (a11 * b07 - a10 * b09 - a12 * b06) / det,
+                       (a00 * b09 - a01 * b07 + a02 * b06) / det,
+                       (a31 * b01 - a30 * b03 - a32 * b00) / det,
+                       (a20 * b03 - a21 * b01 + a22 * b00) / det);
+       }
+
+}
diff --git a/src/notzed.vulkan.test/classes/vulkan/test/quat.java b/src/notzed.vulkan.test/classes/vulkan/test/quat.java
new file mode 100644 (file)
index 0000000..eba150f
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 Michael Zucchi
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package vulkan.test;
+
+import static java.lang.Math.cos;
+import static java.lang.Math.sin;
+import static java.lang.Math.sqrt;
+
+public class quat {
+
+       private final float x, y, z, w;
+
+       quat(float x, float y, float z, float w) {
+               this.x = x;
+               this.y = y;
+               this.z = z;
+               this.w = w;
+       }
+
+       public String toString() {
+               return String.format("[%8.3f %8.3fi %8.3fj %8.3fk]",
+                       w, x, y, z);
+       }
+
+       static quat mul(quat p, quat q) {
+               float a = p.w;
+               float b = p.x;
+               float c = p.y;
+               float d = p.z;
+
+               float e = q.w;
+               float f = q.x;
+               float g = q.y;
+               float h = q.z;
+
+               return new quat(
+                       b * e + a * f + c * h - d * g,
+                       a * g - b * h + c * e + d * f,
+                       a * h + b * g - c * f + d * e,
+                       a * e - b * f - c * g - d * h);
+       }
+
+       static quat fromVector(float x, float y, float z) {
+               float s = 1.0f / (float)sqrt(x*x+y*y+z*z);
+
+               return new quat(x*s, y*s, z*s, 0);
+       }
+
+       static quat fromAngle(float a, float x, float y, float z) {
+               float ca = (float)cos(a * 0.5f);
+               float sa = (float)sin(a * 0.5f)
+                       / (float)sqrt(x * x + y * y + z * z);
+
+               return new quat(x * sa, y * sa, z * sa, ca);
+       }
+
+       public mat4 toMatrix() {
+               return new mat4(
+                       1 - 2 * z * z - 2 * y * y, 2 * x * y + 2 * z * w, 2 * x * z - 2 * y * w, 0,
+                       2 * x * y - 2 * z * w, 1 - 2 * x * x - 2 * z * z, 2 * y * z + 2 * x * w, 0,
+                       2 * x * z + 2 * y * w, 2 * y * z - 2 * x * w, 1 - 2 * x * x - 2 * y * y, 0,
+                       0, 0, 0, 1
+               );
+       }
+}
index c2c2485..adf50c8 100755 (executable)
@@ -19,12 +19,12 @@ import au.notzed.nativez.Memory;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.channels.Channels;
-import jdk.incubator.foreign.MemorySegment;
-import jdk.incubator.foreign.SegmentAllocator;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SegmentAllocator;
 
 public class ShaderIO {
        static IntArray loadSPIRV(String name, long size, SegmentAllocator alloc) throws IOException {
-               try ( InputStream is = TestMandelbrot.class.getResourceAsStream(name)) {
+               try (InputStream is = TestMandelbrot.class.getResourceAsStream(name)) {
                        MemorySegment seg = alloc.allocateArray(Memory.INT, size);
                        int length = Channels.newChannel(is).read(seg.asByteBuffer());
                        return IntArray.create(seg.asSlice(0, length));
index 48bd441..5ffbb2d 100644 (file)
@@ -1,11 +1,17 @@
 #version 450
 
-layout (location=0) in vec2 inPosition;
-layout (location=1) in vec3 inColour;
+layout(binding = 0) uniform UniformBufferObject {
+    mat4 model;
+    mat4 view;
+    mat4 proj;
+} ubo;
 
-layout (location=0) out vec3 colour;
+layout(location = 0) in vec2 inPosition;
+layout(location = 1) in vec3 inColor;
+
+layout(location = 0) out vec3 fragColor;
 
 void main() {
-       gl_Position = vec4(inPosition, 0.0, 1.0);
-       colour = inColour;
+    gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);
+    fragColor = inColor;
 }
index e8f02f1..e85548e 100644 (file)
@@ -62,7 +62,7 @@ code method-query {
 
 code method-extension {
   dispatch {{
-       final NativeSymbol {name}$NS;
+       final MemorySegment {name}$NS;
   }}
   invoke {{
        /* method-extension:invoke */
@@ -77,7 +77,7 @@ code method-extension {
                {native-result-define}
                try {create-frame}{
                        {native-init}
-                       {native-result-assign}{name}$DH.invokeExact(dispatch.{name}$NS, {invoke-arg});
+                       {native-result-assign}{name}$DH.invokeExact((Addressable)dispatch.{name}$NS, {invoke-arg});
                        {result-test}{
                                {java-result-assign}
                                {java-result-return}
@@ -92,7 +92,7 @@ code method-extension {
 
 code method-extension-query {
   dispatch {{
-       final NativeSymbol {name}$NS;
+       final MemorySegment {name}$NS;
   }}
   invoke {{
        /* method-extension:invoke */
@@ -107,10 +107,10 @@ code method-extension-query {
                {native-result-define}
                try {create-frame}{
                        {native-init}
-                       {native-result-assign}{name}$DH.invokeExact(dispatch.{name}$NS, {query-arg});
+                       {native-result-assign}{name}$DH.invokeExact((Addressable)dispatch.{name}$NS, {query-arg});
                        {result-test}{
                                {query-init}
-                               {native-result-assign}{name}$DH.invokeExact(dispatch.{name}$NS, {invoke-arg});
+                               {native-result-assign}{name}$DH.invokeExact((Addressable)dispatch.{name}$NS, {invoke-arg});
                                {java-result-assign}
                                {java-result-return}
                        }
@@ -133,7 +133,7 @@ code funcpointer {
                {function-descriptor};
   }}
   upcall {{
-       public static FunctionPointer<{rename}> upcall({rename} target$, ResourceScope scope$) {
+       public static FunctionPointer<{rename}> upcall({rename} target$, MemorySession scope$) {
                interface Trampoline {
                        {native-result} call({native-arg});
                }
@@ -166,7 +166,7 @@ code funcpointer-readwrite insert=funcpointer:common,funcpointer:upcall,funcpoin
   class {{
        package {package};
 
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -304,7 +304,7 @@ type pointer value {
        carrier {{ MemoryAddress }}
        layout  {{ Memory.POINTER }}
        type    {{ MemoryAddress }}
-       sig             {{ Ljdk/incubator/foreign/MemoryAddress; }}
+       sig             {{ Ljava/lang/foreign/MemoryAddress; }}
 
        invoke-arg      {{ Memory.address({name}) }}
 }
@@ -318,7 +318,7 @@ type void {
 type void* pointer;
 
 type funcpointer pointer {
-       type            {{ NativeSymbol }}
+       type            {{ MemorySegment }}
 }
 
 # FIXME: clenaup, value-pointer does nothing
@@ -509,7 +509,7 @@ type void*-return void* {
 type funcpointer-return funcpointer need-scope {
        native-result-define    {{ MemoryAddress result$; }}
        native-result-assign    {{ result$ = (MemoryAddress) }}
-       java-result-return              {{ return NativeSymbol.ofAddress(pName, result$, scope$); }}
+       java-result-return              {{ return MemorySegment.ofAddress(result$, 0, scope$); }}
 }
 
 type uint32_t-return uint32_t {
@@ -668,7 +668,7 @@ override commands {
        PFN_vkDebugReportCallbackEXT pUserData=type:void*-ignore;
        PFN_vkDeviceMemoryReportCallbackEXT pUserData=type:void*-ignore;
 
-       # Mapped to a NativeSymbol via 'funcpointer' type
+       # Mapped to a MemorySegment via 'funcpointer' type
        PFN_vkVoidFunction ignore;
 
        # Don't need VkAllocationCallbacks, don't need these
index 89d8876..dcb76c6 100755 (executable)
@@ -1363,10 +1363,10 @@ sub collectFunctionInfo {
        }
 
        $info->{'create-frame'} = '(Frame frame$ = Frame.frame())' if $needFrame;
-       $info->{'trampoline-scope'} = '(ResourceScope scope$$ = ResourceScope.newConfinedScope())' if $trampScope;
+       $info->{'trampoline-scope'} = '(MemorySession scope$$ = MemorySession.openConfined())' if $trampScope;
 
        push @{$info->{'java-arg'}}, 'SegmentAllocator alloc$' if $needAlloc;
-       push @{$info->{'java-arg'}}, 'ResourceScope scope$' if $needScope;
+       push @{$info->{'java-arg'}}, 'MemorySession scope$' if $needScope;
 
        foreach my $field (@arrayFields) {
                my $with = $field =~ m/-arg$/n ? ",\n\t" : "\n\t";
index 77c61ae..b9a784d 100644 (file)
@@ -127,14 +127,14 @@ END
 code handle-array {
   getorset {{
        /* value-array {deref} */
-       public {type} get{Name}(VkInstance instance$, ResourceScope scope$) {
+       public {type} get{Name}(VkInstance instance$, MemorySession scope$) {
                try {
                        return {java-get};
                } catch (Throwable t) {
                        throw new RuntimeException(t);
                }
        }
-       public {typei} get{Name}Element(int i$, VkInstance instance$, ResourceScope scope$) {
+       public {typei} get{Name}Element(int i$, VkInstance instance$, MemorySession scope$) {
                return {java-geti};
        }
        public void set{Name}Element(int i$, {typei} {name}) {
@@ -366,7 +366,7 @@ code Vulkan {
        package {package};
 
        import au.notzed.nativez.Memory;
-       import jdk.incubator.foreign.MemorySegment;
+       import java.lang.foreign.MemorySegment;
        import java.util.Arrays;
 
        public class Vulkan {
@@ -413,19 +413,19 @@ code dispatch {
   class {{
        // template: dispatch:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
        class {Name} {
 
                {field-init}
 
-               {Name}(VkInstance instance$, ResourceScope scope$) {
+               {Name}(VkInstance instance$, MemorySession scope$) {
                        {init}
                }
        }
   }}
-  field-init {{        final NativeSymbol {name}$NS; }}
+  field-init {{        final MemorySegment {name}$NS; }}
   init {{ {name}$NS = instance$.vkGetInstanceProcAddr("{name}", scope$); }}
 
 }
@@ -435,24 +435,24 @@ code handle {
   class {{
        // template: handle:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
        public class {name} implements Pointer {
-               final NativeSymbol self;
+               final MemorySegment self;
 
-               private {name}(MemoryAddress address, ResourceScope scope) {
-                       this.self = NativeSymbol.ofAddress("{name}", address, scope);
+               private {name}(MemoryAddress address, MemorySession scope) {
+                       this.self = MemorySegment.ofAddress(address, 0, scope);
                        {init}
                }
 
-               public static {name} create(MemoryAddress address, ResourceScope scope) {
+               public static {name} create(MemoryAddress address, MemorySession scope) {
                        return address != MemoryAddress.NULL ? new {name}(address, scope) : null;
                }
 
                /** Allocate an array where the handle scope is independent of the array allocation */
-               public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, ResourceScope scope$) {
+               public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, MemorySession scope$) {
                        return HandleArray.createArray(length, alloc, (a, s) -> create(a, scope$));
                }
 
@@ -465,8 +465,8 @@ code handle {
                        return self.address();
                }
 
-               public ResourceScope scope() {
-                       return self.scope();
+               public MemorySession scope() {
+                       return self.session();
                }
 
                public String toString() {
@@ -481,21 +481,21 @@ code handle-instance {
   class {{
        // template: handle-instance:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
        public class {name} implements Pointer {
-               final NativeSymbol self;
+               final MemorySegment self;
                final DispatchInstance dispatch;
 
-               private {name}(MemoryAddress address, ResourceScope scope) {
-                       this.self = NativeSymbol.ofAddress("{name}", address, scope);
+               private {name}(MemoryAddress address, MemorySession scope) {
+                       this.self = MemorySegment.ofAddress(address, 0, scope);
                        this.dispatch = new DispatchInstance(this, scope);
                        {init}
                }
 
-               public static {name} create(MemoryAddress address, ResourceScope scope) {
+               public static {name} create(MemoryAddress address, MemorySession scope) {
                        return new {name}(address, scope);
                }
 
@@ -503,8 +503,8 @@ code handle-instance {
                        return self.address();
                }
 
-               public ResourceScope scope() {
-                       return self.scope();
+               public MemorySession scope() {
+                       return self.session();
                }
 
                {commands}
@@ -517,30 +517,30 @@ code handle-dispatch {
   class {{
        // template: handle-dispatch:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
        public class {name} implements Pointer {
-               final NativeSymbol self;
+               final MemorySegment self;
                final DispatchInstance dispatch;
 
-               private {name}(MemoryAddress address, DispatchInstance dispatch, ResourceScope scope) {
-                       this.self = NativeSymbol.ofAddress("{name}", address, scope);
+               private {name}(MemoryAddress address, DispatchInstance dispatch, MemorySession scope) {
+                       this.self = MemorySegment.ofAddress(address, 0, scope);
                        this.dispatch = dispatch;
                        {init}
                }
 
-               public static {name} create(MemoryAddress address, DispatchInstance dispatch, ResourceScope scope) {
+               public static {name} create(MemoryAddress address, DispatchInstance dispatch, MemorySession scope) {
                        return new {name}(address, dispatch, scope);
                }
 
                // TODO: evaluate how scope fits here
-               public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, DispatchInstance dispatch, ResourceScope scope) {
+               public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, DispatchInstance dispatch, MemorySession scope) {
                        return HandleArray.createArray(length, alloc, (a, s) -> create(a, dispatch, s), scope);
                }
 
-               public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, VkInstance instance, ResourceScope scope) {
+               public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, VkInstance instance, MemorySession scope) {
                        return HandleArray.createArray(length, alloc, (a, s) -> create(a, instance.dispatch, s), scope);
                }
 
@@ -548,8 +548,8 @@ code handle-dispatch {
                        return self.address();
                }
 
-               public ResourceScope scope() {
-                       return self.scope();
+               public MemorySession scope() {
+                       return self.session();
                }
 
                {commands}
@@ -576,7 +576,7 @@ code struct {
                        return new {Name}(segment);
                }
 
-               public static {Name} create(MemoryAddress address, ResourceScope scope) {
+               public static {Name} create(MemoryAddress address, MemorySession scope) {
                        return create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope));
                }
 
@@ -603,8 +603,8 @@ code struct {
 
                // Pointer
                @Override
-               public ResourceScope scope() {
-                       return segment.scope();
+               public MemorySession scope() {
+                       return segment.session();
                }
 
                @Override
@@ -636,7 +636,7 @@ code struct {
                }
   }}
   array {{
-               static {Name} createArray(MemoryAddress addr, long length, ResourceScope scope) {
+               static {Name} createArray(MemoryAddress addr, long length, MemorySession scope) {
                        return create(MemorySegment.ofAddress(addr, length * LAYOUT.byteSize(), scope));
                }
 
@@ -646,7 +646,7 @@ code struct {
                        return self$;
                }
 
-               public final static MethodHandle LAYOUT$SH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement());
+               public final static MethodHandle LAYOUT$SH = MemoryLayout.sequenceLayout(-1, LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement());
 
                // Array
                @Override
@@ -676,7 +676,7 @@ code struct-writeonly insert=struct:header,struct:create-all
   class {{
        // template: struct-writeonly:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -698,7 +698,7 @@ code struct-writeonly-array insert=struct:header,struct:create-all,struct:array
   class {{
        // template: struct-writeonly-array:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -727,7 +727,7 @@ code struct-readonly insert=struct:header
   class {{
        // template: struct-readonly:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -749,7 +749,7 @@ code struct-readonly-array insert=struct:header,struct:array
   class {{
        // template: struct-readonly-array:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -776,7 +776,7 @@ code struct-readwrite insert=struct:header,struct:create-all
   class {{
        // template: struct-readwrite:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -801,7 +801,7 @@ code struct-readwrite-array insert=struct:header,struct:create-all,struct:array
   class {{
        // template: struct-readwrite-array:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -833,7 +833,7 @@ code struct-readwrite-all insert=struct:header,struct:create-all,struct:set-all
   class {{
        // template: struct-readwrite-all:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -858,7 +858,7 @@ code struct-readwrite-array-all insert=struct:header,struct:create-all,struct:ar
   class {{
        // template: struct-readwrite-array-all:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -887,7 +887,7 @@ code struct-writeonly-array-all insert=struct:header,struct:create-all,struct:ar
   class {{
        // template: struct-writeonly-array-all:class
        package {package};
-       import jdk.incubator.foreign.*;
+       import java.lang.foreign.*;
        import java.lang.invoke.*;
        import au.notzed.nativez.*;
 
@@ -923,7 +923,7 @@ type value accessor=value {
 
        native-getat    {{ ({type}){name}$AH.get(this.segment, i$) }}
        native-setat    {{ {name}$AH.set(this.segment, i$, {native-value}) }}
-       handleat                {{ final static VarHandle {name}$AH = MemoryLayout.sequenceLayout(LAYOUT).varHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
+       handleat                {{ final static VarHandle {name}$AH = MemoryLayout.sequenceLayout(-1, LAYOUT).varHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
 
        java-getat              {{ {native-getat} }}
        java-setat              {{ {native-setat} }}
@@ -944,7 +944,7 @@ type value-array accessor=value-array {
 
        native-getat    {{ (MemorySegment){name}$AH.invokeExact(this.segment, i$) }}
        handleat                {{
-               final static MethodHandle {name}$AH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}"));
+               final static MethodHandle {name}$AH = MemoryLayout.sequenceLayout(-1, LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}"));
        }}
        java-getat              {{ {type}.create({native-getat}) }}
 }
@@ -967,7 +967,7 @@ type inline accessor=inline {
 
        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}")); }}
+       handleat        {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(-1, LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
 }
 
 type inline-array accessor=inline {
@@ -977,7 +977,7 @@ type inline-array accessor=inline {
 
        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}")); }}
+       handleat        {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(-1, LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
 }
 
 type uint8_t,char value {
@@ -1074,7 +1074,7 @@ type pointer value {
 type void* pointer;
 
 type value-pointer pointer {
-       java-get        {{ {type}.create((MemoryAddress){name}$VH.get(this.segment), segment.scope()) }}
+       java-get        {{ {type}.create((MemoryAddress){name}$VH.get(this.segment), segment.session()) }}
 }
 
 type uint8_t* value-pointer {
@@ -1098,12 +1098,12 @@ type size_t* value-pointer {
 }
 
 type pointer-length pointer {
-       java-get        {{ {type}.createArray({native-get}, {length}, this.segment.scope()) }}
+       java-get        {{ {type}.createArray({native-get}, {length}, this.segment.session()) }}
 }
 
 type void*-length pointer-length {
        type            MemorySegment;
-       java-get        {{ MemorySegment.ofAddress({native-get}, {length}, this.segment.scope()) }}
+       java-get        {{ MemorySegment.ofAddress({native-get}, {length}, this.segment.session()) }}
 }
 
 type uint8_t*-length pointer-length {
@@ -1150,7 +1150,7 @@ type char**-length pointer-length accessor=value-alloc {
 type funcpointer pointer {
        type            {{ FunctionPointer<{baseType}> }}
        typei           {{ {baseType} }}
-       java-get        {{ {baseType}.downcall({native-get}, this.segment.scope()) }}
+       java-get        {{ {baseType}.downcall({native-get}, this.segment.session()) }}
 }
 
 type void** pointer {
@@ -1162,7 +1162,7 @@ type void**-length pointer-length {
 
 type handle pointer {
        type            {{ {baseType} }}
-       java-get        {{ {type}.create({native-get}, this.segment.scope()) }}
+       java-get        {{ {type}.create({native-get}, this.segment.session()) }}
 }
 
 type handle[] value-array accessor=handle-array {
@@ -1183,7 +1183,7 @@ type handle* pointer {
 type handle*-length pointer-length {
        type            {{ HandleArray<{baseType}> }}
        typei           {{ {baseType} }}
-       java-get        {{ HandleArray.createArray({native-get}, {length}, {typei}::create, this.segment.scope()) }}
+       java-get        {{ HandleArray.createArray({native-get}, {length}, {typei}::create, this.segment.session()) }}
        java-set        {{ {name}$VH.set(this.segment, Memory.address({name})); }}
 }
 
@@ -1199,7 +1199,7 @@ type struct-expand inline accessor=inline-expand {
 
 type struct* pointer {
        type            {{ {baseType} }}
-       java-get        {{ {baseType}.create({native-get}, this.segment.scope()) }}
+       java-get        {{ {baseType}.create({native-get}, this.segment.session()) }}
 }
 
 type struct*-length pointer-length {
@@ -1232,7 +1232,7 @@ override structs {
                        VkPipelineCache pipelineCache,
                        VkGraphicsPipelineCreateInfo pCreateInfos,
                        SegmentAllocator alloc$,
-                       ResourceScope scope$) {
+                       MemorySession scope$) {
                        HandleArray<VkPipeline> pPipelines = VkPipeline.createArray(pCreateInfos.length(), alloc$, scope$);
                        vkCreateGraphicsPipelines(pipelineCache, (int)pCreateInfos.length(), pCreateInfos, pPipelines);
                        // Vulkan.VK_PIPELINE_COMPILE_REQUIRED_EXT ??
@@ -1242,7 +1242,7 @@ override structs {
                public VkPipeline vkCreateGraphicsPipeline(
                        VkPipelineCache pipelineCache,
                        VkGraphicsPipelineCreateInfo pCreateInfo,
-                       ResourceScope scope) {
+                       MemorySession scope) {
                        try (Frame alloc$ = Frame.frame()) {
                                HandleArray<VkPipeline> pPipelines = VkPipeline.createArray(1, alloc$, scope);
                                vkCreateGraphicsPipelines(pipelineCache, 1, pCreateInfo, pPipelines);
@@ -1254,7 +1254,7 @@ override structs {
                public HandleArray<VkCommandBuffer> vkAllocateCommandBuffers(
                                VkCommandBufferAllocateInfo pAllocateInfo,
                                SegmentAllocator alloc$,
-                               ResourceScope scope$) {
+                               MemorySession scope$) {
 
                                var buffers = VkCommandBuffer.createArray(
                                        (int)VkCommandBufferAllocateInfo.commandBufferCount$VH.get(pAllocateInfo.segment),
@@ -1268,7 +1268,7 @@ override structs {
                public HandleArray<VkDescriptorSet> vkAllocateDescriptorSets(
                                VkDescriptorSetAllocateInfo pAllocateInfo,
                                SegmentAllocator alloc$,
-                               ResourceScope scope) {
+                               MemorySession scope) {
 
                                var buffers = VkDescriptorSet.createArray(
                                        (int)VkDescriptorSetAllocateInfo.descriptorSetCount$VH.get(pAllocateInfo.segment),
@@ -1331,13 +1331,13 @@ override structs {
                        return self;
                }
 
-               final static VarHandle colour$float32$EH = MemoryLayout.sequenceLayout(LAYOUT).varHandle(
+               final static VarHandle colour$float32$EH = MemoryLayout.sequenceLayout(-1, LAYOUT).varHandle(
                                MemoryLayout.PathElement.sequenceElement(),
                                MemoryLayout.PathElement.groupElement("color"),
                                MemoryLayout.PathElement.groupElement("float32"),
                                MemoryLayout.PathElement.sequenceElement());
 
-               final static VarHandle colour$int32$EH = MemoryLayout.sequenceLayout(LAYOUT).varHandle(
+               final static VarHandle colour$int32$EH = MemoryLayout.sequenceLayout(-1, LAYOUT).varHandle(
                                MemoryLayout.PathElement.sequenceElement(),
                                MemoryLayout.PathElement.groupElement("color"),
                                MemoryLayout.PathElement.groupElement("int32"),
@@ -1356,12 +1356,12 @@ override structs {
                        colour$int32$EH.set(segment, index, 3, a);
                }
 
-               final static VarHandle depthStencil$depth$EH = MemoryLayout.sequenceLayout(LAYOUT).varHandle(
+               final static VarHandle depthStencil$depth$EH = MemoryLayout.sequenceLayout(-1, LAYOUT).varHandle(
                                MemoryLayout.PathElement.sequenceElement(),
                                MemoryLayout.PathElement.groupElement("depthStencil"),
                                MemoryLayout.PathElement.groupElement("depth"));
 
-               final static VarHandle depthStencil$stencil$EH = MemoryLayout.sequenceLayout(LAYOUT).varHandle(
+               final static VarHandle depthStencil$stencil$EH = MemoryLayout.sequenceLayout(-1, LAYOUT).varHandle(
                                MemoryLayout.PathElement.sequenceElement(),
                                MemoryLayout.PathElement.groupElement("depthStencil"),
                                MemoryLayout.PathElement.groupElement("stencil"));
index 27ff8fc..32656d4 100644 (file)
@@ -1,19 +1,19 @@
 
 package xcb;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import au.notzed.nativez.Pointer;
 
 /* small hack to get it to compile, unimplemented functions so far */
 
 public class Connection implements Pointer {
-       NativeSymbol symbol;
+       MemorySegment symbol;
 
-       public Connection(MemoryAddress addr, ResourceScope scope) {
-               symbol = NativeSymbol.ofAddress("Connection", addr, scope);
+       public Connection(MemoryAddress addr, MemorySession scope) {
+               symbol = MemorySegment.ofAddress(addr, 0, scope);
        }
 
-       public static Connection create(MemoryAddress addr, ResourceScope scope) {
+       public static Connection create(MemoryAddress addr, MemorySession scope) {
                return new Connection(addr, scope);
        }
 
@@ -21,8 +21,8 @@ public class Connection implements Pointer {
                return symbol.address();
        }
 
-       public ResourceScope scope() {
-               return symbol.scope();
+       public MemorySession scope() {
+               return symbol.session();
        }
 
 }