Skip to content

Commit

Permalink
Enable VK12 VMA Features + Misc. Shader/Optimisation tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
thr3343 committed Nov 17, 2023
1 parent 66bcb0a commit 2469467
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 82 deletions.
4 changes: 3 additions & 1 deletion src/main/java/net/vulkanmod/render/chunk/ChunkArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.minecraft.core.BlockPos;
import net.vulkanmod.render.chunk.util.ResettableQueue;
import net.vulkanmod.render.chunk.util.StaticQueue;
import org.joml.FrustumIntersection;
import org.joml.Vector3i;

Expand All @@ -15,7 +16,8 @@ public class ChunkArea {

DrawBuffers drawBuffers;

final ResettableQueue<RenderSection> sectionQueue = new ResettableQueue<>();
//Help JIT optimisations by hardcoding the queue size to the max possible ChunkArea limit
final StaticQueue<RenderSection> sectionQueue = new StaticQueue<>(512);

public ChunkArea(int i, Vector3i origin) {
this.index = i;
Expand Down
98 changes: 34 additions & 64 deletions src/main/java/net/vulkanmod/render/chunk/DrawBuffers.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import net.minecraft.client.renderer.RenderType;
import net.vulkanmod.render.chunk.build.UploadBuffer;
import net.vulkanmod.render.chunk.util.ResettableQueue;
import net.vulkanmod.render.chunk.util.StaticQueue;
import net.vulkanmod.render.vertex.TerrainRenderType;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.memory.IndirectBuffer;
Expand Down Expand Up @@ -60,7 +61,7 @@ public DrawParameters upload(UploadBuffer buffer, DrawParameters drawParameters)
drawParameters.firstIndex = firstIndex;
drawParameters.vertexOffset = vertexOffset;

Renderer.getDrawer().getQuadsIndexBuffer().checkCapacity(buffer.indexCount * 2 / 3);


buffer.release();

Expand All @@ -72,7 +73,7 @@ public int buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, ChunkArea chu

int drawCount = 0;

ResettableQueue<RenderSection> queue = chunkArea.sectionQueue;
StaticQueue<RenderSection> queue = chunkArea.sectionQueue;

MemoryStack stack = MemoryStack.stackPush();
ByteBuffer byteBuffer = stack.calloc(20 * queue.size());
Expand All @@ -86,8 +87,9 @@ public int buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, ChunkArea chu

Pipeline pipeline = TerrainShaderManager.getTerrainIndirectShader(renderType);

VkCommandBuffer commandBuffer = Renderer.getCommandBuffer();
if(isTranslucent) {
vkCmdBindIndexBuffer(Renderer.getCommandBuffer(), this.indexBuffer.getId(), 0, VK_INDEX_TYPE_UINT16);
vkCmdBindIndexBuffer(commandBuffer, this.indexBuffer.getId(), 0, VK_INDEX_TYPE_UINT16);
}

var iterator = queue.iterator(isTranslucent);
Expand All @@ -110,10 +112,6 @@ public int buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, ChunkArea chu
// }


if(drawParameters.indexCount == 0) {
continue;
}

//TODO
if(!drawParameters.ready && drawParameters.vertexBufferSegment.getOffset() != -1) {
if(!drawParameters.vertexBufferSegment.isReady())
Expand Down Expand Up @@ -152,11 +150,11 @@ public int buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, ChunkArea chu

LongBuffer pVertexBuffer = stack.longs(vertexBuffer.getId());
LongBuffer pOffset = stack.longs(0);
vkCmdBindVertexBuffers(Renderer.getCommandBuffer(), 0, pVertexBuffer, pOffset);
vkCmdBindVertexBuffers(commandBuffer, 0, pVertexBuffer, pOffset);

// pipeline.bindDescriptorSets(Drawer.getCommandBuffer(), WorldRenderer.getInstance().getUniformBuffers(), Drawer.getCurrentFrame());
pipeline.bindDescriptorSets(Renderer.getCommandBuffer(), Renderer.getCurrentFrame());
vkCmdDrawIndexedIndirect(Renderer.getCommandBuffer(), indirectBuffer.getId(), indirectBuffer.getOffset(), drawCount, stride);
pipeline.bindDescriptorSets(commandBuffer, Renderer.getCurrentFrame());
vkCmdDrawIndexedIndirect(commandBuffer, indirectBuffer.getId(), indirectBuffer.getOffset(), drawCount, stride);

// fakeIndirectCmd(Drawer.getCommandBuffer(), indirectBuffer, drawCount, uboBuffer);

Expand Down Expand Up @@ -202,82 +200,54 @@ private static void fakeIndirectCmd(VkCommandBuffer commandBuffer, IndirectBuffe
}
}

public void buildDrawBatchesDirect(ResettableQueue<RenderSection> queue, Pipeline pipeline, RenderType renderType, double camX, double camY, double camZ) {
public void buildDrawBatchesDirect(StaticQueue<RenderSection> queue, Pipeline pipeline, RenderType renderType, double camX, double camY, double camZ) {
TerrainRenderType terrainRenderType = TerrainRenderType.get(renderType);
terrainRenderType.setCutoutUniform();
boolean isTranslucent = terrainRenderType == TerrainRenderType.TRANSLUCENT;

try(MemoryStack stack = MemoryStack.stackPush()) {
LongBuffer pVertexBuffer = stack.longs(vertexBuffer.getId());
LongBuffer pOffset = stack.longs(0);
vkCmdBindVertexBuffers(Renderer.getCommandBuffer(), 0, pVertexBuffer, pOffset);

}

if(isTranslucent) {
vkCmdBindIndexBuffer(Renderer.getCommandBuffer(), this.indexBuffer.getId(), 0, VK_INDEX_TYPE_UINT16);
}

VkCommandBuffer commandBuffer = Renderer.getCommandBuffer();
try(MemoryStack stack = MemoryStack.stackPush()) {
long pVertexBuffer = stack.npointer(vertexBuffer.getId());
long pOffset = stack.npointer(0);
nvkCmdBindVertexBuffers(commandBuffer, 0, 1, (pVertexBuffer), (pOffset));

// Pipeline pipeline = ShaderManager.shaderManager.terrainDirectShader;
// Pipeline pipeline = TestShaders.getShaderPipeline(renderType);
// Drawer.getInstance().bindPipeline(pipeline);
pipeline.bindDescriptorSets(Renderer.getCommandBuffer(), Renderer.getCurrentFrame());

// ResettableQueue<RenderSection> queue = chunkArea.sectionQueue;

int drawCount = 0;
MemoryStack stack = MemoryStack.stackGet().push();
ByteBuffer byteBuffer = stack.malloc(24 * queue.size());
long bufferPtr = MemoryUtil.memAddress0(byteBuffer);
if(isTranslucent) {
vkCmdBindIndexBuffer(commandBuffer, this.indexBuffer.getId(), 0, VK_INDEX_TYPE_UINT16);
}

var iterator = queue.iterator(isTranslucent);
while (iterator.hasNext()) {
RenderSection section = iterator.next();
DrawParameters drawParameters = section.getDrawParameters(terrainRenderType);

if(drawParameters.indexCount == 0) {
continue;
}

long ptr = bufferPtr + (drawCount * 24L);
MemoryUtil.memPutInt(ptr, drawParameters.indexCount);
MemoryUtil.memPutInt(ptr + 4, drawParameters.firstIndex);
MemoryUtil.memPutInt(ptr + 8, drawParameters.vertexOffset);
// Pipeline pipeline = ShaderManager.shaderManager.terrainDirectShader;
// Pipeline pipeline = TestShaders.getShaderPipeline(renderType);
// Drawer.getInstance().bindPipeline(pipeline);
pipeline.bindDescriptorSets(commandBuffer, Renderer.getCurrentFrame());

MemoryUtil.memPutFloat(ptr + 12, (float)((double) section.xOffset - camX));
MemoryUtil.memPutFloat(ptr + 16, (float)((double) section.yOffset - camY));
MemoryUtil.memPutFloat(ptr + 20, (float)((double) section.zOffset - camZ));
// ResettableQueue<RenderSection> queue = chunkArea.sectionQueue;

drawCount++;

}
final long ptr = stack.nmalloc(16);
final long layout = pipeline.getLayout();
final float camX1 = (float) camX;
final float camY1 = (float) camY;
final float camZ1 = (float) camZ;

if(drawCount > 0) {
long offset;
int indexCount;
int firstIndex;
int vertexOffset;
for(int i = 0; i < drawCount; ++i) {
for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) {
RenderSection section = iterator.next();
DrawParameters drawParameters = section.getDrawParameters(terrainRenderType);

offset = i * 24 + bufferPtr;

indexCount = MemoryUtil.memGetInt(offset + 0);
firstIndex = MemoryUtil.memGetInt(offset + 4);
vertexOffset = MemoryUtil.memGetInt(offset + 8);
MemoryUtil.memPutFloat(ptr + 0, section.xOffset - camX1);
MemoryUtil.memPutFloat(ptr + 4, section.yOffset - camY1);
MemoryUtil.memPutFloat(ptr + 8, section.zOffset - camZ1);

// if(indexCount == 0) {
// continue;
// }
nvkCmdPushConstants(commandBuffer, layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 12, ptr);

nvkCmdPushConstants(commandBuffer, pipeline.getLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, 12, offset + 12);
vkCmdDrawIndexed(commandBuffer, drawParameters.indexCount, 1, drawParameters.firstIndex, drawParameters.vertexOffset, 0);

vkCmdDrawIndexed(commandBuffer, indexCount, 1, firstIndex, vertexOffset, 0);
}
}

stack.pop();
}

public void releaseBuffers() {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,9 @@ private void updateRenderChunks() {
while(this.chunkQueue.hasNext()) {
RenderSection renderSection = this.chunkQueue.poll();

renderSection.getChunkArea().sectionQueue.add(renderSection);

if(!renderSection.isCompletelyEmpty()) {
renderSection.getChunkArea().sectionQueue.add(renderSection);
this.chunkAreaQueue.add(renderSection.getChunkArea());
this.nonEmptyChunks++;
}
Expand Down Expand Up @@ -355,9 +355,9 @@ private void updateRenderChunksSpectator() {
while(this.chunkQueue.hasNext()) {
RenderSection renderSection = this.chunkQueue.poll();

renderSection.getChunkArea().sectionQueue.add(renderSection);

if(!renderSection.isCompletelyEmpty()) {
renderSection.getChunkArea().sectionQueue.add(renderSection);
this.chunkAreaQueue.add(renderSection.getChunkArea());
this.nonEmptyChunks++;
}
Expand Down
99 changes: 99 additions & 0 deletions src/main/java/net/vulkanmod/render/chunk/util/StaticQueue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package net.vulkanmod.render.chunk.util;

import org.jetbrains.annotations.NotNull;

import java.util.Iterator;
import java.util.function.Consumer;

public class StaticQueue<T> implements Iterable<T> {
final T[] queue;
int position = 0;
int limit = 0;
final int capacity;

public StaticQueue() {
this(1024);
}

@SuppressWarnings("unchecked")
public StaticQueue(int initialCapacity) {
this.capacity = initialCapacity;

this.queue = (T[])(new Object[capacity]);
}

public boolean hasNext() {
return this.position < this.limit;
}

public T poll() {
T t = this.queue[position];
this.position++;

return t;
}

public void add(T t) {
if(t == null)
return;

if(limit == capacity) throw new RuntimeException("Exceeded size: "+this.capacity);
this.queue[limit] = t;

this.limit++;
}

public int size() {
return limit;
}

public void clear() {
this.position = 0;
this.limit = 0;
}

public Iterator<T> iterator(boolean reverseOrder) {
return reverseOrder ? new Iterator<>() {
int pos = StaticQueue.this.limit - 1;
final int limit = -1;

@Override
public boolean hasNext() {
return pos > limit;
}

@Override
public T next() {
return queue[pos--];
}
}
: new Iterator<>() {
int pos = 0;
final int limit = StaticQueue.this.limit;

@Override
public boolean hasNext() {
return pos < limit;
}

@Override
public T next() {
return queue[pos++];
}
};
}

@NotNull
@Override
public Iterator<T> iterator() {
return iterator(false);
}

@Override
public void forEach(Consumer<? super T> action) {
for(int i = 0; i < this.limit; ++i) {
action.accept(this.queue[i]);
}

}
}
3 changes: 2 additions & 1 deletion src/main/java/net/vulkanmod/vulkan/Drawer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class Drawer {
private static final LongBuffer offsets = MemoryUtil.memAllocLong(1);
private static final long pBuffers = MemoryUtil.memAddress0(buffers);
private static final long pOffsets = MemoryUtil.memAddress0(offsets);
private static final int UINT16_INDEX_MAX = 98304;

private int framesNum;
private VertexBuffer[] vertexBuffers;
Expand All @@ -34,7 +35,7 @@ public class Drawer {

public Drawer() {
//Index buffers
quadsIndexBuffer = new AutoIndexBuffer(100000, AutoIndexBuffer.DrawType.QUADS);
quadsIndexBuffer = new AutoIndexBuffer(UINT16_INDEX_MAX, AutoIndexBuffer.DrawType.QUADS);
triangleFanIndexBuffer = new AutoIndexBuffer(1000, AutoIndexBuffer.DrawType.TRIANGLE_FAN);
triangleStripIndexBuffer = new AutoIndexBuffer(1000, AutoIndexBuffer.DrawType.TRIANGLE_STRIP);
}
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/net/vulkanmod/vulkan/Vulkan.java
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,9 @@ private static void createInstance() {

appInfo.sType(VK_STRUCTURE_TYPE_APPLICATION_INFO);
appInfo.pApplicationName(stack.UTF8Safe("VulkanMod"));
appInfo.applicationVersion(VK_MAKE_VERSION(1, 0, 0));
appInfo.applicationVersion(VK_API_VERSION_1_2);
appInfo.pEngineName(stack.UTF8Safe("No Engine"));
appInfo.engineVersion(VK_MAKE_VERSION(1, 0, 0));
appInfo.engineVersion(VK_API_VERSION_1_2);
appInfo.apiVersion(VK_API_VERSION_1_2);

VkInstanceCreateInfo createInfo = VkInstanceCreateInfo.calloc(stack);
Expand Down Expand Up @@ -345,6 +345,7 @@ private static void createVma() {
allocatorCreateInfo.device(Device.device);
allocatorCreateInfo.pVulkanFunctions(vulkanFunctions);
allocatorCreateInfo.instance(instance);
allocatorCreateInfo.vulkanApiVersion(VK_API_VERSION_1_2);

PointerBuffer pAllocator = stack.pointers(VK_NULL_HANDLE);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;

import static net.vulkanmod.vulkan.memory.AutoIndexBuffer.DrawType.QUADS;

public class AutoIndexBuffer {
int vertexCount;
DrawType drawType;
Expand Down Expand Up @@ -44,7 +46,7 @@ private void createIndexBuffer(int vertexCount) {
}

public void checkCapacity(int vertexCount) {
if(vertexCount > this.vertexCount) {
if(this.drawType!=QUADS && vertexCount > this.vertexCount) {
int newVertexCount = this.vertexCount * 2;
System.out.println("Reallocating AutoIndexBuffer from " + this.vertexCount + " to " + newVertexCount);

Expand Down
Loading

0 comments on commit 2469467

Please sign in to comment.