Skip to content

Commit ed6096e

Browse files
committed
extract GpuBuffer into an interface; create VersionedBuffer in preparation of multiple simultaneous frames
1 parent 72b0156 commit ed6096e

File tree

7 files changed

+225
-98
lines changed

7 files changed

+225
-98
lines changed

jme3-examples/src/main/java/jme3test/vulkan/VulkanHelperTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ public void accept(Float tpf) {
374374
vkCmdSetScissor(graphicsCommands.getBuffer(), 0, scissor);
375375

376376
// mesh
377-
vkCmdBindVertexBuffers(graphicsCommands.getBuffer(), 0, stack.longs(vertexBuffer.getNativeObject()), stack.longs(0));
378-
vkCmdBindIndexBuffer(graphicsCommands.getBuffer(), indexBuffer.getNativeObject(), 0, VK_INDEX_TYPE_UINT32);
377+
vkCmdBindVertexBuffers(graphicsCommands.getBuffer(), 0, stack.longs(vertexBuffer.getId()), stack.longs(0));
378+
vkCmdBindIndexBuffer(graphicsCommands.getBuffer(), indexBuffer.getId(), 0, VK_INDEX_TYPE_UINT32);
379379
vkCmdDrawIndexed(graphicsCommands.getBuffer(), indexData.limit(), 1, 0, 0, 0);
380380

381381
}
Lines changed: 26 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,122 @@
11
package com.jme3.vulkan.buffers;
22

3-
import com.jme3.renderer.vulkan.VulkanUtils;
43
import com.jme3.util.natives.Native;
5-
import com.jme3.util.natives.NativeReference;
64
import com.jme3.vulkan.commands.CommandBuffer;
75
import com.jme3.vulkan.devices.LogicalDevice;
8-
import com.jme3.vulkan.memory.MemoryFlag;
9-
import com.jme3.vulkan.memory.MemoryRegion;
106
import com.jme3.vulkan.memory.MemorySize;
11-
import com.jme3.vulkan.util.Flag;
127
import org.lwjgl.PointerBuffer;
138
import org.lwjgl.system.MemoryStack;
149
import org.lwjgl.system.MemoryUtil;
1510
import org.lwjgl.system.Struct;
1611
import org.lwjgl.system.StructBuffer;
1712
import org.lwjgl.vulkan.VkBufferCopy;
18-
import org.lwjgl.vulkan.VkBufferCreateInfo;
19-
import org.lwjgl.vulkan.VkMemoryRequirements;
2013

2114
import java.nio.*;
2215
import java.util.function.Function;
2316

24-
import static com.jme3.renderer.vulkan.VulkanUtils.*;
2517
import static org.lwjgl.vulkan.VK10.*;
2618

