Skip to content

Commit db9e1b7

Browse files
committed
Merge remote-tracking branch 'upstream/1.20/dev' into feat/multi-loader-1.21
2 parents 69d9209 + 0c195fe commit db9e1b7

File tree

13 files changed

+71
-47
lines changed

13 files changed

+71
-47
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
restore-keys: "${{ runner.os }}-gradle-"
2424

2525
- name: Setup Gradle
26-
uses: gradle/actions/setup-gradle@v3
26+
uses: gradle/actions/setup-gradle@v4.2.0
2727
with:
2828
gradle-home-cache-cleanup: true
2929
cache-read-only: ${{ !endsWith(github.ref_name, '/dev') }}

common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightStorage.java

+38-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dev.engine_room.flywheel.backend.engine;
22

33
import java.util.BitSet;
4+
import java.util.Objects;
45

56
import org.jetbrains.annotations.Nullable;
67
import org.lwjgl.system.MemoryUtil;
@@ -34,6 +35,7 @@
3435
import net.minecraft.world.level.LevelAccessor;
3536
import net.minecraft.world.level.LightLayer;
3637
import net.minecraft.world.level.chunk.DataLayer;
38+
import net.minecraft.world.level.lighting.LayerLightEventListener;
3739

3840
/**
3941
* A managed arena of light sections for uploading to the GPU.
@@ -57,8 +59,8 @@ public class LightStorage implements Effect {
5759
private static final int DEFAULT_ARENA_CAPACITY_SECTIONS = 64;
5860
private static final int INVALID_SECTION = -1;
5961

60-
private static final ConstantDataLayer EMPTY_BLOCK_DATA = new ConstantDataLayer(0);
61-
private static final ConstantDataLayer EMPTY_SKY_DATA = new ConstantDataLayer(15);
62+
private static final ConstantDataLayer ALWAYS_0 = new ConstantDataLayer(0);
63+
private static final ConstantDataLayer ALWAYS_15 = new ConstantDataLayer(15);
6264

6365
private final LevelAccessor level;
6466
private final LightLut lut;
@@ -268,29 +270,51 @@ private void collectSolidData(long ptr, long section) {
268270
}
269271

270272
private DataLayer getSkyData(long section) {
271-
var sky = level.getLightEngine()
273+
var layerListener = level.getLightEngine()
272274
.getLayerListener(LightLayer.SKY);
273-
var skyStorage = (SkyLightSectionStorageExtension) ((LightEngineAccessor<?, ?>) sky).flywheel$storage();
274275

275-
var out = skyStorage.flywheel$skyDataLayer(section);
276+
if (layerListener == LayerLightEventListener.DummyLightLayerEventListener.INSTANCE) {
277+
// The dummy listener always returns 0.
278+
// In vanilla this happens in the nether and end,
279+
// and the light texture is simply updated
280+
// to be invariant on sky light.
281+
return ALWAYS_0;
282+
}
283+
284+
if (layerListener instanceof LightEngineAccessor<?, ?> accessor) {
285+
// Sky storage has a fancy way to get the sky light at a given block position, but the logic is not
286+
// implemented in vanilla for fetching data layers directly. We need to re-implement it here. The simplest
287+
// way to do it was to expose the same logic via an extension method. Re-implementing it external to the
288+
// SkyLightSectionStorage class would require many more accessors.
289+
if (accessor.flywheel$storage() instanceof SkyLightSectionStorageExtension skyStorage) {
290+
var out = skyStorage.flywheel$skyDataLayer(section);
276291

277-
if (out == null) {
278-
return EMPTY_SKY_DATA;
292+
// Null section here means there are no blocks above us to darken this section.
293+
return Objects.requireNonNullElse(out, ALWAYS_15);
294+
}
279295
}
280296

281-
return out;
297+
// FIXME: We're likely in some exotic dimension that needs special handling.
298+
return ALWAYS_0;
282299
}
283300

284301
private DataLayer getBlockData(long section) {
285-
var out = ((LightEngineAccessor<?, ?>) level.getLightEngine()
286-
.getLayerListener(LightLayer.BLOCK)).flywheel$storage()
287-
.getDataLayerData(section);
302+
var layerListener = level.getLightEngine()
303+
.getLayerListener(LightLayer.BLOCK);
288304

289-
if (out == null) {
290-
return EMPTY_BLOCK_DATA;
305+
if (layerListener == LayerLightEventListener.DummyLightLayerEventListener.INSTANCE) {
306+
return ALWAYS_0;
291307
}
292308

293-
return out;
309+
if (layerListener instanceof LightEngineAccessor<?, ?> accessor) {
310+
var out = accessor.flywheel$storage()
311+
.getDataLayerData(section);
312+
313+
return Objects.requireNonNullElse(out, ALWAYS_0);
314+
}
315+
316+
// FIXME: We're likely in some exotic dimension that needs special handling.
317+
return ALWAYS_0;
294318
}
295319

296320
private void collectXStrip(long ptr, long section, SectionEdge y, SectionEdge z) {

common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,9 @@ public void bindForDraw() {
109109
GlBufferType.DRAW_INDIRECT_BUFFER.bind(draw.handle());
110110
}
111111

112-
/**
113-
* Bind all buffers except the draw command buffer.
114-
*/
115112
public void bindForCrumbling() {
116-
multiBind(1, 4);
113+
// All we need is the instance buffer. Crumbling uses its own draw buffer.
114+
multiBind(BufferBindings.INSTANCE, 1);
117115
}
118116

