Advance tutorial to chapter 29.
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=\
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=\
# 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}
package au.notzed.display;
-import jdk.incubator.foreign.*;
-import au.notzed.nativez.*;
-
-import vulkan.*;
-import static vulkan.Vulkan.*;
-
import xlib.*;
import static xlib.XLib.*;
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);
}
@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,
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;
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;
import vulkan.VkSwapchainKHR;
import vulkan.VkVertexInputAttributeDescription;
import vulkan.VkVertexInputBindingDescription;
+import vulkan.VkWriteDescriptorSet;
import vulkan.Vulkan;
import static vulkan.Vulkan.*;
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,
}
}
- 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());
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);
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);
}
// 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);
}
- 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),
+ 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,
}
}
- 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,
}
}
- 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);
}
}
- 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);
}
}
- 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],
}
// 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);
}
}
- 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());
}
+ 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;
package vulkan.test;
import au.notzed.display.Display;
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
import au.notzed.nativez.*;
import vulkan.*;
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;
/* 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);
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;
public class TestMandelbrot {
static final boolean debug = true;
- ResourceScope scope = ResourceScope.newSharedScope();
+ MemorySession scope = MemorySession.openShared();
int WIDTH = 1920 * 1;
int HEIGHT = 1080 * 1;
* 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];
}
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];
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.*;
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;
/* 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);
/*
Going through the Vulkan Tutorial.
-*/
+
+ Chapter 28-29, Descriptor Layout and Buffer - Descriptor Pool Sets
+ */
package vulkan.test;
import au.notzed.display.Display;
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;
import vulkan.VkPhysicalDeviceFeatures;
import vulkan.VkPipeline;
import vulkan.VkPipelineLayout;
+import vulkan.VkPipelineLayoutCreateInfo;
import vulkan.VkPresentInfoKHR;
import vulkan.VkRect2D;
import vulkan.VkRenderPassBeginInfo;
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,
VkPipelineLayout pipelineLayout,
HandleArray<VkCommandBuffer> commandBuffers,
HandleArray<VkFramebuffer> frameBuffers,
+ Demo.UniformBuffers uniformBuffers,
Runnable[] resources,
- ResourceScope scope) {
+ MemorySession scope) {
public void close() {
VkDevice d = device.device();
d.vkDestroyPipeline(pipeline);
d.vkDestroyPipelineLayout(pipelineLayout);
+ uniformBuffers.close(d);
+
for (int i = resources.length - 1; i >= 0; i--)
resources[i].run();
}
}
- 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<>();
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);
cleanup.add(() -> {
indexBuffer.close(device.device());
vertexBuffer.close(device.device());
+ device.device().vkDestroyDescriptorSetLayout(descriptorSetLayout);
});
for (int i = 0; i < commandBuffers.size(); i++) {
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");
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:
}
}
- 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) {
device.device().vkResetFences(1, renderCurrent);
}
+ updateUniformBuffer(render, index);
+
submitDraw.setWaitSemaphores(imageReady.asSlice(currentFrame));
submitDraw.setSignalSemaphores(renderDone.asSlice(currentFrame));
submitDraw.setCommandBuffers(commandBuffers.asSlice(index));
--- /dev/null
+/*
+ * 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();
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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);
+ }
+
+}
--- /dev/null
+/*
+ * 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
+ );
+ }
+}
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));
#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;
}
code method-extension {
dispatch {{
- final NativeSymbol {name}$NS;
+ final MemorySegment {name}$NS;
}}
invoke {{
/* method-extension:invoke */
{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}
code method-extension-query {
dispatch {{
- final NativeSymbol {name}$NS;
+ final MemorySegment {name}$NS;
}}
invoke {{
/* method-extension:invoke */
{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}
}
{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});
}
class {{
package {package};
- import jdk.incubator.foreign.*;
+ import java.lang.foreign.*;
import java.lang.invoke.*;
import au.notzed.nativez.*;
carrier {{ MemoryAddress }}
layout {{ Memory.POINTER }}
type {{ MemoryAddress }}
- sig {{ Ljdk/incubator/foreign/MemoryAddress; }}
+ sig {{ Ljava/lang/foreign/MemoryAddress; }}
invoke-arg {{ Memory.address({name}) }}
}
type void* pointer;
type funcpointer pointer {
- type {{ NativeSymbol }}
+ type {{ MemorySegment }}
}
# FIXME: clenaup, value-pointer does nothing
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 {
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
}
$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";
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}) {
package {package};
import au.notzed.nativez.Memory;
- import jdk.incubator.foreign.MemorySegment;
+ import java.lang.foreign.MemorySegment;
import java.util.Arrays;
public class Vulkan {
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$); }}
}
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$));
}
return self.address();
}
- public ResourceScope scope() {
- return self.scope();
+ public MemorySession scope() {
+ return self.session();
}
public String toString() {
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);
}
return self.address();
}
- public ResourceScope scope() {
- return self.scope();
+ public MemorySession scope() {
+ return self.session();
}
{commands}
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);
}
return self.address();
}
- public ResourceScope scope() {
- return self.scope();
+ public MemorySession scope() {
+ return self.session();
}
{commands}
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));
}
// Pointer
@Override
- public ResourceScope scope() {
- return segment.scope();
+ public MemorySession scope() {
+ return segment.session();
}
@Override
}
}}
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));
}
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
class {{
// template: struct-writeonly:class
package {package};
- import jdk.incubator.foreign.*;
+ import java.lang.foreign.*;
import java.lang.invoke.*;
import au.notzed.nativez.*;
class {{
// template: struct-writeonly-array:class
package {package};
- import jdk.incubator.foreign.*;
+ import java.lang.foreign.*;
import java.lang.invoke.*;
import au.notzed.nativez.*;
class {{
// template: struct-readonly:class
package {package};
- import jdk.incubator.foreign.*;
+ import java.lang.foreign.*;
import java.lang.invoke.*;
import au.notzed.nativez.*;
class {{
// template: struct-readonly-array:class
package {package};
- import jdk.incubator.foreign.*;
+ import java.lang.foreign.*;
import java.lang.invoke.*;
import au.notzed.nativez.*;
class {{
// template: struct-readwrite:class
package {package};
- import jdk.incubator.foreign.*;
+ import java.lang.foreign.*;
import java.lang.invoke.*;
import au.notzed.nativez.*;
class {{
// template: struct-readwrite-array:class
package {package};
- import jdk.incubator.foreign.*;
+ import java.lang.foreign.*;
import java.lang.invoke.*;
import au.notzed.nativez.*;
class {{
// template: struct-readwrite-all:class
package {package};
- import jdk.incubator.foreign.*;
+ import java.lang.foreign.*;
import java.lang.invoke.*;
import au.notzed.nativez.*;
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.*;
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.*;
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} }}
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}) }}
}
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 {
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 {
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 {
}
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 {
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 {
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 {
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})); }}
}
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 {
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 ??
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);
public HandleArray<VkCommandBuffer> vkAllocateCommandBuffers(
VkCommandBufferAllocateInfo pAllocateInfo,
SegmentAllocator alloc$,
- ResourceScope scope$) {
+ MemorySession scope$) {
var buffers = VkCommandBuffer.createArray(
(int)VkCommandBufferAllocateInfo.commandBufferCount$VH.get(pAllocateInfo.segment),
public HandleArray<VkDescriptorSet> vkAllocateDescriptorSets(
VkDescriptorSetAllocateInfo pAllocateInfo,
SegmentAllocator alloc$,
- ResourceScope scope) {
+ MemorySession scope) {
var buffers = VkDescriptorSet.createArray(
(int)VkDescriptorSetAllocateInfo.descriptorSetCount$VH.get(pAllocateInfo.segment),
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"),
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"));
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);
}
return symbol.address();
}
- public ResourceScope scope() {
- return symbol.scope();
+ public MemorySession scope() {
+ return symbol.session();
}
}