27-
public class GpuBuffer implements Native<Long> {
28-
29-
private final LogicalDevice<?> device;
30-
private final NativeReference ref;
31-
private final MemorySize size;
32-
private final long id;
33-
protected final MemoryRegion memory;
34-
35-
public GpuBuffer(LogicalDevice<?> device, MemorySize size, Flag<BufferUsage> usage, Flag<MemoryFlag> mem, boolean concurrent) {
36-
this.device = device;
37-
this.size = size;
38-
try (MemoryStack stack = MemoryStack.stackPush()) {
39-
VkBufferCreateInfo create = VkBufferCreateInfo.calloc(stack)
40-
.sType(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
41-
.size(size.getBytes())
42-
.usage(usage.bits())
43-
.sharingMode(VulkanUtils.sharingMode(concurrent));
44-
LongBuffer idBuf = stack.mallocLong(1);
45-
check(vkCreateBuffer(device.getNativeObject(), create, null, idBuf),
46-
"Failed to create buffer.");
47-
id = idBuf.get(0);
48-
VkMemoryRequirements bufferMem = VkMemoryRequirements.malloc(stack);
49-
vkGetBufferMemoryRequirements(device.getNativeObject(), id, bufferMem);
50-
memory = new MemoryRegion(device, bufferMem.size(), device.getPhysicalDevice().findSupportedMemoryType(
51-
stack, bufferMem.memoryTypeBits(), mem));
52-
memory.bind(this, 0);
53-
}
54-
ref = Native.get().register(this);
55-
device.getNativeReference().addDependent(ref);
56-
memory.getNativeReference().addDependent(ref);
57-
}
19+
public interface GpuBuffer {
5820

59-
@Override
60-
public Long getNativeObject() {
61-
return id;
62-
}
21+
PointerBuffer map(MemoryStack stack, int offset, int size, int flags);
6322

64-
@Override
65-
public Runnable createNativeDestroyer() {
66-
return () -> vkDestroyBuffer(device.getNativeObject(), id, null);
67-
}
23+
void unmap();
6824

69-
@Override
70-
public void prematureNativeDestruction() {}
25+
void freeMemory();
7126

72-
@Override
73-
public NativeReference getNativeReference() {
74-
return ref;
75-
}
27+
MemorySize size();
28+
29+
long getId();
7630

77-
private void verifyBufferSize(int elements, long bytesPerElement) {
78-
if (elements * bytesPerElement > size.getBytes()) {
31+
default void verifyBufferSize(int elements, long bytesPerElement) {
32+
if (elements * bytesPerElement > size().getBytes()) {
7933
throw new BufferOverflowException();
8034
}
8135
}
8236

83-
public PointerBuffer map(MemoryStack stack, int offset, int size, int flags) {
84-
return memory.map(stack, offset, size, flags);
85-
}
86-
87-
public ByteBuffer mapBytes(MemoryStack stack, int offset, int size, int flags) {
37+
default ByteBuffer mapBytes(MemoryStack stack, int offset, int size, int flags) {
8838
return map(stack, offset, size, flags).getByteBuffer(0, size);
8939
}
9040

91-
public ShortBuffer mapShorts(MemoryStack stack, int offset, int size, int flags) {
41+
default ShortBuffer mapShorts(MemoryStack stack, int offset, int size, int flags) {
9242
return map(stack, offset, size * Short.BYTES, flags).getShortBuffer(0, size);
9343
}
9444

95-
public IntBuffer mapInts(MemoryStack stack, int offset, int size, int flags) {
45+
default IntBuffer mapInts(MemoryStack stack, int offset, int size, int flags) {
9646
return map(stack, offset, size * Integer.BYTES, flags).getIntBuffer(0, size);
9747
}
9848

99-
public FloatBuffer mapFloats(MemoryStack stack, int offset, int size, int flags) {
49+
default FloatBuffer mapFloats(MemoryStack stack, int offset, int size, int flags) {
10050
return map(stack, offset, size * Float.BYTES, flags).getFloatBuffer(0, size);
10151
}
10252

103-
public DoubleBuffer mapDoubles(MemoryStack stack, int offset, int size, int flags) {
53+
default DoubleBuffer mapDoubles(MemoryStack stack, int offset, int size, int flags) {
10454
return map(stack, offset, size * Double.BYTES, flags).getDoubleBuffer(0, size);
10555
}
10656

107-
public LongBuffer mapLongs(MemoryStack stack, int offset, int size, int flags) {
57+
default LongBuffer mapLongs(MemoryStack stack, int offset, int size, int flags) {
10858
return map(stack, offset, size * Long.BYTES, flags).getLongBuffer(0, size);
10959
}
11060

111-
public <T> T mapObject(MemoryStack stack, int offset, int size, int flags, Function<PointerBuffer, T> factory) {
61+
default <T> T mapObject(MemoryStack stack, int offset, int size, int flags, Function<PointerBuffer, T> factory) {
11262
return factory.apply(map(stack, offset, size, flags));
11363
}
11464

115-
public void copy(MemoryStack stack, ByteBuffer buffer) {
65+
default void copy(MemoryStack stack, ByteBuffer buffer) {
11666
verifyBufferSize(buffer.limit(), Byte.BYTES);
11767
MemoryUtil.memCopy(buffer, mapBytes(stack, 0, buffer.limit(), 0));
11868
unmap();
11969
}
12070

121-
public void copy(MemoryStack stack, ShortBuffer buffer) {
71+
default void copy(MemoryStack stack, ShortBuffer buffer) {
12272
verifyBufferSize(buffer.limit(), Short.BYTES);
12373
MemoryUtil.memCopy(buffer, mapShorts(stack, 0, buffer.limit(), 0));
12474
unmap();
12575
}
12676

127-
public void copy(MemoryStack stack, IntBuffer buffer) {
77+
default void copy(MemoryStack stack, IntBuffer buffer) {
12878
verifyBufferSize(buffer.limit(), Integer.BYTES);
12979
MemoryUtil.memCopy(buffer, mapInts(stack, 0, buffer.limit(), 0));
13080
unmap();
13181
}
13282

133-
public void copy(MemoryStack stack, FloatBuffer buffer) {
83+
default void copy(MemoryStack stack, FloatBuffer buffer) {
13484
verifyBufferSize(buffer.limit(), Float.BYTES);
13585
MemoryUtil.memCopy(buffer, mapFloats(stack, 0, buffer.limit(), 0));
13686
unmap();
13787
}
13888

139-
public void copy(MemoryStack stack, DoubleBuffer buffer) {
89+
default void copy(MemoryStack stack, DoubleBuffer buffer) {
14090
verifyBufferSize(buffer.limit(), Double.BYTES);
14191
MemoryUtil.memCopy(buffer, mapDoubles(stack, 0, buffer.limit(), 0));
14292
unmap();
14393
}
14494

145-
public void copy(MemoryStack stack, LongBuffer buffer) {
95+
default void copy(MemoryStack stack, LongBuffer buffer) {
14696
verifyBufferSize(buffer.limit(), Long.BYTES);
14797
MemoryUtil.memCopy(buffer, mapLongs(stack, 0, buffer.limit(), 0));
14898
unmap();
14999
}
150100

151-
public void copy(MemoryStack stack, Struct<?> struct) {
101+
default void copy(MemoryStack stack, Struct<?> struct) {
152102
verifyBufferSize(struct.sizeof(), Byte.BYTES);
153103
MemoryUtil.memCopy(MemoryUtil.memByteBuffer(struct.address(), struct.sizeof()),
154104
mapBytes(stack, 0, struct.sizeof(), 0));
155105
unmap();
156106
}
157107

158-
public void copy(MemoryStack stack, StructBuffer<?, ?> buffer) {
108+
default void copy(MemoryStack stack, StructBuffer<?, ?> buffer) {
159109
verifyBufferSize(buffer.limit(), buffer.sizeof());
160110
int size = buffer.limit() * buffer.sizeof();
161111
MemoryUtil.memCopy(MemoryUtil.memByteBuffer(buffer.address(), size), mapBytes(stack, 0, size, 0));
162112
unmap();
163113
}
164114

165-
public void unmap() {
166-
memory.unmap();
167-
}
168-
169-
public void recordCopy(MemoryStack stack, CommandBuffer commands, GpuBuffer source,
115+
default void recordCopy(MemoryStack stack, CommandBuffer commands, GpuBuffer source,
170116
long srcOffset, long dstOffset, long size) {
171117
VkBufferCopy.Buffer copy = VkBufferCopy.calloc(1, stack)
172118
.srcOffset(srcOffset).dstOffset(dstOffset).size(size);
173-
vkCmdCopyBuffer(commands.getBuffer(), source.getNativeObject(), id, copy);
174-
}
175-
176-
public void freeMemory() {
177-
memory.getNativeReference().destroy();
178-
}
179-
180-
public MemorySize size() {
181-
return size;
182-
}
183-
184-
public LogicalDevice<?> getDevice() {
185-
return device;
119+
vkCmdCopyBuffer(commands.getBuffer(), source.getNativeObject(), getNativeObject(), copy);
186120
}
187121

188122
}

jme3-lwjgl3/src/main/java/com/jme3/vulkan/buffers/PersistentBuffer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.jme3.vulkan.buffers;
22

3+
import com.jme3.vulkan.VulkanObject;
34
import com.jme3.vulkan.devices.LogicalDevice;
45
import com.jme3.vulkan.memory.MemoryFlag;
56
import com.jme3.vulkan.memory.MemorySize;
67
import com.jme3.vulkan.util.Flag;
78
import org.lwjgl.PointerBuffer;
89
import org.lwjgl.system.MemoryStack;
910

10-
public class PersistentBuffer extends GpuBuffer {
11+
public class PersistentBuffer extends VulkanBuffer {
1112

1213
private final long address;
1314

jme3-lwjgl3/src/main/java/com/jme3/vulkan/buffers/StageableBuffer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
import org.lwjgl.PointerBuffer;
1111
import org.lwjgl.system.MemoryStack;
1212

13-
public class StageableBuffer extends GpuBuffer {
13+
public class StageableBuffer extends VulkanBuffer {
1414

15-
private final GpuBuffer stage;
15+
private final VulkanBuffer stage;
1616

1717
public StageableBuffer(LogicalDevice device, MemorySize size,
1818
Flag<BufferUsage> usage, Flag<MemoryFlag> mem, boolean concurrent) {
1919
super(device, size, usage.add(BufferUsage.TransferDst), mem, concurrent);
20-
this.stage = new GpuBuffer(device, size, BufferUsage.TransferSrc,
20+
this.stage = new VulkanBuffer(device, size, BufferUsage.TransferSrc,
2121
Flag.of(MemoryFlag.HostVisible, MemoryFlag.HostCoherent), concurrent);
2222
}
2323

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.jme3.vulkan.buffers;
2+
3+
import com.jme3.vulkan.memory.MemorySize;
4+
import org.lwjgl.PointerBuffer;
5+
import org.lwjgl.system.MemoryStack;
6+
7+
public class VersionedBuffer implements GpuBuffer {
8+
9+
private final GpuBuffer[] buffers;
10+
private int version = 0;
11+
private boolean mapped = false;
12+
13+
public VersionedBuffer(GpuBuffer... buffers) {
14+
assert buffers.length > 0;
15+
this.buffers = buffers;
16+
MemorySize standard = buffers[0].size();
17+
for (int i = 1; i < buffers.length; i++) {
18+
if (!buffers[i].size().equals(standard)) {
19+
throw new IllegalArgumentException("All buffers must be of equivalent size.");
20+
}
21+
}
22+
}
23+
24+
@Override
25+
public PointerBuffer map(MemoryStack stack, int offset, int size, int flags) {
26+
mapped = true;
27+
return buffers[version].map(stack, offset, size, flags);
28+
}
29+
30+
@Override
31+
public void unmap() {
32+
mapped = false;
33+
buffers[version].unmap();
34+
}
35+
36+
@Override
37+
public void freeMemory() {
38+
for (GpuBuffer buf : buffers) {
39+
buf.freeMemory();
40+
}
41+
}
42+
43+
@Override
44+
public MemorySize size() {
45+
return buffers[version].size();
46+
}
47+
48+
@Override
49+
public long getId() {
50+
return buffers[version].getId();
51+
}
52+
53+
public void setVersion(int version) {
54+
if (mapped) {
55+
throw new IllegalStateException("Cannot change version while buffer is mapped.");
56+
}
57+
if (version < 0 || version >= buffers.length) {
58+
throw new IndexOutOfBoundsException("Version must be between 0 (inclusive) and the number of internal buffers (exclusive).");
59+
}
60+
this.version = version;
61+
}
62+
63+
public GpuBuffer[] getInternalBuffers() {
64+
return buffers;
65+
}
66+
67+
public int getVersion() {
68+
return version;
69+
}
70+
71+
}

0 commit comments

Comments
 (0)