VulkanShader_1.21.10-0.0.4-alpha.jar
Download file
package net.vulkanmod.render.chunk.buffer;
import java.nio.ByteBuffer;
import java.util.EnumMap;
import java.util.Iterator;
import net.minecraft.class_243;
import net.vulkanmod.Initializer;
import net.vulkanmod.render.PipelineManager;
import net.vulkanmod.render.chunk.RenderSection;
import net.vulkanmod.render.chunk.build.UploadBuffer;
import net.vulkanmod.render.chunk.cull.QuadFacing;
import net.vulkanmod.render.chunk.util.StaticQueue;
import net.vulkanmod.render.vertex.CustomVertexFormat;
import net.vulkanmod.render.vertex.TerrainRenderType;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.memory.buffer.IndirectBuffer;
import net.vulkanmod.vulkan.shader.Pipeline;
import org.joml.Vector3i;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.VK10;
import org.lwjgl.vulkan.VkCommandBuffer;
public class DrawBuffers {
public static final int VERTEX_SIZE;
public static final int INDEX_SIZE = 2;
public static final int UNDEFINED_FACING_IDX;
public static final float POS_OFFSET;
private static final int CMD_STRIDE = 32;
private static final long cmdBufferPtr;
private final int index;
private final Vector3i origin;
private final int minHeight;
private boolean allocated = false;
AreaBuffer indexBuffer;
private final EnumMap<TerrainRenderType, AreaBuffer> vertexBuffers = new EnumMap(TerrainRenderType.class);
long drawParamsPtr;
final int[] sectionIndices = new int[512];
final int[] masks = new int[512];
public DrawBuffers(int index, Vector3i origin, int minHeight) {
this.index = index;
this.origin = origin;
this.minHeight = minHeight;
this.drawParamsPtr = DrawParametersBuffer.allocateBuffer();
}
public void upload(RenderSection section, UploadBuffer buffer, TerrainRenderType renderType) {
ByteBuffer[] vertexBuffers = buffer.getVertexBuffers();
if (buffer.indexOnly) {
long paramsPtr = DrawParametersBuffer.getParamsPtr(this.drawParamsPtr, section.inAreaIndex, renderType.ordinal(), QuadFacing.UNDEFINED.ordinal());
int firstIndex = DrawParametersBuffer.getFirstIndex(paramsPtr);
int indexCount = DrawParametersBuffer.getIndexCount(paramsPtr);
int oldOffset = indexCount > 0 ? firstIndex : -1;
AreaBuffer.Segment segment = this.indexBuffer.upload(buffer.getIndexBuffer(), oldOffset, paramsPtr);
firstIndex = segment.offset / 2;
DrawParametersBuffer.setFirstIndex(paramsPtr, firstIndex);
buffer.release();
} else {
int oldOffset = -1;
int size = 0;
for(int i = 0; i < QuadFacing.COUNT; ++i) {
long paramPtr = DrawParametersBuffer.getParamsPtr(this.drawParamsPtr, section.inAreaIndex, renderType.ordinal(), i);
int vertexOffset = DrawParametersBuffer.getVertexOffset(paramPtr);
if (oldOffset == -1) {
oldOffset = vertexOffset;
}
ByteBuffer vertexBuffer = vertexBuffers[i];
if (vertexBuffer != null) {
size += vertexBuffer.remaining();
}
}
AreaBuffer areaBuffer = null;
AreaBuffer.Segment segment = null;
boolean doUpload = false;
if (size > 0) {
areaBuffer = this.getAreaBufferOrAlloc(renderType);
areaBuffer.freeSegment(oldOffset);
segment = areaBuffer.allocateSegment(size);
doUpload = true;
}
int baseInstance = this.encodeSectionOffset(section.xOffset(), section.yOffset(), section.zOffset());
int offset = 0;
for(int i = 0; i < QuadFacing.COUNT; ++i) {
long paramPtr = DrawParametersBuffer.getParamsPtr(this.drawParamsPtr, section.inAreaIndex, renderType.ordinal(), i);
int vertexOffset = -1;
int firstIndex = 0;
int indexCount = 0;
ByteBuffer vertexBuffer = vertexBuffers[i];
int vertexCount = 0;
if (vertexBuffer != null && doUpload) {
areaBuffer.upload(segment, vertexBuffer, offset);
vertexOffset = (segment.offset + offset) / VERTEX_SIZE;
offset += vertexBuffer.remaining();
vertexCount = vertexBuffer.limit() / VERTEX_SIZE;
indexCount = vertexCount * 6 / 4;
}
if (i == QuadFacing.UNDEFINED.ordinal() && !buffer.autoIndices) {
if (this.indexBuffer == null) {
this.indexBuffer = new AreaBuffer(AreaBuffer.Usage.INDEX, 60000, 2);
}
oldOffset = DrawParametersBuffer.getIndexCount(paramPtr) > 0 ? DrawParametersBuffer.getFirstIndex(paramPtr) : -1;
AreaBuffer.Segment ibSegment = this.indexBuffer.upload(buffer.getIndexBuffer(), oldOffset, paramPtr);
firstIndex = ibSegment.offset / 2;
} else {
Renderer.getDrawer().getQuadsIndexBuffer().checkCapacity(vertexCount);
}
DrawParametersBuffer.setIndexCount(paramPtr, indexCount);
DrawParametersBuffer.setFirstIndex(paramPtr, firstIndex);
DrawParametersBuffer.setVertexOffset(paramPtr, vertexOffset);
DrawParametersBuffer.setBaseInstance(paramPtr, baseInstance);
}
buffer.release();
}
}
private AreaBuffer getAreaBufferOrAlloc(TerrainRenderType renderType) {
this.allocated = true;
int var10000;
switch (renderType) {
case SOLID:
case CUTOUT:
var10000 = 100000;
break;
case CUTOUT_MIPPED:
var10000 = 250000;
break;
case TRANSLUCENT:
case TRIPWIRE:
var10000 = 60000;
break;
default:
throw new MatchException((String)null, (Throwable)null);
}
int initialSize = var10000;
return (AreaBuffer)this.vertexBuffers.computeIfAbsent(renderType, (renderType1) -> new AreaBuffer(AreaBuffer.Usage.VERTEX, initialSize, VERTEX_SIZE));
}
public AreaBuffer getAreaBuffer(TerrainRenderType r) {
return (AreaBuffer)this.vertexBuffers.get(r);
}
private boolean hasRenderType(TerrainRenderType r) {
return this.vertexBuffers.containsKey(r);
}
private int encodeSectionOffset(int xOffset, int yOffset, int zOffset) {
int xOffset1 = xOffset & 127;
int zOffset1 = zOffset & 127;
int yOffset1 = yOffset - this.minHeight & 127;
return yOffset1 << 16 | zOffset1 << 8 | xOffset1;
}
private void updateChunkAreaOrigin(VkCommandBuffer commandBuffer, Pipeline pipeline, double camX, double camY, double camZ, MemoryStack stack) {
float xOffset = (float)((double)((float)this.origin.x + POS_OFFSET) - camX);
float yOffset = (float)((double)((float)this.origin.y + POS_OFFSET) - camY);
float zOffset = (float)((double)((float)this.origin.z + POS_OFFSET) - camZ);
ByteBuffer byteBuffer = stack.malloc(12);
byteBuffer.putFloat(0, xOffset);
byteBuffer.putFloat(4, yOffset);
byteBuffer.putFloat(8, zOffset);
VK10.vkCmdPushConstants(commandBuffer, pipeline.getLayout(), 1, 0, byteBuffer);
}
public void buildDrawBatchesIndirect(class_243 cameraPos, IndirectBuffer indirectBuffer, StaticQueue<RenderSection> queue, TerrainRenderType terrainRenderType) {
long bufferPtr = cmdBufferPtr;
boolean isTranslucent = terrainRenderType == TerrainRenderType.TRANSLUCENT;
boolean backFaceCulling = Initializer.CONFIG.backFaceCulling && !isTranslucent;
int drawCount = 0;
long drawParamsBasePtr = this.drawParamsPtr + (long)(terrainRenderType.ordinal() * 512 * 7) * 16L;
long facingsStride = 112L;
int count = 0;
if (backFaceCulling) {
for(Iterator<RenderSection> iterator = queue.iterator(isTranslucent); iterator.hasNext(); ++count) {
RenderSection section = (RenderSection)iterator.next();
this.sectionIndices[count] = section.inAreaIndex;
this.masks[count] = this.getMask(cameraPos, section);
}
long ptr = bufferPtr;
for(int j = 0; j < count; ++j) {
int sectionIdx = this.sectionIndices[j];
int mask = this.masks[j];
long drawParamsBasePtr2 = drawParamsBasePtr + (long)sectionIdx * 112L;
int indexCount = 0;
int firstIndex = 0;
int vertexOffset = 0;
int baseInstance = 0;
for(int i = 0; i < QuadFacing.COUNT; ++i) {
if ((mask & 1 << i) == 0) {
drawParamsBasePtr2 += 16L;
if (indexCount > 0) {
MemoryUtil.memPutInt(ptr, indexCount);
MemoryUtil.memPutInt(ptr + 4L, 1);
MemoryUtil.memPutInt(ptr + 8L, firstIndex);
MemoryUtil.memPutInt(ptr + 12L, vertexOffset);
MemoryUtil.memPutInt(ptr + 16L, baseInstance);
ptr += 32L;
++drawCount;
}
indexCount = 0;
firstIndex = 0;
vertexOffset = 0;
baseInstance = 0;
} else {
int indexCount_i = DrawParametersBuffer.getIndexCount(drawParamsBasePtr2);
int firstIndex_i = DrawParametersBuffer.getFirstIndex(drawParamsBasePtr2);
int vertexOffset_i = DrawParametersBuffer.getVertexOffset(drawParamsBasePtr2);
int baseInstance_i = DrawParametersBuffer.getBaseInstance(drawParamsBasePtr2);
if (indexCount == 0) {
indexCount = indexCount_i;
firstIndex = firstIndex_i;
vertexOffset = vertexOffset_i;
baseInstance = baseInstance_i;
} else {
indexCount += indexCount_i;
}
drawParamsBasePtr2 += 16L;
}
}
if (indexCount > 0) {
MemoryUtil.memPutInt(ptr, indexCount);
MemoryUtil.memPutInt(ptr + 4L, 1);
MemoryUtil.memPutInt(ptr + 8L, firstIndex);
MemoryUtil.memPutInt(ptr + 12L, vertexOffset);
MemoryUtil.memPutInt(ptr + 16L, baseInstance);
ptr += 32L;
++drawCount;
}
}
} else {
for(Iterator<RenderSection> iterator = queue.iterator(isTranslucent); iterator.hasNext(); ++count) {
RenderSection section = (RenderSection)iterator.next();
this.sectionIndices[count] = section.inAreaIndex;
}
long facingOffset = (long)UNDEFINED_FACING_IDX * 16L;
drawParamsBasePtr += facingOffset;
long ptr = bufferPtr;
for(int i = 0; i < count; ++i) {
int sectionIdx = this.sectionIndices[i];
long drawParamsPtr = drawParamsBasePtr + (long)sectionIdx * 112L;
int indexCount = DrawParametersBuffer.getIndexCount(drawParamsPtr);
int firstIndex = DrawParametersBuffer.getFirstIndex(drawParamsPtr);
int vertexOffset = DrawParametersBuffer.getVertexOffset(drawParamsPtr);
int baseInstance = DrawParametersBuffer.getBaseInstance(drawParamsPtr);
if (indexCount > 0) {
MemoryUtil.memPutInt(ptr, indexCount);
MemoryUtil.memPutInt(ptr + 4L, 1);
MemoryUtil.memPutInt(ptr + 8L, firstIndex);
MemoryUtil.memPutInt(ptr + 12L, vertexOffset);
MemoryUtil.memPutInt(ptr + 16L, baseInstance);
ptr += 32L;
++drawCount;
}
}
}
if (drawCount != 0) {
ByteBuffer byteBuffer = MemoryUtil.memByteBuffer(cmdBufferPtr, queue.size() * QuadFacing.COUNT * 32);
indirectBuffer.recordCopyCmd(byteBuffer.position(0));
VK10.vkCmdDrawIndexedIndirect(Renderer.getCommandBuffer(), indirectBuffer.getId(), indirectBuffer.getOffset(), drawCount, 32);
}
}
public void buildDrawBatchesDirect(class_243 cameraPos, StaticQueue<RenderSection> queue, TerrainRenderType terrainRenderType) {
boolean isTranslucent = terrainRenderType == TerrainRenderType.TRANSLUCENT;
boolean backFaceCulling = Initializer.CONFIG.backFaceCulling && !isTranslucent;
VkCommandBuffer commandBuffer = Renderer.getCommandBuffer();
long drawParamsBasePtr = this.drawParamsPtr + (long)(terrainRenderType.ordinal() * 512 * 7) * 16L;
long facingsStride = 112L;
int count = 0;
if (backFaceCulling) {
for(Iterator<RenderSection> iterator = queue.iterator(isTranslucent); iterator.hasNext(); ++count) {
RenderSection section = (RenderSection)iterator.next();
this.sectionIndices[count] = section.inAreaIndex;
this.masks[count] = this.getMask(cameraPos, section);
}
for(int j = 0; j < count; ++j) {
int sectionIdx = this.sectionIndices[j];
int mask = this.masks[j];
long drawParamsBasePtr2 = drawParamsBasePtr + (long)sectionIdx * 112L;
int indexCount = 0;
int firstIndex = 0;
int vertexOffset = 0;
int baseInstance = 0;
for(int i = 0; i < QuadFacing.COUNT; ++i) {
if ((mask & 1 << i) == 0) {
drawParamsBasePtr2 += 16L;
if (indexCount > 0) {
VK10.vkCmdDrawIndexed(commandBuffer, indexCount, 1, firstIndex, vertexOffset, baseInstance);
}
indexCount = 0;
firstIndex = 0;
vertexOffset = 0;
baseInstance = 0;
} else {
int indexCount_i = DrawParametersBuffer.getIndexCount(drawParamsBasePtr2);
int firstIndex_i = DrawParametersBuffer.getFirstIndex(drawParamsBasePtr2);
int vertexOffset_i = DrawParametersBuffer.getVertexOffset(drawParamsBasePtr2);
int baseInstance_i = DrawParametersBuffer.getBaseInstance(drawParamsBasePtr2);
if (indexCount == 0) {
indexCount = indexCount_i;
firstIndex = firstIndex_i;
vertexOffset = vertexOffset_i;
baseInstance = baseInstance_i;
} else {
indexCount += indexCount_i;
}
drawParamsBasePtr2 += 16L;
}
}
if (indexCount > 0) {
VK10.vkCmdDrawIndexed(commandBuffer, indexCount, 1, firstIndex, vertexOffset, baseInstance);
}
}
} else {
long facingOffset = (long)UNDEFINED_FACING_IDX * 16L;
drawParamsBasePtr += facingOffset;
for(Iterator<RenderSection> iterator = queue.iterator(isTranslucent); iterator.hasNext(); ++count) {
RenderSection section = (RenderSection)iterator.next();
this.sectionIndices[count] = section.inAreaIndex;
}
for(int i = 0; i < count; ++i) {
int sectionIdx = this.sectionIndices[i];
long drawParamsPtr = drawParamsBasePtr + (long)sectionIdx * 112L;
int indexCount = DrawParametersBuffer.getIndexCount(drawParamsPtr);
int firstIndex = DrawParametersBuffer.getFirstIndex(drawParamsPtr);
int vertexOffset = DrawParametersBuffer.getVertexOffset(drawParamsPtr);
int baseInstance = DrawParametersBuffer.getBaseInstance(drawParamsPtr);
if (indexCount > 0) {
VK10.vkCmdDrawIndexed(commandBuffer, indexCount, 1, firstIndex, vertexOffset, baseInstance);
}
}
}
}
private int getMask(class_243 camera, RenderSection section) {
int secX = section.xOffset;
int secY = section.yOffset;
int secZ = section.zOffset;
int mask = 1 << UNDEFINED_FACING_IDX;
mask |= camera.field_1352 - (double)secX >= (double)0.0F ? 1 << QuadFacing.X_POS.ordinal() : 0;
mask |= camera.field_1351 - (double)secY >= (double)0.0F ? 1 << QuadFacing.Y_POS.ordinal() : 0;
mask |= camera.field_1350 - (double)secZ >= (double)0.0F ? 1 << QuadFacing.Z_POS.ordinal() : 0;
mask |= camera.field_1352 - (double)(secX + 16) < (double)0.0F ? 1 << QuadFacing.X_NEG.ordinal() : 0;
mask |= camera.field_1351 - (double)(secY + 16) < (double)0.0F ? 1 << QuadFacing.Y_NEG.ordinal() : 0;
mask |= camera.field_1350 - (double)(secZ + 16) < (double)0.0F ? 1 << QuadFacing.Z_NEG.ordinal() : 0;
return mask;
}
public void bindBuffers(VkCommandBuffer commandBuffer, Pipeline pipeline, TerrainRenderType terrainRenderType, double camX, double camY, double camZ) {
MemoryStack stack = MemoryStack.stackPush();
try {
AreaBuffer vertexBuffer = this.getAreaBuffer(terrainRenderType);
VK10.nvkCmdBindVertexBuffers(commandBuffer, 0, 1, stack.npointer(vertexBuffer.getId()), stack.npointer(0L));
this.updateChunkAreaOrigin(commandBuffer, pipeline, camX, camY, camZ, stack);
} catch (Throwable var14) {
if (stack != null) {
try {
stack.close();
} catch (Throwable var13) {
var14.addSuppressed(var13);
}
}
throw var14;
}
if (stack != null) {
stack.close();
}
if (terrainRenderType == TerrainRenderType.TRANSLUCENT && this.indexBuffer != null) {
VK10.vkCmdBindIndexBuffer(commandBuffer, this.indexBuffer.getId(), 0L, 0);
}
}
public void releaseBuffers() {
if (this.allocated) {
this.vertexBuffers.values().forEach(AreaBuffer::freeBuffer);
this.vertexBuffers.clear();
if (this.indexBuffer != null) {
this.indexBuffer.freeBuffer();
}
this.indexBuffer = null;
this.allocated = false;
}
}
public void free() {
this.releaseBuffers();
DrawParametersBuffer.freeBuffer(this.drawParamsPtr);
}
public boolean isAllocated() {
return !this.vertexBuffers.isEmpty();
}
public EnumMap<TerrainRenderType, AreaBuffer> getVertexBuffers() {
return this.vertexBuffers;
}
public AreaBuffer getIndexBuffer() {
return this.indexBuffer;
}
public long getDrawParamsPtr() {
return this.drawParamsPtr;
}
static {
VERTEX_SIZE = PipelineManager.terrainVertexFormat.getVertexSize();
UNDEFINED_FACING_IDX = QuadFacing.UNDEFINED.ordinal();
POS_OFFSET = CustomVertexFormat.getPositionOffset();
cmdBufferPtr = MemoryUtil.nmemAlignedAlloc(32L, 512L * (long)QuadFacing.COUNT * 32L);
}
}
Download file