119117
private void multiBind(int base, int count) {

common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java

+6-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
44
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
5-
import static org.lwjgl.opengl.GL30.glUniform1ui;
65
import static org.lwjgl.opengl.GL42.GL_COMMAND_BARRIER_BIT;
76
import static org.lwjgl.opengl.GL42.glMemoryBarrier;
87
import static org.lwjgl.opengl.GL43.glDispatchCompute;
@@ -199,7 +198,6 @@ public void submit(VisualType visualType) {
199198
drawBarrier();
200199

201200
GlProgram lastProgram = null;
202-
int baseDrawUniformLoc = -1;
203201

204202
for (var multiDraw : multiDraws.get(visualType)) {
205203
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material);
@@ -208,28 +206,24 @@ public void submit(VisualType visualType) {
208206

209207
// Don't need to do this unless the program changes.
210208
drawProgram.bind();
211-
baseDrawUniformLoc = drawProgram.getUniformLocation("_flw_baseDraw");
212209
}
213210

214-
glUniform1ui(baseDrawUniformLoc, multiDraw.start);
215-
216211
MaterialRenderState.setup(multiDraw.material);
217212

218-
multiDraw.submit();
213+
multiDraw.submit(drawProgram);
219214
}
220215
}
221216

222-
public void bindWithContextShader(ContextShader override, Material material) {
223-
var program = programs.getIndirectProgram(instanceType, override, material);
217+
public void bindForCrumbling(Material material) {
218+
var program = programs.getIndirectProgram(instanceType, ContextShader.CRUMBLING, material);
224219

225220
program.bind();
226221

227222
buffers.bindForCrumbling();
228223

229224
drawBarrier();
230225

231-
var flwBaseDraw = program.getUniformLocation("_flw_baseDraw");
232-
glUniform1ui(flwBaseDraw, 0);
226+
program.setUInt("_flw_baseDraw", 0);
233227
}
234228

235229
private void drawBarrier() {
@@ -290,8 +284,8 @@ public boolean checkEmptyAndDelete() {
290284
}
291285

292286
private record MultiDraw(Material material, boolean embedded, int start, int end) {
293-
private void submit() {
294-
GlCompat.safeMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, this.start * IndirectBuffers.DRAW_COMMAND_STRIDE, this.end - this.start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE);
287+
private void submit(GlProgram drawProgram) {
288+
GlCompat.safeMultiDrawElementsIndirect(drawProgram, GL_TRIANGLES, GL_UNSIGNED_INT, this.start, this.end, IndirectBuffers.DRAW_COMMAND_STRIDE);
295289
}
296290
}
297291
}

common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import dev.engine_room.flywheel.api.instance.InstanceType;
1818
import dev.engine_room.flywheel.api.visualization.VisualType;
1919
import dev.engine_room.flywheel.backend.Samplers;
20-
import dev.engine_room.flywheel.backend.compile.ContextShader;
2120
import dev.engine_room.flywheel.backend.compile.IndirectPrograms;
2221
import dev.engine_room.flywheel.backend.engine.AbstractInstancer;
2322
import dev.engine_room.flywheel.backend.engine.CommonCrumbling;
@@ -235,7 +234,7 @@ public void renderCrumbling(List<Engine.CrumblingBlock> crumblingBlocks) {
235234
// Transform the material to be suited for crumbling.
236235
CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material());
237236

238-
cullingGroup.bindWithContextShader(ContextShader.CRUMBLING, crumblingMaterial);
237+
cullingGroup.bindForCrumbling(crumblingMaterial);
239238

240239
MaterialRenderState.setup(crumblingMaterial);
241240

common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
2525
private final Vector4fc boundingSphere;
2626

2727
private final AtomicReference<InstancePage<I>[]> pages = new AtomicReference<>(pageArray(0));
28+
29+
private final AtomicInteger instanceCount = new AtomicInteger(0);
30+
2831
/**
2932
* The set of pages whose count changed and thus need their descriptor re-uploaded.
3033
*/
@@ -145,6 +148,8 @@ public boolean add(I instance, InstanceHandleImpl<I> handle) {
145148
// We just filled the 17th instance, so we are no longer mergeable.
146149
parent.mergeablePages.clear(pageNo);
147150
}
151+
152+
parent.instanceCount.incrementAndGet();
148153
return true;
149154
}
150155
}
@@ -203,6 +208,7 @@ private void clear(int localIndex) {
203208
}
204209
// Set full page last so that other threads don't race to set the other bitsets.
205210
parent.fullPages.clear(pageNo);
211+
parent.instanceCount.decrementAndGet();
206212
break;
207213
}
208214
}
@@ -538,9 +544,7 @@ private void addInner(I instance, InstanceHandleImpl<I> handle) {
538544
}
539545

