Be more lazy (#1794)

* Be more lazy

---------

Co-authored-by: sisyphussy <221229741+sisyphussy@users.noreply.github.com>
This commit is contained in:
Jason Mitchellandsisyphussy authored and GitHub committed 2026-06-05 08:29:27 -07:00
1 parent ec278d3d7a
commit f325fd7fc3
6 files changed
+70 -44

No files matched your search

@@ -1,6 +1,5 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.backend.RenderBackend;
import org.taumc.glsl.ShaderParser;
import org.taumc.glsl.Transformer;
@@ -114,13 +113,17 @@ public class CompatShaderTransformer {
return result;
}
private static boolean needsTransformation(String source) {
// Shaders already at 330+ core don't need compat transformation
public static boolean isCoreShader(String source) {
final Matcher vm = VERSION_PATTERN.matcher(source);
if (vm.find()) {
final int version = Integer.parseInt(vm.group(1));
if (version >= 330 && "core".equals(vm.group(2))) return false;
return version >= 330 && "core".equals(vm.group(2));
}
return false;
}
private static boolean needsTransformation(String source) {
if (isCoreShader(source)) return false;
return NEEDS_TRANSFORM_PATTERN.matcher(source).find();
}
@@ -7,8 +7,6 @@ import com.gtnewhorizons.angelica.glsm.states.LightModelState;
import com.gtnewhorizons.angelica.glsm.states.LightState;
import com.gtnewhorizons.angelica.glsm.states.MaterialState;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Vector3f;
@@ -17,6 +15,8 @@ import org.lwjgl.opengl.GL11;
import java.nio.FloatBuffer;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
/**
* Per-program compat uniform location cache and upload manager.
*
@@ -157,11 +157,14 @@ public class CompatUniformManager {
}
}
public static void refreshCompatUniforms(int program) {
if (program == 0) return;
/**
* Uploads the emulated uniforms.
*
* @return Whether the program needs emulation (FFP or Iris Program)
*/
public static boolean refreshCompatUniforms(int program) {
final ProgramUniforms pu = programUniforms.get(program);
if (pu == null) return;
if (pu == null) return false;
final int[] locs = pu.locs;
// Matrix uniforms — skip if this program's storage already holds the current generation
@@ -205,6 +208,8 @@ public class CompatUniformManager {
uploadClipPlanes(locs);
}
}
return true;
}
private static void uploadMatrices(int[] locs, boolean mvChanged, boolean mvLinearChanged, boolean projChanged, boolean texMatChanged) {
@@ -187,22 +187,23 @@ public class GLStateManager {
private static boolean dirtyTexCoordAttrib;
private static boolean dirtyLightmapAttrib = true;
/** Flush deferred vertex attribute uploads. Called before draw to ensure default attrib values are current. */
public static void flushDeferredVertexAttribs() {
if (dirtyColorAttrib) {
// vertexFlags bits mark attribs the VBO already supplies; FFP supplies the rest via u_Current* uniforms.
// Skip the backend vertexAttrib call in either case.
public static void flushDeferredVertexAttribs(int vertexFlags) {
if (dirtyColorAttrib && (vertexFlags & VertexFlags.COLOR_BIT) == 0) {
RENDER_BACKEND.vertexAttrib4f(Usage.COLOR.getAttributeLocation(), color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
dirtyColorAttrib = false;
}
if (dirtyLightmapAttrib) {
if (dirtyLightmapAttrib && (vertexFlags & VertexFlags.BRIGHTNESS_BIT) == 0) {
RENDER_BACKEND.vertexAttrib4f(Usage.SECONDARY_UV.getAttributeLocation(), GLSMConfig.lastBrightnessX, GLSMConfig.lastBrightnessY, 0.0f, 1.0f);
dirtyLightmapAttrib = false;
}
if (dirtyNormalAttrib) {
if (dirtyNormalAttrib && (vertexFlags & VertexFlags.NORMAL_BIT) == 0) {
final var n = ShaderManager.getCurrentNormal();
RENDER_BACKEND.vertexAttrib3f(Usage.NORMAL.getAttributeLocation(), n.x, n.y, n.z);
dirtyNormalAttrib = false;
}
if (dirtyTexCoordAttrib) {
if (dirtyTexCoordAttrib && (vertexFlags & VertexFlags.TEXTURE_BIT) == 0) {
final var tc = ShaderManager.getCurrentTexCoord();
RENDER_BACKEND.vertexAttrib4f(Usage.PRIMARY_UV.getAttributeLocation(), tc.x, tc.y, tc.z, tc.w);
dirtyTexCoordAttrib = false;
@@ -3345,9 +3346,18 @@ public class GLStateManager {
if (texMatrixGeneration != savedTexMatGen[depth]) texMatrixGeneration++;
}
if ((mask & GL11.GL_CURRENT_BIT) != 0) {
if (colorGeneration != savedColorGen[depth]) colorGeneration++;
if (ShaderManager.getNormalGeneration() != savedNormalGen[depth]) ShaderManager.bumpNormalGeneration();
if (ShaderManager.getTexCoordGeneration() != savedTexCoordGen[depth]) ShaderManager.bumpTexCoordGeneration();
if (colorGeneration != savedColorGen[depth]) {
colorGeneration++;
dirtyColorAttrib = true;
}
if (ShaderManager.getNormalGeneration() != savedNormalGen[depth]) {
ShaderManager.bumpNormalGeneration();
dirtyNormalAttrib = true;
}
if (ShaderManager.getTexCoordGeneration() != savedTexCoordGen[depth]) {
ShaderManager.bumpTexCoordGeneration();
dirtyTexCoordAttrib = true;
}
}
}
@@ -22,7 +22,7 @@ import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACK
/**
* FFP shader manager
*/
public class ShaderManager {
public final class ShaderManager {
private static final class Holder {
@@ -88,8 +88,7 @@ public class ShaderManager {
public void activate() {
active = true;
updateVariant(true, true, true, true);
uploadUniforms();
lastBoundProgramId = GLStateManager.getActiveProgram();
}
public void deactivate() {
@@ -101,20 +100,22 @@ public class ShaderManager {
}
public void preDraw(boolean hasColor, boolean hasNormal, boolean hasTexCoord, boolean hasLightmap) {
GLStateManager.flushDeferredVertexAttribs();
final DeferredBlendHandler bh = GLSMHooks.blendHandler;
if (bh != null) bh.flushDeferredBlend();
if (!active) {
final int currentProgramId = GLStateManager.getActiveProgram();
if (currentProgramId != 0) {
CompatUniformManager.refreshCompatUniforms(currentProgramId);
return;
// Handle FFP & Iris uniforms
final int currentProgramId = GLStateManager.getActiveProgram();
if (currentProgramId != 0) {
if (!CompatUniformManager.refreshCompatUniforms(currentProgramId)) {
return; // Don't emulate FFP on non-iris core shaders
}
if (!enabled) return;
active = true;
}
GLStateManager.flushDeferredVertexAttribs(currentVertexFlags);
if (!active) return;
final int fkLen = FragmentKey.packFromState(currentFKScratch);
final int fragMask = FragmentKey.unitMaskFromPacked(currentFKScratch, fkLen);
final long vkPacked = VertexKey.packFromState(hasColor, hasNormal, hasTexCoord, hasLightmap, fragMask);
@@ -140,13 +141,6 @@ public class ShaderManager {
preDraw(currentVertexFlags);
}
private void updateVariant(boolean hasColor, boolean hasNormal, boolean hasTexCoord, boolean hasLightmap) {
final int fkLen = FragmentKey.packFromState(currentFKScratch);
final int fragMask = FragmentKey.unitMaskFromPacked(currentFKScratch, fkLen);
final long vkPacked = VertexKey.packFromState(hasColor, hasNormal, hasTexCoord, hasLightmap, fragMask);
commitVariant(vkPacked, fkLen);
}
private void commitVariant(long vkPacked, int fkLen) {
currentVertexKeyPacked = vkPacked;
System.arraycopy(currentFKScratch, 0, currentFKPacked, 0, fkLen);
@@ -6,6 +6,8 @@ import com.gtnewhorizons.angelica.glsm.hooks.GLSMInitConfig;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
@@ -19,7 +21,19 @@ import java.lang.reflect.Field;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL;
public class GLSMExtension implements BeforeAllCallback, BeforeEachCallback, AfterEachCallback, ExtensionContext.Store.CloseableResource {
public class GLSMExtension implements BeforeAllCallback, BeforeEachCallback, AfterEachCallback, ExecutionCondition, ExtensionContext.Store.CloseableResource {
// Compat profile is not available on OSX
private static final boolean IS_MAC = System.getProperty("os.name", "").toLowerCase().contains("mac");
private static final boolean FORCE_RUN = Boolean.getBoolean("angelica.glsm.test.forceRun");
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
if (IS_MAC && !FORCE_RUN) {
return ConditionEvaluationResult.disabled("Skipped on macOS: needs GL3+ compat profile");
}
return ConditionEvaluationResult.enabled("OS supports GL3+ compat profile");
}
private static final Unsafe theUnsafe;
static {
@@ -28,7 +28,7 @@ class VertexAttribDefaultBridgeTest {
@Test
void testGlColor4fSetsVertexAttrib() {
GLStateManager.glColor4f(0.5f, 0.25f, 0.75f, 0.8f);
GLStateManager.flushDeferredVertexAttribs();
GLStateManager.flushDeferredVertexAttribs(0);
float[] color = getVertexAttrib4f(COLOR_ATTRIB);
assertEquals(0.5f, color[0], EPSILON, "color.r");
@@ -40,7 +40,7 @@ class VertexAttribDefaultBridgeTest {
@Test
void testGlNormal3fSetsVertexAttrib() {
GLStateManager.glNormal3f(0.0f, 1.0f, 0.0f);
GLStateManager.flushDeferredVertexAttribs();
GLStateManager.flushDeferredVertexAttribs(0);
float[] normal = getVertexAttrib4f(NORMAL_ATTRIB);
assertEquals(0.0f, normal[0], EPSILON, "normal.x");
@@ -51,7 +51,7 @@ class VertexAttribDefaultBridgeTest {
@Test
void testSetLightmapTextureCoordsOnUnit1SetsVertexAttrib() {
GLStateManager.setLightmapTextureCoords(GL13.GL_TEXTURE1, 240.0f, 128.0f);
GLStateManager.flushDeferredVertexAttribs();
GLStateManager.flushDeferredVertexAttribs(0);
float[] lm = getVertexAttrib4f(SECONDARY_UV_ATTRIB);
assertEquals(240.0f, lm[0], EPSILON, "lightmap.s");
@@ -64,7 +64,7 @@ class VertexAttribDefaultBridgeTest {
void testGlTexCoord2fSetsVertexAttrib() {
// glTexCoord2f outside recording → sets default vertex attrib 2 (PRIMARY_UV)
GLStateManager.glTexCoord2f(0.5f, 0.75f);
GLStateManager.flushDeferredVertexAttribs();
GLStateManager.flushDeferredVertexAttribs(0);
float[] uv = getVertexAttrib4f(PRIMARY_UV_ATTRIB);
assertEquals(0.5f, uv[0], EPSILON, "texcoord.s");
@@ -77,7 +77,7 @@ class VertexAttribDefaultBridgeTest {
// Second call is a cache hit — changeColor not called.
// Vertex attrib should still hold the correct value from the first call.
GLStateManager.glColor4f(0.3f, 0.6f, 0.9f, 1.0f);
GLStateManager.flushDeferredVertexAttribs();
GLStateManager.flushDeferredVertexAttribs(0);
float[] color = getVertexAttrib4f(COLOR_ATTRIB);
assertEquals(0.3f, color[0], EPSILON, "color.r after dedup");
@@ -89,7 +89,7 @@ class VertexAttribDefaultBridgeTest {
@Test
void testCompileMode_DoesNotSetVertexAttrib() {
GLStateManager.glColor4f(0.1f, 0.2f, 0.3f, 1.0f);
GLStateManager.flushDeferredVertexAttribs();
GLStateManager.flushDeferredVertexAttribs(0);
int listId = GLStateManager.glGenLists(1);
GLStateManager.glNewList(listId, org.lwjgl.opengl.GL11.GL_COMPILE);