Skip to content

Commit

Permalink
Implement more VertexBufferWriter fallbacks (#2115)
Browse files Browse the repository at this point in the history
This also checks any delegate VertexConsumers for compatibility with the optimized rendering path.
  • Loading branch information
embeddedt authored Dec 3, 2023
1 parent 43e53c4 commit 37c08b7
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface VertexBufferWriter {
* @throws IllegalArgumentException If the vertex consumer does not implement the necessary interface
*/
static VertexBufferWriter of(VertexConsumer consumer) {
if (consumer instanceof VertexBufferWriter writer) {
if (consumer instanceof VertexBufferWriter writer && writer.canUseIntrinsics()) {
return writer;
}

Expand All @@ -31,7 +31,7 @@ static VertexBufferWriter of(VertexConsumer consumer) {
*/
@Nullable
static VertexBufferWriter tryOf(VertexConsumer consumer) {
if (consumer instanceof VertexBufferWriter writer) {
if (consumer instanceof VertexBufferWriter writer && writer.canUseIntrinsics()) {
return writer;
}

Expand Down Expand Up @@ -63,6 +63,16 @@ private static RuntimeException createUnsupportedVertexConsumerThrowable(VertexC
*/
void push(MemoryStack stack, long ptr, int count, VertexFormatDescription format);

/**
* If this {@link VertexBufferWriter} passes through data to nested {@link VertexConsumer} implementations,
* this method should be implemented to check that the nested implementations also support use of VertexBufferWriter
* methods.
* @return true if the inner consumer is also a valid {@link VertexBufferWriter} that can use intrinsics
*/
default boolean canUseIntrinsics() {
return true;
}

/**
* Creates a copy of the source data and pushes it into the specified {@param writer}. This is useful for when
* you need to use to re-use the source data after the call, and do not want the {@param writer} to modify
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,11 @@ private void duplicateVertex() {
this.grow(this.vertexStride);
}

@Override
public boolean canUseIntrinsics() {
return true;
}

@Override
public void push(MemoryStack stack, long src, int count, VertexFormatDescription format) {
var length = count * this.vertexStride;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,29 @@
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(targets = "net/minecraft/client/render/OutlineVertexConsumerProvider$OutlineVertexConsumer")
public abstract class OutlineVertexConsumerMixin extends FixedColorVertexConsumer implements VertexBufferWriter {
@Shadow
@Final
private VertexConsumer delegate;

@Unique
private boolean canUseIntrinsics;

@Inject(method = "<init>", at = @At("RETURN"))
private void onInit(CallbackInfo ci) {
this.canUseIntrinsics = VertexBufferWriter.tryOf(this.delegate) != null;
}

@Override
public boolean canUseIntrinsics() {
return this.canUseIntrinsics;
}

@Override
public void push(MemoryStack stack, long ptr, int count, VertexFormatDescription format) {
transform(ptr, count, format,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(OverlayVertexConsumer.class)
public class OverlayVertexConsumerMixin implements VertexBufferWriter {
Expand All @@ -39,6 +42,19 @@ public class OverlayVertexConsumerMixin implements VertexBufferWriter {
@Final
private float textureScale;

@Unique
private boolean canUseIntrinsics;

@Inject(method = "<init>", at = @At("RETURN"))
private void onInit(CallbackInfo ci) {
this.canUseIntrinsics = VertexBufferWriter.tryOf(this.delegate) != null;
}

@Override
public boolean canUseIntrinsics() {
return this.canUseIntrinsics;
}

@Override
public void push(MemoryStack stack, long ptr, int count, VertexFormatDescription format) {
transform(ptr, count, format,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class SpriteTexturedVertexConsumerMixin implements VertexBufferWriter {
@Final
private VertexConsumer delegate;

@Unique
private boolean canUseIntrinsics;

@Unique
private float minU, minV;

Expand All @@ -35,6 +38,13 @@ private void onInit(VertexConsumer delegate, Sprite sprite, CallbackInfo ci) {

this.maxU = sprite.getMaxU();
this.maxV = sprite.getMaxV();

this.canUseIntrinsics = VertexBufferWriter.tryOf(this.delegate) != null;
}

@Override
public boolean canUseIntrinsics() {
return this.canUseIntrinsics;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

public class VertexConsumersMixin {
@Mixin(targets = "net/minecraft/client/render/VertexConsumers$Dual")
Expand All @@ -20,6 +24,18 @@ public static class DualMixin implements VertexBufferWriter {
@Final
private VertexConsumer second;

private boolean canUseIntrinsics;

@Inject(method = "<init>", at = @At("RETURN"))
private void checkFullStatus(CallbackInfo ci) {
this.canUseIntrinsics = VertexBufferWriter.tryOf(this.first) != null && VertexBufferWriter.tryOf(this.second) != null;
}

@Override
public boolean canUseIntrinsics() {
return this.canUseIntrinsics;
}

@Override
public void push(MemoryStack stack, long ptr, int count, VertexFormatDescription format) {
VertexBufferWriter.copyInto(VertexBufferWriter.of(this.first), stack, ptr, count, format);
Expand All @@ -33,6 +49,29 @@ public static class UnionMixin implements VertexBufferWriter {
@Final
private VertexConsumer[] delegates;

private boolean canUseIntrinsics;

@Inject(method = "<init>", at = @At("RETURN"))
private void checkFullStatus(CallbackInfo ci) {
this.canUseIntrinsics = allDelegatesSupportIntrinsics();
}

@Unique
private boolean allDelegatesSupportIntrinsics() {
for (var delegate : this.delegates) {
if (VertexBufferWriter.tryOf(delegate) == null) {
return false;
}
}

return true;
}

@Override
public boolean canUseIntrinsics() {
return this.canUseIntrinsics;
}

@Override
public void push(MemoryStack stack, long ptr, int count, VertexFormatDescription format) {
for (var delegate : this.delegates) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.jellysquid.mods.sodium.mixin.features.render.entity.shadows;

import me.jellysquid.mods.sodium.client.render.vertex.VertexConsumerUtils;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.api.vertex.format.common.ModelVertex;
import net.caffeinemc.mods.sodium.api.util.ColorABGR;
Expand All @@ -20,8 +21,10 @@
import org.joml.Matrix4f;
import org.lwjgl.system.MemoryStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(EntityRenderDispatcher.class)
public class EntityRenderDispatcherMixin {
Expand All @@ -32,8 +35,16 @@ public class EntityRenderDispatcherMixin {
* @author JellySquid
* @reason Reduce vertex assembly overhead for shadow rendering
*/
@Overwrite
private static void renderShadowPart(MatrixStack.Entry entry, VertexConsumer vertices, Chunk chunk, WorldView world, BlockPos pos, double x, double y, double z, float radius, float opacity) {
@Inject(method = "renderShadowPart", at = @At("HEAD"), cancellable = true)
private static void renderShadowPartFast(MatrixStack.Entry entry, VertexConsumer vertices, Chunk chunk, WorldView world, BlockPos pos, double x, double y, double z, float radius, float opacity, CallbackInfo ci) {
var writer = VertexConsumerUtils.convertOrLog(vertices);

if (writer == null) {
return;
}

ci.cancel();

BlockPos blockPos = pos.down();
BlockState blockState = world.getBlockState(blockPos);

Expand Down Expand Up @@ -71,12 +82,12 @@ private static void renderShadowPart(MatrixStack.Entry entry, VertexConsumer ver
float minZ = (float) ((pos.getZ() + box.minZ) - z);
float maxZ = (float) ((pos.getZ() + box.maxZ) - z);

renderShadowPart(entry, vertices, radius, alpha, minX, maxX, minY, minZ, maxZ);
renderShadowPart(entry, writer, radius, alpha, minX, maxX, minY, minZ, maxZ);
}
}

@Unique
private static void renderShadowPart(MatrixStack.Entry matrices, VertexConsumer vertices, float radius, float alpha, float minX, float maxX, float minY, float minZ, float maxZ) {
private static void renderShadowPart(MatrixStack.Entry matrices, VertexBufferWriter writer, float radius, float alpha, float minX, float maxX, float minY, float minZ, float maxZ) {
float size = 0.5F * (1.0F / radius);

float u1 = (-minX * size) + 0.5F;
Expand Down Expand Up @@ -107,8 +118,7 @@ private static void renderShadowPart(MatrixStack.Entry matrices, VertexConsumer
writeShadowVertex(ptr, matPosition, maxX, minY, minZ, u2, v1, color, normal);
ptr += ModelVertex.STRIDE;

VertexBufferWriter.of(vertices)
.push(stack, buffer, 4, ModelVertex.FORMAT);
writer.push(stack, buffer, 4, ModelVertex.FORMAT);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.jellysquid.mods.sodium.mixin.features.render.gui.font;

import me.jellysquid.mods.sodium.client.render.vertex.VertexConsumerUtils;
import net.caffeinemc.mods.sodium.api.vertex.format.common.GlyphVertex;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.api.util.ColorABGR;
Expand All @@ -9,6 +10,9 @@
import org.joml.Matrix4f;
import org.lwjgl.system.MemoryStack;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(GlyphRenderer.class)
public class GlyphRendererMixin {
Expand Down Expand Up @@ -48,8 +52,16 @@ public class GlyphRendererMixin {
* @reason Use intrinsics
* @author JellySquid
*/
@Overwrite
public void draw(boolean italic, float x, float y, Matrix4f matrix, VertexConsumer vertexConsumer, float red, float green, float blue, float alpha, int light) {
@Inject(method = "draw", at = @At("HEAD"), cancellable = true)
private void drawFast(boolean italic, float x, float y, Matrix4f matrix, VertexConsumer vertexConsumer, float red, float green, float blue, float alpha, int light, CallbackInfo ci) {
var writer = VertexConsumerUtils.convertOrLog(vertexConsumer);

if (writer == null) {
return;
}

ci.cancel();

float x1 = x + this.minX;
float x2 = x + this.maxX;
float y1 = this.minY - 3.0F;
Expand All @@ -61,8 +73,6 @@ public void draw(boolean italic, float x, float y, Matrix4f matrix, VertexConsum

int color = ColorABGR.pack(red, green, blue, alpha);

var writer = VertexBufferWriter.of(vertexConsumer);

try (MemoryStack stack = MemoryStack.stackPush()) {
long buffer = stack.nmalloc(4 * GlyphVertex.STRIDE);
long ptr = buffer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.jellysquid.mods.sodium.mixin.features.render.gui.outlines;

import me.jellysquid.mods.sodium.client.render.vertex.VertexConsumerUtils;
import net.caffeinemc.mods.sodium.api.vertex.format.common.LineVertex;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.api.util.NormI8;
Expand All @@ -15,17 +16,28 @@
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(WorldRenderer.class)
public class WorldRendererMixin {
/**
* @author JellySquid
* @reason Use intrinsics where possible to speed up vertex writing
*/
@Overwrite
public static void drawBox(MatrixStack matrices, VertexConsumer vertexConsumer, double x1, double y1, double z1,
double x2, double y2, double z2, float red, float green, float blue, float alpha,
float xAxisRed, float yAxisGreen, float zAxisBlue) {
@Inject(method = "drawBox(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;DDDDDDFFFFFFF)V", at = @At("HEAD"), cancellable = true)
private static void drawBoxFast(MatrixStack matrices, VertexConsumer vertexConsumer, double x1, double y1, double z1,
double x2, double y2, double z2, float red, float green, float blue, float alpha,
float xAxisRed, float yAxisGreen, float zAxisBlue, CallbackInfo ci) {
var writer = VertexConsumerUtils.convertOrLog(vertexConsumer);

if (writer == null) {
return;
}

ci.cancel();

Matrix4f position = matrices.peek().getPositionMatrix();
Matrix3f normal = matrices.peek().getNormalMatrix();

Expand Down Expand Up @@ -70,8 +82,6 @@ public static void drawBox(MatrixStack matrices, VertexConsumer vertexConsumer,
float v8y = Math.fma(position.m01(), x2f, Math.fma(position.m11(), y2f, Math.fma(position.m21(), z2f, position.m31())));
float v8z = Math.fma(position.m02(), x2f, Math.fma(position.m12(), y2f, Math.fma(position.m22(), z2f, position.m32())));

var writer = VertexBufferWriter.of(vertexConsumer);

writeLineVertices(writer, v1x, v1y, v1z, ColorABGR.pack(red, yAxisGreen, zAxisBlue, alpha), NormI8.pack(normal.m00(), normal.m01(), normal.m02()));
writeLineVertices(writer, v2x, v2y, v2z, ColorABGR.pack(red, yAxisGreen, zAxisBlue, alpha), NormI8.pack(normal.m00(), normal.m01(), normal.m02()));
writeLineVertices(writer, v1x, v1y, v1z, ColorABGR.pack(xAxisRed, green, zAxisBlue, alpha), NormI8.pack(normal.m10(), normal.m11(), normal.m12()));
Expand Down

0 comments on commit 37c08b7

Please sign in to comment.