540546
public int instanceCount() {
541-
// Not exactly accurate but it's an upper bound.
542-
// TODO: maybe this could be tracked with an AtomicInteger?
543-
return pages.get().length << ObjectStorage.LOG_2_PAGE_SIZE;
547+
return instanceCount.get();
544548
}
545549

546550
/**

common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import dev.engine_room.flywheel.backend.FlwBackend;
1818
import dev.engine_room.flywheel.backend.compile.core.Compilation;
19+
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
1920
import dev.engine_room.flywheel.backend.glsl.GlslVersion;
2021
import dev.engine_room.flywheel.lib.math.MoreMath;
2122

@@ -78,15 +79,20 @@ public static void safeShaderSource(int glId, CharSequence source) {
7879
* but uses consecutive DI instead of MDI if MDI is known to not work well with the current driver.
7980
* Unlike the original function, stride cannot be equal to 0.
8081
*/
81-
public static void safeMultiDrawElementsIndirect(int mode, int type, long indirect, int drawcount, int stride) {
82+
public static void safeMultiDrawElementsIndirect(GlProgram drawProgram, int mode, int type, int start, int end, long stride) {
83+
var count = end - start;
84+
long indirect = start * stride;
85+
8286
if (GlCompat.DRIVER == Driver.INTEL) {
83-
// Intel renders garbage with MDI, but consecutive DI works fine.
84-
for (int i = 0; i < drawcount; i++) {
87+
// Intel renders garbage with MDI, but consecutive DI works "fine".
88+
for (int i = 0; i < count; i++) {
89+
drawProgram.setUInt("_flw_baseDraw", start + i);
8590
GL40.glDrawElementsIndirect(mode, type, indirect);
8691
indirect += stride;
8792
}
8893
} else {
89-
GL43.glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
94+
drawProgram.setUInt("_flw_baseDraw", start);
95+
GL43.glMultiDrawElementsIndirect(mode, type, indirect, count, (int) stride);
9096
}
9197
}
9298

common/src/lib/java/dev/engine_room/flywheel/lib/vertex/DefaultVertexList.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package dev.engine_room.flywheel.lib.vertex;
22

33
import dev.engine_room.flywheel.api.vertex.MutableVertexList;
4-
import net.minecraft.client.renderer.LightTexture;
54
import net.minecraft.client.renderer.texture.OverlayTexture;
65

76
public interface DefaultVertexList extends MutableVertexList {
@@ -57,7 +56,7 @@ default int overlay(int index) {
5756

5857
@Override
5958
default int light(int index) {
60-
return LightTexture.FULL_BRIGHT;
59+
return 0;
6160
}
6261

6362
@Override

common/src/lib/resources/assets/flywheel/flywheel/instance/oriented.vert

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ void flw_instanceVertex(in FlwInstance i) {
66
flw_vertexColor *= i.color;
77
flw_vertexOverlay = i.overlay;
88
// Some drivers have a bug where uint over float division is invalid, so use an explicit cast.
9-
flw_vertexLight = vec2(i.light) / 256.0;
9+
flw_vertexLight = max(vec2(i.light) / 256.0, flw_vertexLight);
1010
}

common/src/lib/resources/assets/flywheel/flywheel/instance/posed.vert

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ void flw_instanceVertex(in FlwInstance i) {
44
flw_vertexColor *= i.color;
55
flw_vertexOverlay = i.overlay;
66
// Some drivers have a bug where uint over float division is invalid, so use an explicit cast.
7-
flw_vertexLight = vec2(i.light) / 256.0;
7+
flw_vertexLight = max(vec2(i.light) / 256.0, flw_vertexLight);
88
}

common/src/lib/resources/assets/flywheel/flywheel/instance/transformed.vert

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ void flw_instanceVertex(in FlwInstance i) {
44
flw_vertexColor *= i.color;
55
flw_vertexOverlay = i.overlay;
66
// Some drivers have a bug where uint over float division is invalid, so use an explicit cast.
7-
flw_vertexLight = vec2(i.light) / 256.0;
7+
flw_vertexLight = max(vec2(i.light) / 256.0, flw_vertexLight);
88
}

fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public interface ResultConsumer {
144144
}
145145

146146
private static class ThreadLocalObjects {
147-
public final FabricOriginBlockAndTintGetter level = new FabricOriginBlockAndTintGetter(p -> 0, p -> 15);
147+
public final FabricOriginBlockAndTintGetter level = new FabricOriginBlockAndTintGetter(p -> 0, p -> 0);
148148
public final PoseStack identityPoseStack = new PoseStack();
149149
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
150150

neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public interface ResultConsumer {
143143
}
144144

145145
private static class ThreadLocalObjects {
146-
public final OriginBlockAndTintGetter level = new OriginBlockAndTintGetter(p -> 0, p -> 15);
146+
public final OriginBlockAndTintGetter level = new OriginBlockAndTintGetter(p -> 0, p -> 0);
147147
public final PoseStack identityPoseStack = new PoseStack();
148148
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
149149

0 commit comments

Comments
 (0)