Skip to content

Commit

Permalink
Test 3 (not working)
Browse files Browse the repository at this point in the history
  • Loading branch information
IMS212 committed Aug 11, 2023
1 parent c63cfd6 commit 3b7750d
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 15 deletions.
4 changes: 3 additions & 1 deletion src/main/java/net/coderbot/iris/Iris.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.coderbot.iris.compat.sodium.SodiumVersionCheck;
import net.coderbot.iris.config.IrisConfig;
import net.coderbot.iris.gl.GLDebug;
import net.coderbot.iris.gl.buffer.IrisUniformBuffer;
import net.coderbot.iris.gl.shader.ShaderCompileException;
import net.coderbot.iris.gl.shader.StandardMacros;
import net.coderbot.iris.gui.debug.DebugLoadFailedGridScreen;
Expand Down Expand Up @@ -72,8 +73,9 @@ public class Iris {
public static final String MODNAME = "Iris";

public static final IrisLogging logger = new IrisLogging(MODNAME);
public static IrisUniformBuffer bufferObject;

private static Path shaderpacksDirectory;
private static Path shaderpacksDirectory;
private static ShaderpackDirectoryManager shaderpacksDirectoryManager;

private static ShaderPack currentPack;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

public class IrisUniformBuffer implements LocationalUniformHolder {
private Map<UniformUpdateFrequency, List<Uniform>> uniformList = new HashMap<>();
public List<String> uniformNameList = new ArrayList<>();
private int size;
private ArrayList<Pair<UniformUpdateFrequency, Uniform>> uniformOrder;
private long lastTick;
Expand All @@ -44,8 +45,11 @@ public void finish() {
uniform.second().setBufferIndex(size);
Iris.logger.warn("Uniform " + uniform.second().getType().name() + " added at " + size);
size += uniform.second().getByteSize();
uniformNameList.add(uniform.second().getName());
}

size = align(size, 256);

Iris.logger.warn("Final size: " + size);

Iris.logger.warn(getLayout());
Expand All @@ -56,7 +60,7 @@ public void finish() {
public String getLayout() {
StringBuilder builder = new StringBuilder();

builder.append("layout (std140, binding = 1) uniform CommonUniforms {\n");
builder.append("layout (std140, binding = 2) uniform CommonUniforms {\n");
uniformOrder.forEach(uniformInformation -> builder.append(uniformInformation.second().getType().name().toLowerCase()).append(" ").append(uniformInformation.second().getName()).append(";").append("\n"));


Expand Down
12 changes: 6 additions & 6 deletions src/main/java/net/coderbot/iris/gl/buffer/UniformBuffer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.coderbot.iris.gl.buffer;

import net.coderbot.iris.Iris;
import org.lwjgl.opengl.GL46C;

public class UniformBuffer {
Expand All @@ -13,7 +14,7 @@ public UniformBuffer(long size) {
this.size = size;
this.buffer = GL46C.glCreateBuffers();
GL46C.glNamedBufferStorage(buffer, size * 3L, GL46C.GL_MAP_WRITE_BIT | GL46C.GL_MAP_PERSISTENT_BIT | GL46C.GL_CLIENT_STORAGE_BIT);
this.address = GL46C.nglMapNamedBuffer(buffer, GL46C.GL_MAP_PERSISTENT_BIT | GL46C.GL_MAP_INVALIDATE_BUFFER_BIT | GL46C.GL_MAP_WRITE_BIT | GL46C.GL_MAP_FLUSH_EXPLICIT_BIT);
this.address = GL46C.nglMapNamedBufferRange(buffer, 0, size * 3L, GL46C.GL_MAP_PERSISTENT_BIT | GL46C.GL_MAP_INVALIDATE_BUFFER_BIT | GL46C.GL_MAP_WRITE_BIT | GL46C.GL_MAP_FLUSH_EXPLICIT_BIT);
}

public long getWriteAddressForFrame() {
Expand All @@ -25,15 +26,14 @@ public long getReadAddressForFrame() {
}

public void updateFrame() {
GL46C.glFlush();
GL46C.glFinish();
GL46C.glFlushMappedNamedBufferRange(buffer, size * frameId, size);
GL46C.glBindBufferRange(GL46C.GL_UNIFORM_BUFFER, 2, buffer, (size * frameId), size);

lastFrameId = frameId;
frameId++;
if (frameId == 3) {
frameId = 0;
}
frameId = (frameId+1)%3;

GL46C.glBindBufferRange(GL46C.GL_UNIFORM_BUFFER, 2, buffer, (size * lastFrameId), size);
}

public void destroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ private static UniformType getExpectedType(int type) {
} else if (type == GL20C.GL_INT) {
return UniformType.INT;
} else if (type == GL20C.GL_BOOL) {
return UniformType.BOOL;
return UniformType.INT;
} else if (type == GL20C.GL_FLOAT_MAT4) {
return UniformType.MAT4;
} else if (type == GL20C.GL_FLOAT_VEC4) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,4 @@ public class BooleanUniform extends IntUniform {
super(name, location, () -> value.getAsBoolean() ? 1 : 0);
}

@Override
public UniformType getType() {
return UniformType.BOOL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ default LocationalUniformHolder uniform1i(UniformUpdateFrequency updateFrequency

@Override
default LocationalUniformHolder uniform1b(UniformUpdateFrequency updateFrequency, String name, BooleanSupplier value) {
location(name, UniformType.BOOL).ifPresent(id -> addUniform(updateFrequency, new BooleanUniform(name, id, value)));
location(name, UniformType.INT).ifPresent(id -> addUniform(updateFrequency, new BooleanUniform(name, id, value)));

return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void updateBuffer(long address) {

@Override
public UniformType getType() {
return UniformType.VEC2;
return UniformType.VEC3;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,73 @@
package net.coderbot.iris.mixin;

import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue;
import net.coderbot.iris.Iris;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.util.profiling.ProfilerFiller;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.opengl.GL32C;
import org.spongepowered.asm.mixin.Mixin;
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(Minecraft.class)
@Environment(EnvType.CLIENT)
public class MixinMinecraft_PipelineManagement {
@Unique
private final LongArrayFIFOQueue fences = new LongArrayFIFOQueue();

/**
* We run this at the beginning of the frame (except for the first frame) to give the previous frame plenty of time
* to render on the GPU. This allows us to stall on ClientWaitSync for less time.
*/
@Inject(method = "runTick", at = @At("HEAD"))
private void preRender(boolean tick, CallbackInfo ci) {
ProfilerFiller profiler = Minecraft.getInstance().getProfiler();
profiler.push("iris_wait_for_gpu");

while (this.fences.size() > 3) {
var fence = this.fences.dequeueLong();
// We do a ClientWaitSync here instead of a WaitSync to not allow the CPU to get too far ahead of the GPU.
// This is also needed to make sure that our persistently-mapped staging buffers function correctly, rather
// than being overwritten by data meant for future frames before the current one has finished rendering on
// the GPU.
//
// Because we use GL_SYNC_FLUSH_COMMANDS_BIT, a flush will be inserted at some point in the command stream
// (the stream of commands the GPU and/or driver (aka. the "server") is processing).
// In OpenGL 4.4 contexts and below, the flush will be inserted *right before* the call to ClientWaitSync.
// In OpenGL 4.5 contexts and above, the flush will be inserted *right after* the call to FenceSync (the
// creation of the fence).
// The flush, when the server reaches it in the command stream and processes it, tells the server that it
// must *finish execution* of all the commands that have already been processed in the command stream,
// and only after everything before the flush is done is it allowed to start processing and executing
// commands after the flush.
// Because we are also waiting on the client for the FenceSync to finish, the flush is effectively treated
// like a Finish command, where we know that once ClientWaitSync returns, it's likely that everything
// before it has been completed by the GPU.
GL32C.glClientWaitSync(fence, GL32C.GL_SYNC_FLUSH_COMMANDS_BIT, Long.MAX_VALUE);
GL32C.glDeleteSync(fence);
}

profiler.pop();
}

@Inject(method = "runTick", at = @At("RETURN"))
private void postRender(boolean tick, CallbackInfo ci) {
var fence = GL32C.glFenceSync(GL32C.GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

if (fence == 0) {
throw new RuntimeException("Failed to create fence object");
}

this.fences.enqueue(fence);
}

/**
* Should run before the Minecraft.level field is updated after disconnecting from a server or leaving a singleplayer world
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ public NewWorldRenderingPipeline(ProgramSet programSet) throws IOException {

buffer.finish();

Iris.bufferObject = buffer;

this.customImages = new HashSet<>();
for (ImageInformation information : programSet.getPack().getIrisCustomImages()) {
if (information.isRelative()) {
Expand Down Expand Up @@ -932,6 +934,8 @@ public void beginLevelRendering() {
// NB: execute this before resizing / clearing so that the center depth sample is retrieved properly.
updateNotifier.onNewFrame();

Iris.bufferObject.updateUniforms();

// Update custom uniforms
this.customUniforms.update();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;

import io.github.douira.glsl_transformer.ast.node.Identifier;
Expand Down Expand Up @@ -55,6 +56,17 @@ public class CommonTransformer {
}
};

public static final AutoHintedMatcher<ExternalDeclaration> uniform = new AutoHintedMatcher<>(
"uniform Type name;", ParseShape.EXTERNAL_DECLARATION, "__") {
{
markClassedPredicateWildcard("type",
pattern.getRoot().identifierIndex.getOne("Type").getAncestor(TypeSpecifier.class),
BuiltinNumericTypeSpecifier.class,
specifier -> specifier.type != null);
markClassWildcard("name*", pattern.getRoot().identifierIndex.getOne("name").getAncestor(DeclarationMember.class));
}
};

private static final AutoHintedMatcher<Expression> glFragDataI = new AutoHintedMatcher<>(
"gl_FragData[index]", ParseShape.EXPRESSION) {
{
Expand Down Expand Up @@ -117,6 +129,35 @@ public static void transform(
boolean core) {
// TODO: What if the shader does gl_PerVertex.gl_FogFragCoord ?

tree.parseAndInjectNode(t, ASTInjectionPoint.BEFORE_ALL, "#extension GL_ARB_shading_language_420pack : enable\n");
for (String name : Iris.bufferObject.uniformNameList) {
List<Identifier> uniformNames = new ArrayList<>();
AtomicBoolean hadName = new AtomicBoolean(false);
root.process(name, id -> {
DeclarationExternalDeclaration declaration = (DeclarationExternalDeclaration) id.getAncestor(
3, 0, DeclarationExternalDeclaration.class::isInstance);
if (uniform.matchesExtract(declaration)) {
DeclarationMember secondDeclarationMember = id.getAncestor(DeclarationMember.class);
if (((TypeAndInitDeclaration) secondDeclarationMember.getParent()).getMembers().size() == 1) {
declaration.detachAndDelete();
} else {
secondDeclarationMember.detachAndDelete();
}
hadName.set(true);
} else {
uniformNames.add(id);
}
});

uniformNames.forEach(name2 -> {
if (!hadName.get()) {
name2.setName("nonUniform_" + name);
}
});
}

tree.parseAndInjectNode(t, ASTInjectionPoint.BEFORE_DECLARATIONS, Iris.bufferObject.getLayout());

root.rename("gl_FogFragCoord", "iris_FogFragCoord");

// TODO: This doesn't handle geometry shaders... How do we do that?
Expand Down

0 comments on commit 3b7750d

Please sign in to comment.