From bc35154bc48c7ef3bbb03d91d1a8615768b74694 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Sun, 25 Sep 2022 22:11:43 +0930 Subject: [PATCH] Update to OpenJDK 19 java.lang.foriegn. Advance tutorial to chapter 29. --- nbproject/project.properties | 8 +- .../classes/au/notzed/display/Display.java | 6 - .../classes/au/notzed/display/Window.java | 7 +- .../classes/vulkan/test/Demo.java | 108 ++++-- .../classes/vulkan/test/TestCube.java | 7 +- .../classes/vulkan/test/TestMandelbrot.java | 8 +- .../classes/vulkan/test/TestSDF.java | 7 +- .../classes/vulkan/test/Tutorial.java | 161 ++++++--- .../classes/vulkan/test/mat.java | 207 +++++++++++ .../classes/vulkan/test/mat4.java | 341 ++++++++++++++++++ .../classes/vulkan/test/quat.java | 79 ++++ src/notzed.vulkan.test/gen/generate-shaderio | 6 +- .../shaders/vulkan/test/tutorial.vert | 16 +- src/notzed.vulkan/gen/command-types.api | 22 +- src/notzed.vulkan/gen/generate-vulkan | 4 +- src/notzed.vulkan/gen/struct-types.api | 126 +++---- src/notzed.xcb/classes/xcb/Connection.java | 14 +- 17 files changed, 937 insertions(+), 190 deletions(-) create mode 100644 src/notzed.vulkan.test/classes/vulkan/test/mat.java create mode 100644 src/notzed.vulkan.test/classes/vulkan/test/mat4.java create mode 100644 src/notzed.vulkan.test/classes/vulkan/test/quat.java diff --git a/nbproject/project.properties b/nbproject/project.properties index 484a1fa..b0c5f0d 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -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} diff --git a/src/notzed.display/classes/au/notzed/display/Display.java b/src/notzed.display/classes/au/notzed/display/Display.java index 55806b8..e418279 100644 --- a/src/notzed.display/classes/au/notzed/display/Display.java +++ b/src/notzed.display/classes/au/notzed/display/Display.java @@ -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.*; diff --git a/src/notzed.display/classes/au/notzed/display/Window.java b/src/notzed.display/classes/au/notzed/display/Window.java index ef1106b..b2a9755 100644 --- a/src/notzed.display/classes/au/notzed/display/Window.java +++ b/src/notzed.display/classes/au/notzed/display/Window.java @@ -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, diff --git a/src/notzed.vulkan.test/classes/vulkan/test/Demo.java b/src/notzed.vulkan.test/classes/vulkan/test/Demo.java index ff3cfc5..a803f13 100644 --- a/src/notzed.vulkan.test/classes/vulkan/test/Demo.java +++ b/src/notzed.vulkan.test/classes/vulkan/test/Demo.java @@ -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 createSemaphores(int count, SegmentAllocator alloc, ResourceScope scope) { + public HandleArray createSemaphores(int count, SegmentAllocator alloc, MemorySession scope) { HandleArray 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 createFences(int count, int flags, SegmentAllocator alloc, ResourceScope scope) { + public HandleArray createFences(int count, int flags, SegmentAllocator alloc, MemorySession scope) { HandleArray 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 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 createFramebuffers(DemoDevice device, DemoChain chain, SegmentAllocator alloc, ResourceScope scope) { + public static HandleArray createFramebuffers(DemoDevice device, DemoChain chain, SegmentAllocator alloc, MemorySession scope) { try ( Frame frame = Frame.frame()) { var frameBuffers = VkFramebuffer.createArray(chain.views.length(), alloc); HandleArray attachments = VkImageView.createArray(1, frame); @@ -682,7 +685,7 @@ public class Demo { } } - public static HandleArray createCommandBuffers(DemoDevice device, int appIndex, int count, SegmentAllocator alloc, ResourceScope scope) { + public static HandleArray 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 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 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; diff --git a/src/notzed.vulkan.test/classes/vulkan/test/TestCube.java b/src/notzed.vulkan.test/classes/vulkan/test/TestCube.java index f68a177..b883958 100644 --- a/src/notzed.vulkan.test/classes/vulkan/test/TestCube.java +++ b/src/notzed.vulkan.test/classes/vulkan/test/TestCube.java @@ -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 fences = VkFence.createArray(1, frame); diff --git a/src/notzed.vulkan.test/classes/vulkan/test/TestMandelbrot.java b/src/notzed.vulkan.test/classes/vulkan/test/TestMandelbrot.java index cc139fb..5e42462 100755 --- a/src/notzed.vulkan.test/classes/vulkan/test/TestMandelbrot.java +++ b/src/notzed.vulkan.test/classes/vulkan/test/TestMandelbrot.java @@ -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]; diff --git a/src/notzed.vulkan.test/classes/vulkan/test/TestSDF.java b/src/notzed.vulkan.test/classes/vulkan/test/TestSDF.java index c292253..3e56451 100644 --- a/src/notzed.vulkan.test/classes/vulkan/test/TestSDF.java +++ b/src/notzed.vulkan.test/classes/vulkan/test/TestSDF.java @@ -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 fences = VkFence.createArray(1, frame); diff --git a/src/notzed.vulkan.test/classes/vulkan/test/Tutorial.java b/src/notzed.vulkan.test/classes/vulkan/test/Tutorial.java index c955de3..afc3e79 100644 --- a/src/notzed.vulkan.test/classes/vulkan/test/Tutorial.java +++ b/src/notzed.vulkan.test/classes/vulkan/test/Tutorial.java @@ -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 commandBuffers, HandleArray 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 commandBuffers = info.commandBuffers(); - HandleArray 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 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 frameBuffers = Demo.createFramebuffers(device, chain, alloc, scope); - HandleArray commandBuffers = Demo.createCommandBuffers(device, 0, frameBuffers.size(), alloc, scope); + HandleArray 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 index 0000000..049a9d1 --- /dev/null +++ b/src/notzed.vulkan.test/classes/vulkan/test/mat.java @@ -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 . + */ +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 index 0000000..cccf4ab --- /dev/null +++ b/src/notzed.vulkan.test/classes/vulkan/test/mat4.java @@ -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 . + */ +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 index 0000000..eba150f --- /dev/null +++ b/src/notzed.vulkan.test/classes/vulkan/test/quat.java @@ -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 . + */ +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 + ); + } +} diff --git a/src/notzed.vulkan.test/gen/generate-shaderio b/src/notzed.vulkan.test/gen/generate-shaderio index c2c2485..adf50c8 100755 --- a/src/notzed.vulkan.test/gen/generate-shaderio +++ b/src/notzed.vulkan.test/gen/generate-shaderio @@ -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)); diff --git a/src/notzed.vulkan.test/shaders/vulkan/test/tutorial.vert b/src/notzed.vulkan.test/shaders/vulkan/test/tutorial.vert index 48bd441..5ffbb2d 100644 --- a/src/notzed.vulkan.test/shaders/vulkan/test/tutorial.vert +++ b/src/notzed.vulkan.test/shaders/vulkan/test/tutorial.vert @@ -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; } diff --git a/src/notzed.vulkan/gen/command-types.api b/src/notzed.vulkan/gen/command-types.api index e8f02f1..e85548e 100644 --- a/src/notzed.vulkan/gen/command-types.api +++ b/src/notzed.vulkan/gen/command-types.api @@ -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 diff --git a/src/notzed.vulkan/gen/generate-vulkan b/src/notzed.vulkan/gen/generate-vulkan index 89d8876..dcb76c6 100755 --- a/src/notzed.vulkan/gen/generate-vulkan +++ b/src/notzed.vulkan/gen/generate-vulkan @@ -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"; diff --git a/src/notzed.vulkan/gen/struct-types.api b/src/notzed.vulkan/gen/struct-types.api index 77c61ae..b9a784d 100644 --- a/src/notzed.vulkan/gen/struct-types.api +++ b/src/notzed.vulkan/gen/struct-types.api @@ -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 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 pPipelines = VkPipeline.createArray(1, alloc$, scope); vkCreateGraphicsPipelines(pipelineCache, 1, pCreateInfo, pPipelines); @@ -1254,7 +1254,7 @@ override structs { public HandleArray 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 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")); diff --git a/src/notzed.xcb/classes/xcb/Connection.java b/src/notzed.xcb/classes/xcb/Connection.java index 27ff8fc..32656d4 100644 --- a/src/notzed.xcb/classes/xcb/Connection.java +++ b/src/notzed.xcb/classes/xcb/Connection.java @@ -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(); } } -- 2.39.2