diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java index c4d5fb8ea..f72f66af9 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java @@ -3,12 +3,10 @@ import static org.lwjgl.opengl.GL11.GL_TRIANGLES; import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; import static org.lwjgl.opengl.GL30.glUniform1ui; -import static org.lwjgl.opengl.GL40.glDrawElementsIndirect; import static org.lwjgl.opengl.GL42.GL_COMMAND_BARRIER_BIT; import static org.lwjgl.opengl.GL42.glMemoryBarrier; import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BARRIER_BIT; import static org.lwjgl.opengl.GL43.glDispatchCompute; -import static org.lwjgl.opengl.GL43.glMultiDrawElementsIndirect; import java.util.ArrayList; import java.util.Comparator; @@ -27,7 +25,6 @@ import dev.engine_room.flywheel.backend.engine.MeshPool; import dev.engine_room.flywheel.backend.engine.embed.Environment; import dev.engine_room.flywheel.backend.engine.uniform.Uniforms; -import dev.engine_room.flywheel.backend.gl.Driver; import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.backend.gl.shader.GlProgram; import dev.engine_room.flywheel.lib.math.MoreMath; @@ -282,14 +279,7 @@ public void delete() { private record MultiDraw(Material material, int start, int end) { private void submit() { - if (GlCompat.DRIVER == Driver.INTEL) { - // Intel renders garbage with MDI, but Consecutive Normal Draws works fine. - for (int i = this.start; i < this.end; i++) { - glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, i * IndirectBuffers.DRAW_COMMAND_STRIDE); - } - } else { - glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, this.start * IndirectBuffers.DRAW_COMMAND_STRIDE, this.end - this.start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE); - } + GlCompat.safeMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, this.start * IndirectBuffers.DRAW_COMMAND_STRIDE, this.end - this.start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE); } } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java index d860d2556..b7efa23ed 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java @@ -8,6 +8,8 @@ import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20C; import org.lwjgl.opengl.GL31C; +import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.GL43; import org.lwjgl.opengl.GLCapabilities; import org.lwjgl.opengl.KHRShaderSubgroup; import org.lwjgl.system.MemoryStack; @@ -71,6 +73,23 @@ public static void safeShaderSource(int glId, CharSequence source) { } } + /** + * Similar in function to {@link GL43#glMultiDrawElementsIndirect(int, int, long, int, int)}, + * but uses consecutive DI instead of MDI if MDI is known to not work well with the current driver. + * Unlike the original function, stride cannot be equal to 0. + */ + public static void safeMultiDrawElementsIndirect(int mode, int type, long indirect, int drawcount, int stride) { + if (GlCompat.DRIVER == Driver.INTEL) { + // Intel renders garbage with MDI, but consecutive DI works fine. + for (int i = 0; i < drawcount; i++) { + GL40.glDrawElementsIndirect(mode, type, indirect); + indirect += stride; + } + } else { + GL43.glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); + } + } + private static Driver readVendorString() { if (CAPABILITIES == null) { return Driver.UNKNOWN;