-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
297 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
src/main/java/com/github/knokko/boiler/buffers/MappedVkbBufferRange.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package com.github.knokko.boiler.buffers; | ||
|
||
import java.nio.*; | ||
|
||
import static org.lwjgl.system.MemoryUtil.*; | ||
|
||
public record MappedVkbBufferRange(MappedVkbBuffer buffer, long offset, long size) { | ||
|
||
long hostAddress() { | ||
return buffer.hostAddress() + offset; | ||
} | ||
|
||
int intSize() { | ||
if (size > Integer.MAX_VALUE) throw new UnsupportedOperationException("Size (" + size + ") is too large"); | ||
return (int) size; | ||
} | ||
|
||
VkbBufferRange range() { | ||
return new VkbBufferRange(buffer, offset, size); | ||
} | ||
|
||
ByteBuffer byteBuffer() { | ||
return memByteBuffer(hostAddress(), intSize()); | ||
} | ||
|
||
ShortBuffer shortBuffer() { | ||
return memShortBuffer(hostAddress(), intSize() / Short.BYTES); | ||
} | ||
|
||
IntBuffer intBuffer() { | ||
return memIntBuffer(hostAddress(), intSize() / Integer.BYTES); | ||
} | ||
|
||
FloatBuffer floatBuffer() { | ||
return memFloatBuffer(hostAddress(), intSize() / Float.BYTES); | ||
} | ||
|
||
LongBuffer longBuffer() { | ||
return memLongBuffer(hostAddress(), intSize() / Long.BYTES); | ||
} | ||
|
||
DoubleBuffer doubleBuffer() { | ||
return memDoubleBuffer(hostAddress(), intSize() / Double.BYTES); | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/com/github/knokko/boiler/buffers/SharedBufferBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.github.knokko.boiler.buffers; | ||
|
||
import com.github.knokko.boiler.BoilerInstance; | ||
|
||
import java.util.function.Supplier; | ||
|
||
import static com.github.knokko.boiler.utilities.BoilerMath.nextMultipleOf; | ||
|
||
public abstract class SharedBufferBuilder<B extends VkbBuffer, R> { | ||
|
||
protected final BoilerInstance instance; | ||
private long totalSize = 0L; | ||
private B buffer; | ||
|
||
public SharedBufferBuilder(BoilerInstance instance) { | ||
this.instance = instance; | ||
} | ||
|
||
public Supplier<R> add(long size, long alignment) { | ||
if (alignment > 0L) totalSize = nextMultipleOf(totalSize, alignment); | ||
long offset = totalSize; | ||
totalSize += size; | ||
|
||
return () -> { | ||
if (buffer == null) throw new IllegalStateException("Buffer hasn't been built yet"); | ||
return createRange(buffer, offset, size); | ||
}; | ||
} | ||
|
||
public B build(int usage, String name) { | ||
this.buffer = buildBuffer(totalSize, usage, name); | ||
return this.buffer; | ||
} | ||
|
||
protected abstract B buildBuffer(long size, int usage, String name); | ||
|
||
protected abstract R createRange(B buffer, long offset, long size); | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/com/github/knokko/boiler/buffers/SharedDeviceBufferBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.github.knokko.boiler.buffers; | ||
|
||
import com.github.knokko.boiler.BoilerInstance; | ||
|
||
public class SharedDeviceBufferBuilder extends SharedBufferBuilder<DeviceVkbBuffer, VkbBufferRange> { | ||
|
||
public SharedDeviceBufferBuilder(BoilerInstance instance) { | ||
super(instance); | ||
} | ||
|
||
@Override | ||
protected DeviceVkbBuffer buildBuffer(long size, int usage, String name) { | ||
return instance.buffers.create(size, usage, name); | ||
} | ||
|
||
@Override | ||
protected VkbBufferRange createRange(DeviceVkbBuffer buffer, long offset, long size) { | ||
return new VkbBufferRange(buffer, offset, size); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/github/knokko/boiler/buffers/SharedMappedBufferBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.github.knokko.boiler.buffers; | ||
|
||
import com.github.knokko.boiler.BoilerInstance; | ||
|
||
public class SharedMappedBufferBuilder extends SharedBufferBuilder<MappedVkbBuffer, MappedVkbBufferRange> { | ||
public SharedMappedBufferBuilder(BoilerInstance instance) { | ||
super(instance); | ||
} | ||
|
||
@Override | ||
protected MappedVkbBuffer buildBuffer(long size, int usage, String name) { | ||
return instance.buffers.createMapped(size, usage, name); | ||
} | ||
|
||
@Override | ||
protected MappedVkbBufferRange createRange(MappedVkbBuffer buffer, long offset, long size) { | ||
return new MappedVkbBufferRange(buffer, offset, size); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/com/github/knokko/boiler/utilities/BoilerMath.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.github.knokko.boiler.utilities; | ||
|
||
public class BoilerMath { | ||
|
||
public static long nextMultipleOf(long value, long alignment) { // TODO Document this | ||
long quotient = value / alignment; | ||
long reverted = quotient * alignment; | ||
if (reverted < value) reverted += alignment; | ||
return reverted; | ||
} | ||
} |
140 changes: 140 additions & 0 deletions
140
src/test/java/com/github/knokko/boiler/buffers/TestSharedBufferBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package com.github.knokko.boiler.buffers; | ||
|
||
import com.github.knokko.boiler.BoilerInstance; | ||
import com.github.knokko.boiler.builders.BoilerBuilder; | ||
import com.github.knokko.boiler.commands.CommandRecorder; | ||
import com.github.knokko.boiler.synchronization.ResourceUsage; | ||
import org.junit.jupiter.api.AfterAll; | ||
import org.junit.jupiter.api.BeforeAll; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.lwjgl.system.MemoryStack.stackPush; | ||
import static org.lwjgl.vulkan.VK10.*; | ||
|
||
public class TestSharedBufferBuilder { | ||
|
||
private static BoilerInstance instance; | ||
|
||
@BeforeAll | ||
public static void setUp() { | ||
instance = new BoilerBuilder( | ||
VK_API_VERSION_1_0, "TestSharedBufferBuilder", 1 | ||
).validation().forbidValidationErrors().build(); | ||
} | ||
|
||
@Test | ||
public void testAlignment() { | ||
var builder = new SharedDeviceBufferBuilder(instance); | ||
var getRange0 = builder.add(1, 1234); | ||
var getRange1 = builder.add(100, 13); | ||
var getRange2 = builder.add(50, 57); | ||
var buffer = builder.build(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, "AlignmentBuffer"); | ||
|
||
var range0 = getRange0.get(); | ||
var range1 = getRange1.get(); | ||
var range2 = getRange2.get(); | ||
|
||
assertEquals(1, range0.size()); | ||
assertEquals(0, range0.offset()); | ||
assertEquals(100, range1.size()); | ||
assertEquals(13, range1.offset()); | ||
assertEquals(50, range2.size()); | ||
assertEquals(114, range2.offset()); | ||
assertEquals(164, buffer.size()); | ||
|
||
buffer.destroy(instance); | ||
} | ||
// TODO Docs | ||
@Test | ||
public void testBufferCopyShuffle() { | ||
var sourceBuilder = new SharedMappedBufferBuilder(instance); | ||
var getSource0 = sourceBuilder.add(7, 4); | ||
var getSource1 = sourceBuilder.add(8, 8); | ||
var getSource2 = sourceBuilder.add(1, 1); | ||
var sourceBuffer = sourceBuilder.build(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, "SharedSource"); | ||
getSource0.get().intBuffer().put(1234); | ||
getSource1.get().doubleBuffer().put(1.25); | ||
getSource2.get().byteBuffer().put((byte) 123); | ||
|
||
var middleBuilder = new SharedDeviceBufferBuilder(instance); | ||
var getMiddle2 = middleBuilder.add(1, 1); | ||
var getMiddle0 = middleBuilder.add(7, 4); | ||
var getMiddle1 = middleBuilder.add(8, 8); | ||
var middleBuffer = middleBuilder.build( | ||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, "SharedMiddle" | ||
); | ||
|
||
var destBuilder = new SharedMappedBufferBuilder(instance); | ||
var getDest1 = destBuilder.add(8, 8); | ||
var getDest2 = destBuilder.add(1, 1); | ||
var getDest0 = destBuilder.add(7, 4); | ||
var destBuffer = destBuilder.build(VK_BUFFER_USAGE_TRANSFER_DST_BIT, "SharedDestination"); | ||
|
||
var commandPool = instance.commands.createPool( | ||
0, instance.queueFamilies().transfer().index(), "SharedCommandPool" | ||
); | ||
var commandBuffer = instance.commands.createPrimaryBuffers(commandPool, 1, "SharedCommandBuffer")[0]; | ||
try (var stack = stackPush()) { | ||
var recorder = CommandRecorder.begin(commandBuffer, instance, stack, "SharedShuffle"); | ||
recorder.copyBuffer(getSource0.get().range(), middleBuffer.vkBuffer(), getMiddle0.get().offset()); | ||
recorder.copyBuffer(getSource1.get().range(), middleBuffer.vkBuffer(), getMiddle1.get().offset()); | ||
recorder.copyBuffer(getSource2.get().range(), middleBuffer.vkBuffer(), getMiddle2.get().offset()); | ||
|
||
recorder.bufferBarrier(getMiddle0.get(), ResourceUsage.TRANSFER_DEST, ResourceUsage.TRANSFER_SOURCE); | ||
recorder.bufferBarrier(getMiddle1.get(), ResourceUsage.TRANSFER_DEST, ResourceUsage.TRANSFER_SOURCE); | ||
recorder.bufferBarrier(getMiddle2.get(), ResourceUsage.TRANSFER_DEST, ResourceUsage.TRANSFER_SOURCE); | ||
|
||
recorder.copyBuffer(getMiddle0.get(), destBuffer.vkBuffer(), getDest0.get().offset()); | ||
recorder.copyBuffer(getMiddle1.get(), destBuffer.vkBuffer(), getDest1.get().offset()); | ||
recorder.copyBuffer(getMiddle2.get(), destBuffer.vkBuffer(), getDest2.get().offset()); | ||
|
||
recorder.end(); | ||
|
||
var fence = instance.sync.fenceBank.borrowFence(false, "ShuffleFence"); | ||
instance.queueFamilies().transfer().first().submit(commandBuffer, "Shuffle", null, fence); | ||
fence.awaitSignal(); | ||
instance.sync.fenceBank.returnFence(fence); | ||
} | ||
|
||
vkDestroyCommandPool(instance.vkDevice(), commandPool, null); | ||
|
||
assertEquals(1234, getDest0.get().intBuffer().get()); | ||
assertEquals(1.25, getDest1.get().doubleBuffer().get()); | ||
assertEquals(123, getDest2.get().byteBuffer().get()); | ||
|
||
sourceBuffer.destroy(instance); | ||
middleBuffer.destroy(instance); | ||
destBuffer.destroy(instance); | ||
} | ||
|
||
@Test | ||
public void testMappedBufferBuilder() { | ||
var builder = new SharedMappedBufferBuilder(instance); | ||
var getRange0 = builder.add(3, 0); | ||
var getRange1 = builder.add(8, 4); | ||
|
||
var buffer = builder.build(VK_BUFFER_USAGE_TRANSFER_DST_BIT, "TestMappedBuffer"); | ||
var range0 = getRange0.get(); | ||
var range1 = getRange1.get(); | ||
|
||
assertEquals(0, range0.offset()); | ||
assertEquals(3, range0.size()); | ||
assertEquals(4, range1.offset()); | ||
assertEquals(8, range1.size()); | ||
assertEquals(12, buffer.size()); | ||
|
||
range0.byteBuffer().put(2, (byte) 3); | ||
range1.intBuffer().put(12345); | ||
|
||
assertEquals(3, buffer.fullMappedRange().byteBuffer().get(2)); | ||
assertEquals(12345, buffer.fullMappedRange().intBuffer().get(1)); | ||
|
||
buffer.destroy(instance); | ||
} | ||
|
||
@AfterAll | ||
public static void cleanUp() { | ||
instance.destroyInitialObjects(); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/test/java/com/github/knokko/boiler/utilities/TestBoilerMath.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.github.knokko.boiler.utilities; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import static com.github.knokko.boiler.utilities.BoilerMath.nextMultipleOf; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
public class TestBoilerMath { | ||
|
||
@Test | ||
public void testNextMultipleOf() { | ||
assertEquals(10, nextMultipleOf(10, 1)); | ||
assertEquals(10, nextMultipleOf(10, 2)); | ||
assertEquals(10, nextMultipleOf(10, 5)); | ||
assertEquals(10, nextMultipleOf(10, 10)); | ||
assertEquals(12, nextMultipleOf(10, 3)); | ||
assertEquals(12, nextMultipleOf(10, 4)); | ||
} | ||
} |