From aabb3e82deed035f4cf4c2f2d88cff14aee175fe Mon Sep 17 00:00:00 2001 From: knokko Date: Fri, 25 Oct 2024 00:04:35 +0200 Subject: [PATCH] Add MappedVkbBufferRange --- docs/methods.md | 9 +++ .../boiler/buffers/MappedVkbBuffer.java | 17 ++++ .../boiler/buffers/MappedVkbBufferRange.java | 79 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 src/main/java/com/github/knokko/boiler/buffers/MappedVkbBufferRange.java diff --git a/docs/methods.md b/docs/methods.md index a48fdee..6d626ed 100644 --- a/docs/methods.md +++ b/docs/methods.md @@ -28,6 +28,15 @@ tuple `(buffer, byteOffset, byteSize)`. You can obtain an instance by calling the `range(...)` or `fullRange()` method of a `DeviceVkbBuffer` or a `MappedVkbBuffer`. +### MappedVkbBufferRange +The `MappedVkbBufferRange` represents a range of a `MappedVkbBuffer`, +which is a tuple `(mappedBuffer, byteOffset, byteSize)`. You can obtain +an instance by calling the `mappedRange(...)` or `mappedFullRange()` +method of a `MappedVkbBuffer`. It provides `byteBuffer()`, +`shortBuffer()`, etc... methods to create Java NIO buffers whose memory +is backed by the buffer range. It also provides a `range(...)` method to +create a corresponding `VkbBufferRange`. + ### Encoding/decoding images You can use `boiler.buffers.encodeBufferedImageRGBA(...)` to encode/store a `BufferedImage` in a `MappedVkbBuffer` in RGBA8 format. You can use this to diff --git a/src/main/java/com/github/knokko/boiler/buffers/MappedVkbBuffer.java b/src/main/java/com/github/knokko/boiler/buffers/MappedVkbBuffer.java index de79e6f..f34d860 100644 --- a/src/main/java/com/github/knokko/boiler/buffers/MappedVkbBuffer.java +++ b/src/main/java/com/github/knokko/boiler/buffers/MappedVkbBuffer.java @@ -5,4 +5,21 @@ * host-visible memory, and must be mapped at hostAddress during its lifetime. */ public record MappedVkbBuffer(long vkBuffer, long vmaAllocation, long size, long hostAddress) implements VkbBuffer { + + /** + * @return a MappedVkbBufferRange that covers this whole buffer + */ + public MappedVkbBufferRange fullMappedRange() { + return new MappedVkbBufferRange(this, 0L, size); + } + + /** + * @param offset The offset, in bytes + * @param rangeSize The size of the range, in bytes + * @return a MappedVkbBufferRange that covers the bytes [offset, offset + rangeSize> from this buffer + */ + public MappedVkbBufferRange mappedRange(long offset, long rangeSize) { + if (offset + rangeSize > size) throw new IllegalArgumentException(offset + " + " + rangeSize + " > " + size); + return new MappedVkbBufferRange(this, offset, rangeSize); + } } diff --git a/src/main/java/com/github/knokko/boiler/buffers/MappedVkbBufferRange.java b/src/main/java/com/github/knokko/boiler/buffers/MappedVkbBufferRange.java new file mode 100644 index 0000000..6ea1d00 --- /dev/null +++ b/src/main/java/com/github/knokko/boiler/buffers/MappedVkbBufferRange.java @@ -0,0 +1,79 @@ +package com.github.knokko.boiler.buffers; + +import java.nio.*; + +import static org.lwjgl.system.MemoryUtil.*; + +/** + * Represents a range/section of a MappedVkbBuffer + * @param buffer The mapped buffer + * @param offset The offset into the mapped buffer, in bytes + * @param size The size of this range, in bytes + */ +public record MappedVkbBufferRange(MappedVkbBuffer buffer, long offset, long size) { + + /** + * @return The start host address of this buffer range + */ + public long hostAddress() { + return buffer.hostAddress() + offset; + } + + /** + * @return The size of this range in bytes, but represented as integer + * @throws UnsupportedOperationException When the size is larger than Integer.MAX_VALUE + */ + public int intSize() { + if (size > Integer.MAX_VALUE) throw new UnsupportedOperationException("Size (" + size + ") is too large"); + return (int) size; + } + + /** + * @return The corresponding VkbBufferRange + */ + public VkbBufferRange range() { + return new VkbBufferRange(buffer, offset, size); + } + + /** + * @return A direct byte buffer that starts at the start of this range, and has the same capacity + */ + public ByteBuffer byteBuffer() { + return memByteBuffer(hostAddress(), intSize()); + } + + /** + * @return A direct short buffer that starts at the start of this range, with a capacity of size / Short.BYTES + */ + public ShortBuffer shortBuffer() { + return memShortBuffer(hostAddress(), intSize() / Short.BYTES); + } + + /** + * @return A direct int buffer that starts at the start of this range, with a capacity of size / Int.BYTES + */ + public IntBuffer intBuffer() { + return memIntBuffer(hostAddress(), intSize() / Integer.BYTES); + } + + /** + * @return A direct float buffer that starts at the start of this range, with a capacity of size / Float.BYTES + */ + public FloatBuffer floatBuffer() { + return memFloatBuffer(hostAddress(), intSize() / Float.BYTES); + } + + /** + * @return A direct long buffer that starts at the start of this range, with a capacity of size / Long.BYTES + */ + public LongBuffer longBuffer() { + return memLongBuffer(hostAddress(), intSize() / Long.BYTES); + } + + /** + * @return A direct double buffer that starts at the start of this range, with a capacity of size / Double.BYTES + */ + public DoubleBuffer doubleBuffer() { + return memDoubleBuffer(hostAddress(), intSize() / Double.BYTES); + } +}