Skip to content

Commit

Permalink
Use hardware copy for render target blits where possible
Browse files Browse the repository at this point in the history
Minecraft performs a blit using a fragment shader, which
is unnecessary when blending is not used. Using the fixed
function hardware to perform the blit is much faster and
doesn't utilize the rasterization engine.

This is a cherry-pick of cd18e7f, 1ac46d0, and e1bae36.
  • Loading branch information
jellysquid3 committed Feb 21, 2025
1 parent 3c95e1d commit e68abfb
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ private MixinConfig() {

this.addMixinRule("features.render", true);

this.addMixinRule("features.render.compositing", true);

this.addMixinRule("features.render.entity", true);
this.addMixinRule("features.render.entity.cull", true);
this.addMixinRule("features.render.entity.shadow", true);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package me.jellysquid.mods.sodium.mixin.features.render.compositing;


import net.caffeinemc.mods.sodium.client.compatibility.workarounds.Workarounds;
import net.minecraft.client.gl.Framebuffer;
import org.lwjgl.opengl.GL32C;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(Framebuffer.class)
public class FramebufferMixin {
@Shadow
public int fbo;

@Shadow
public int textureWidth;

@Shadow
public int textureHeight;

/**
* @author JellySquid
* @reason Use fixed function hardware for framebuffer blits
*/
@Inject(method = "drawInternal", at = @At("HEAD"), cancellable = true)
public void blitToScreen(int width, int height, boolean disableBlend, CallbackInfo ci) {
if (Workarounds.isWorkaroundEnabled(Workarounds.Reference.INTEL_FRAMEBUFFER_BLIT_CRASH_WHEN_UNFOCUSED)) {
return;
}

if (disableBlend) {
ci.cancel();

// When blending is not used, we can directly copy the contents of one
// framebuffer to another using the blitting engine. This can save a lot of time
// when compared to going through the rasterization pipeline.
GL32C.glBindFramebuffer(GL32C.GL_READ_FRAMEBUFFER, this.fbo);
GL32C.glBlitFramebuffer(
0, 0, width, height,
0, 0, width, height,
GL32C.GL_COLOR_BUFFER_BIT, GL32C.GL_LINEAR);
GL32C.glBindFramebuffer(GL32C.GL_READ_FRAMEBUFFER, 0);
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/sodium.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"features.options.render_layers.LeavesBlockMixin",
"features.options.render_layers.RenderLayersMixin",
"features.options.weather.WorldRendererMixin",
"features.render.compositing.FramebufferMixin",
"features.render.entity.CuboidMixin",
"features.render.entity.ModelPartMixin",
"features.render.entity.cull.EntityRendererMixin",
Expand Down

0 comments on commit e68abfb

Please sign in to comment.