mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-10 20:25:03 +01:00
Who's counting?
- Atomically count instances in indirect instancer - Fixes indirect draws/instancers never being deleted - Fix baseDraw being set incorrectly on intel - Handle setting baseDraw in GlCompat#safeMultiDrawElementsIndirect
This commit is contained in:
parent
3811da166c
commit
00bd05af88
3 changed files with 20 additions and 14 deletions
|
@ -199,7 +199,6 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
drawBarrier();
|
drawBarrier();
|
||||||
|
|
||||||
GlProgram lastProgram = null;
|
GlProgram lastProgram = null;
|
||||||
int baseDrawUniformLoc = -1;
|
|
||||||
|
|
||||||
for (var multiDraw : multiDraws.get(visualType)) {
|
for (var multiDraw : multiDraws.get(visualType)) {
|
||||||
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material);
|
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material);
|
||||||
|
@ -208,14 +207,11 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
|
|
||||||
// Don't need to do this unless the program changes.
|
// Don't need to do this unless the program changes.
|
||||||
drawProgram.bind();
|
drawProgram.bind();
|
||||||
baseDrawUniformLoc = drawProgram.getUniformLocation("_flw_baseDraw");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glUniform1ui(baseDrawUniformLoc, multiDraw.start);
|
|
||||||
|
|
||||||
MaterialRenderState.setup(multiDraw.material);
|
MaterialRenderState.setup(multiDraw.material);
|
||||||
|
|
||||||
multiDraw.submit();
|
multiDraw.submit(drawProgram);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +286,8 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private record MultiDraw(Material material, boolean embedded, int start, int end) {
|
private record MultiDraw(Material material, boolean embedded, int start, int end) {
|
||||||
private void submit() {
|
private void submit(GlProgram drawProgram) {
|
||||||
GlCompat.safeMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, this.start * IndirectBuffers.DRAW_COMMAND_STRIDE, this.end - this.start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE);
|
GlCompat.safeMultiDrawElementsIndirect(drawProgram, GL_TRIANGLES, GL_UNSIGNED_INT, this.start, this.end, IndirectBuffers.DRAW_COMMAND_STRIDE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
private final Vector4fc boundingSphere;
|
private final Vector4fc boundingSphere;
|
||||||
|
|
||||||
private final AtomicReference<InstancePage<I>[]> pages = new AtomicReference<>(pageArray(0));
|
private final AtomicReference<InstancePage<I>[]> pages = new AtomicReference<>(pageArray(0));
|
||||||
|
|
||||||
|
private final AtomicInteger instanceCount = new AtomicInteger(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The set of pages whose count changed and thus need their descriptor re-uploaded.
|
* The set of pages whose count changed and thus need their descriptor re-uploaded.
|
||||||
*/
|
*/
|
||||||
|
@ -145,6 +148,8 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
// We just filled the 17th instance, so we are no longer mergeable.
|
// We just filled the 17th instance, so we are no longer mergeable.
|
||||||
parent.mergeablePages.clear(pageNo);
|
parent.mergeablePages.clear(pageNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent.instanceCount.incrementAndGet();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,6 +208,7 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
}
|
}
|
||||||
// Set full page last so that other threads don't race to set the other bitsets.
|
// Set full page last so that other threads don't race to set the other bitsets.
|
||||||
parent.fullPages.clear(pageNo);
|
parent.fullPages.clear(pageNo);
|
||||||
|
parent.instanceCount.decrementAndGet();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -538,9 +544,7 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
}
|
}
|
||||||
|
|
||||||
public int instanceCount() {
|
public int instanceCount() {
|
||||||
// Not exactly accurate but it's an upper bound.
|
return instanceCount.get();
|
||||||
// TODO: maybe this could be tracked with an AtomicInteger?
|
|
||||||
return pages.get().length << ObjectStorage.LOG_2_PAGE_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.lwjgl.system.MemoryStack;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.backend.FlwBackend;
|
import dev.engine_room.flywheel.backend.FlwBackend;
|
||||||
import dev.engine_room.flywheel.backend.compile.core.Compilation;
|
import dev.engine_room.flywheel.backend.compile.core.Compilation;
|
||||||
|
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
|
||||||
import dev.engine_room.flywheel.backend.glsl.GlslVersion;
|
import dev.engine_room.flywheel.backend.glsl.GlslVersion;
|
||||||
import dev.engine_room.flywheel.lib.math.MoreMath;
|
import dev.engine_room.flywheel.lib.math.MoreMath;
|
||||||
|
|
||||||
|
@ -78,15 +79,20 @@ public final class GlCompat {
|
||||||
* but uses consecutive DI instead of MDI if MDI is known to not work well with the current driver.
|
* 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.
|
* Unlike the original function, stride cannot be equal to 0.
|
||||||
*/
|
*/
|
||||||
public static void safeMultiDrawElementsIndirect(int mode, int type, long indirect, int drawcount, int stride) {
|
public static void safeMultiDrawElementsIndirect(GlProgram drawProgram, int mode, int type, int start, int end, long stride) {
|
||||||
|
var count = end - start;
|
||||||
|
long indirect = start * stride;
|
||||||
|
|
||||||
if (GlCompat.DRIVER == Driver.INTEL) {
|
if (GlCompat.DRIVER == Driver.INTEL) {
|
||||||
// Intel renders garbage with MDI, but consecutive DI works fine.
|
// Intel renders garbage with MDI, but consecutive DI works "fine".
|
||||||
for (int i = 0; i < drawcount; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
drawProgram.setUInt("_flw_baseDraw", start + i);
|
||||||
GL40.glDrawElementsIndirect(mode, type, indirect);
|
GL40.glDrawElementsIndirect(mode, type, indirect);
|
||||||
indirect += stride;
|
indirect += stride;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GL43.glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
|
drawProgram.setUInt("_flw_baseDraw", start);
|
||||||
|
GL43.glMultiDrawElementsIndirect(mode, type, indirect, count, (int) stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue