Skip to content

Commit

Permalink
Entities mate!
Browse files Browse the repository at this point in the history
  • Loading branch information
bobcao3 committed Jun 2, 2024
1 parent 7cccaf2 commit 71e2655
Show file tree
Hide file tree
Showing 14 changed files with 589 additions and 348 deletions.

Large diffs are not rendered by default.

147 changes: 84 additions & 63 deletions src/main/java/me/cortex/vulkanite/acceleration/EntityBlasBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,81 @@
import java.util.ArrayList;
import java.util.List;

import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
import static org.lwjgl.vulkan.KHRAccelerationStructure.*;
import static org.lwjgl.vulkan.KHRAccelerationStructure.VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
import static org.lwjgl.vulkan.KHRBufferDeviceAddress.VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR;
import static org.lwjgl.vulkan.VK10.*;

public class EntityBlasBuilder {
private final VContext ctx;

public EntityBlasBuilder(VContext context) {
this.ctx = context;
}

private record BuildInfo(VertexFormat format, int quadCount, long address) {}
Pair<VRef<VAccelerationStructure>, VRef<VBuffer>> buildBlas(List<Pair<RenderLayer, BufferBuilder.BuiltBuffer>> renders, VCmdBuff cmd) {
private static VRef<VAccelerationStructure> executeBlasBuild(VContext ctx, VCmdBuff cmd, MemoryStack stack, VkAccelerationStructureGeometryKHR.Buffer geometryInfos, int[] prims) {
var buildInfos = VkAccelerationStructureBuildGeometryInfoKHR.calloc(1, stack);
var buildRanges = VkAccelerationStructureBuildRangeInfoKHR.calloc(prims.length, stack);
for (int primCount : prims) {
buildRanges.get().primitiveCount(primCount);
}

var bi = buildInfos.get()
.sType$Default()
.type(VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR)
.flags(VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)
.pGeometries(geometryInfos)
.geometryCount(geometryInfos.remaining());

VkAccelerationStructureBuildSizesInfoKHR buildSizesInfo = VkAccelerationStructureBuildSizesInfoKHR
.calloc(stack)
.sType$Default();

vkGetAccelerationStructureBuildSizesKHR(
ctx.device,
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
bi,
prims,
buildSizesInfo);


var structure = ctx.memory.createAcceleration(buildSizesInfo.accelerationStructureSize(), 256,
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR, VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR);

var scratch = ctx.memory.createBuffer(buildSizesInfo.buildScratchSize(),
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 256, 0);

bi.scratchData(VkDeviceOrHostAddressKHR.calloc(stack).deviceAddress(scratch.get().deviceAddress()));
bi.dstAccelerationStructure(structure.get().structure);

buildInfos.rewind();
buildRanges.rewind();

vkCmdBuildAccelerationStructuresKHR(cmd.buffer(), buildInfos, stack.pointers(buildRanges));

vkCmdPipelineBarrier(cmd.buffer(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, VkMemoryBarrier.calloc(1, stack)
.sType$Default()
.srcAccessMask(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR)
.dstAccessMask(VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR), null, null);

cmd.addAccelerationStructureRef(structure);
cmd.addBufferRef(scratch);
scratch.close();

return structure;
}

List<BLASResult> buildBlas(List<Pair<RenderLayer, BufferBuilder.BuiltBuffer>> renders, VCmdBuff cmd) {
long combined_size = 0;
TextureManager textureManager = MinecraftClient.getInstance().getTextureManager();
for (var type : renders) {
if (((RenderLayer.MultiPhase)type.getLeft()).phases.texture instanceof RenderPhase.Textures) {
if (((RenderLayer.MultiPhase) type.getLeft()).phases.texture instanceof RenderPhase.Textures) {
throw new IllegalStateException("Multi texture not supported");
}
var textureId = ((RenderLayer.MultiPhase)type.getLeft()).phases.texture.getId().get();
var textureId = ((RenderLayer.MultiPhase) type.getLeft()).phases.texture.getId().get();
var texture = textureManager.getTexture(textureId);
var vkImage = ((IVGImage)texture).getVGImage();
var vkImage = ((IVGImage) texture).getVGImage();
if (vkImage == null) {
throw new IllegalStateException("Vulkan texture not created for render layer " + type.getLeft());
}
Expand All @@ -56,20 +108,34 @@ Pair<VRef<VAccelerationStructure>, VRef<VBuffer>> buildBlas(List<Pair<RenderLaye
//Each render layer gets its own geometry entry in the blas

//TODO: PUT THE BINDLESS TEXTURE REFERENCE AT THE START OF THE render layers geometry buffer
var geometryBuffer = ctx.memory.createBuffer(combined_size, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
long ptr = geometryBuffer.get().map();
var geometryBufferStaging = ctx.memory.createBuffer(
combined_size,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
0,
VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT);
var geometryBuffer = ctx.memory.createBuffer(
combined_size,
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
long ptr = geometryBufferStaging.get().map();
long offset = 0;
List<BuildInfo> infos = new ArrayList<>();
List<Long> offsets = new ArrayList<>();
for (var pair : renders) {
offset = VUtil.alignUp(offset, 128);
MemoryUtil.memCopy(MemoryUtil.memAddress(pair.getRight().getVertexBuffer()), ptr + offset, pair.getRight().getVertexBuffer().remaining());
infos.add(new BuildInfo(pair.getRight().getParameters().format(), pair.getRight().getParameters().indexCount()/6, geometryBuffer.get().deviceAddress() + offset));

cmd.addBufferRef(geometryBuffer);
infos.add(new BuildInfo(pair.getRight().getParameters().format(), pair.getRight().getParameters().indexCount() / 6, geometryBuffer.get().deviceAddress() + offset));
offsets.add(offset);

offset += pair.getRight().getVertexBuffer().remaining();
}
geometryBuffer.get().unmap();
cmd.addBufferRef(geometryBufferStaging);
geometryBufferStaging.get().unmap();

cmd.encodeBufferCopy(geometryBufferStaging, 0, geometryBuffer, 0, combined_size);
cmd.encodeBufferBarrier(geometryBuffer, 0, combined_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR);
geometryBufferStaging.close();

VRef<VAccelerationStructure> blas;
try (var stack = MemoryStack.stackPush()) {
Expand All @@ -79,8 +145,7 @@ Pair<VRef<VAccelerationStructure>, VRef<VBuffer>> buildBlas(List<Pair<RenderLaye
blas = executeBlasBuild(ctx, cmd, stack, buildInfo, primitiveCounts);
}


return new Pair<>(blas, geometryBuffer);
return List.of(new BLASResult(blas, geometryBuffer, offsets));
}

private VkAccelerationStructureGeometryKHR.Buffer populateBuildStructs(VContext ctx, MemoryStack stack, VCmdBuff cmdBuff, List<BuildInfo> geometries, int[] primitiveCounts) {
Expand Down Expand Up @@ -111,6 +176,7 @@ private VkAccelerationStructureGeometryKHR.Buffer populateBuildStructs(VContext
.geometryType(VK_GEOMETRY_TYPE_TRIANGLES_KHR)
// .flags(geometry.geometryFlags)
;

primitiveCounts[i++] = (geometry.quadCount * 2);

cmdBuff.addBufferRef(indexBuffer);
Expand All @@ -119,54 +185,9 @@ private VkAccelerationStructureGeometryKHR.Buffer populateBuildStructs(VContext
return geometryInfos;
}

private static VRef<VAccelerationStructure> executeBlasBuild(VContext ctx, VCmdBuff cmd, MemoryStack stack, VkAccelerationStructureGeometryKHR.Buffer geometryInfos, int[] prims) {
var buildInfos = VkAccelerationStructureBuildGeometryInfoKHR.calloc(1, stack);
var buildRanges = VkAccelerationStructureBuildRangeInfoKHR.calloc(prims.length, stack);
for (int primCount : prims) {
buildRanges.get().primitiveCount(primCount);
}

var bi = buildInfos.get()
.sType$Default()
.type(VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR)
.flags(VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)
.pGeometries(geometryInfos)
.geometryCount(geometryInfos.remaining());

VkAccelerationStructureBuildSizesInfoKHR buildSizesInfo = VkAccelerationStructureBuildSizesInfoKHR
.calloc(stack)
.sType$Default();

vkGetAccelerationStructureBuildSizesKHR(
ctx.device,
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
bi,
prims,
buildSizesInfo);


var structure = ctx.memory.createAcceleration(buildSizesInfo.accelerationStructureSize(), 256,
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR, VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR);

var scratch = ctx.memory.createBuffer(buildSizesInfo.buildScratchSize(),
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 256, 0);

bi.scratchData(VkDeviceOrHostAddressKHR.calloc(stack).deviceAddress(scratch.get().deviceAddress()));
bi.dstAccelerationStructure(structure.get().structure);

buildInfos.rewind();
buildRanges.rewind();

vkCmdBuildAccelerationStructuresKHR(cmd.buffer(), buildInfos, stack.pointers(buildRanges));

vkCmdPipelineBarrier(cmd.buffer(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, VkMemoryBarrier.calloc(1, stack)
.sType$Default()
.srcAccessMask(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR)
.dstAccessMask(VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR), null, null);
public record BLASResult(VRef<VAccelerationStructure> structure, VRef<VBuffer> geometry, List<Long> offsets) {
}

cmd.addAccelerationStructureRef(structure);
cmd.addBufferRef(scratch);
return structure;
private record BuildInfo(VertexFormat format, int quadCount, long address) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package me.cortex.vulkanite.acceleration;

public enum GeometryRayFlags {
OPAQUE(1),
TRANSPARENT(1 << 1),
ENTITY(1 << 2),
PLAYER(1 << 7),
;
final int flag;

GeometryRayFlags(int i) {
flag = i;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@
import net.minecraft.client.texture.TextureManager;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.util.Pair;
import net.minecraft.world.World;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
import static org.lwjgl.vulkan.KHRAccelerationStructure.*;
Expand Down Expand Up @@ -86,10 +85,22 @@ public List<Pair<RenderLayer, BufferBuilder.BuiltBuffer>> end() {
if (builtBuffer.getParameters().format().equals(IrisVertexFormats.TERRAIN)) {
return;
}

// TODO: Support anything other than ENTITY
if (!builtBuffer.getParameters().format().equals(IrisVertexFormats.ENTITY)) {
return;
}

//Dont support no texture things
if (((RenderLayer.MultiPhase)layer).phases.texture.getId().isEmpty()) {
if (!(layer instanceof RenderLayer.MultiPhase)) {
return;
}

var texture = ((RenderLayer.MultiPhase)layer).phases.texture;
if ((texture == null) || (texture.getId().isEmpty())) {
return;
}

buffers.add(new Pair<>(layer, builtBuffer));
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import me.cortex.vulkanite.lib.memory.VImage;
import me.cortex.vulkanite.lib.other.VImageView;
import me.cortex.vulkanite.lib.other.VSampler;
import me.cortex.vulkanite.lib.other.VUtil;
import me.cortex.vulkanite.lib.other.sync.VSemaphore;
import me.cortex.vulkanite.lib.pipeline.RaytracePipelineBuilder;
import me.cortex.vulkanite.lib.pipeline.VRaytracePipeline;
Expand Down Expand Up @@ -236,14 +237,28 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray
}

private final EntityCapture capture = new EntityCapture();
private void buildEntities() {
private void captureEntities() {
accelerationManager.setEntityData(supportsEntities?capture.capture(CapturedRenderingState.INSTANCE.getTickDelta(), MinecraftClient.getInstance().world):null);
}

public void renderPostShadows(List<VRef<VGImage>> vgOutImgs, Camera camera, ShaderStorageBuffer[] ssbos, MixinCelestialUniforms celestialUniforms) {
var prof = MinecraftClient.getInstance().getProfiler();

for (int i = 0; i < 15; i++) {
if (VUtil._REPORT_GL_ERROR_()) {
break;
} else if (i == 14) {
System.err.println("Found OpenGL errors generated outside Vulkanite that can't be cleared");
VUtil._CHECK_GL_ERROR_();
}
}

ctx.cmd.newFrame();
VRegistry.INSTANCE.threadLocalCollect();

buildEntities();
prof.push("vulkanite_capture_entities");
captureEntities();
prof.pop();

PBRTextureManager.notifyPBRTexturesChanged();

Expand All @@ -256,7 +271,9 @@ public void renderPostShadows(List<VRef<VGImage>> vgOutImgs, Camera camera, Shad
var cmdRef = ctx.cmd.getSingleUsePool().createCommandBuffer();
var cmd = cmdRef.get();

prof.push("vulkanite_build_tlas");
var tlas = accelerationManager.buildTLAS(0, cmd);
prof.pop();

if (tlas == null) {
VRegistry.INSTANCE.threadLocalCollect();
Expand All @@ -273,6 +290,7 @@ public void renderPostShadows(List<VRef<VGImage>> vgOutImgs, Camera camera, Shad

var uboBuffer = uboAllocator.allocate(1024);
{
prof.push("vulkanite_encode_rt_passes");
long ptr = uboBuffer.buffer().get().map();
MemoryUtil.memSet(ptr, 0, 1024);
{
Expand Down Expand Up @@ -414,6 +432,7 @@ public void renderPostShadows(List<VRef<VGImage>> vgOutImgs, Camera camera, Shad
}
}

prof.pop();
ctx.cmd.submit(0, cmdRef, Arrays.asList(vref_in), Arrays.asList(vref_out), null);
}

Expand All @@ -427,7 +446,6 @@ public void renderPostShadows(List<VRef<VGImage>> vgOutImgs, Camera camera, Shad
in.close();
out.close();

VRegistry.INSTANCE.threadLocalCollect();
// System.out.println(VRegistry.INSTANCE.dumpStats());
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/java/me/cortex/vulkanite/lib/base/VObject.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package me.cortex.vulkanite.lib.base;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class VObject {
protected final AtomicInteger refCount = new AtomicInteger(0);
protected Object heap = null;

protected abstract void free();

protected final AtomicLong refCount = new AtomicLong(0);
protected void incRef() {
if (refCount.incrementAndGet() == 1) {
// First reference, put into registry
Expand All @@ -19,6 +21,4 @@ protected void decRef() {
VRegistry.INSTANCE.unregister(this);
}
}

public Object heap = null;
}
Loading

0 comments on commit 71e2655

Please sign in to comment.