Slick2D Shader Crash

I’m using Slick2D’s ShaderProgram for shader-based drawing in my game. Some players report that after 3-10 minutes, the game inevitably crashes hard during what appears to be a setUniform4f operation that’s happened thousands of times before:


[error occurred during error reporting (printing native stack), id 0xc0000005]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J  org.lwjgl.opengl.ARBShaderObjects.nglUniform4fARB(IFFFFJ)V
J  com.zarkonnen.airships.Appearance.draw(Lcom/zarkonnen/catengine/Draw;DDDDILcom/zarkonnen/catengine/util/Clr;Z)V

Why might this happen? Is it a transient problem, or maybe a driver issue? I’m confused that this happens not when the shader is bound, or when textures are set, but at the point of this utterly mundane operation of setting a 4f value. I’m in fact pretty lost here, as I can’t even repro this on any of my own machines.

This is the culprit function in its entirety:


public void draw(Draw d, double x, double y, double w, double h, int ms, Clr tint, boolean flipped) {
if (shaderLoadFailed) {
	drawFallback(d, x, y, w, h, ms, tint, flipped);
	return;
}

if (tex == null) {
	tex = loadTex(SPRITESHEET);
	if (tex == null) {
		shaderLoadFailed = true;
	}
}
if (sp == null) {
	try {
		sp = ShaderProgram.loadProgram(
				AGame.getGameDirectoryPath("data/passthrough.vert"),
				AGame.getGameDirectoryPath("data/frag.frag"));
	} catch (Exception e) {
		e.printStackTrace();
		shaderLoadFailed = true;
	}
}

if (shaderLoadFailed) { return; }

sp.bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL11.GL_TEXTURE_2D, tex.getTextureID());
sp.setUniform1i("tex", 0);
if (tint == null) {
	sp.setUniform4f("tint", 1.0f, 1.0f, 1.0f, 1.0f);
} else {
	sp.setUniform4f("tint", tint.r / 255.0f, tint.g / 255.0f, tint.b / 255.0f, 1.0f);
}

Img img = frames.get((ms / interval) % frames.size());

glBegin(GL_QUADS);
if (flipped ^ isFlipped) {
	glTexCoord2d(img.srcX, img.srcY);
	glVertex2d(x + w, y);
	glTexCoord2d(img.srcX, img.srcY + img.srcHeight);
	glVertex2d(x + w, y + h);
	glTexCoord2d(img.srcX + img.srcWidth, img.srcY + img.srcHeight);
	glVertex2d(x, y + h);
	glTexCoord2d(img.srcX + img.srcWidth, img.srcY);
	glVertex2d(x, y);
} else {
	glTexCoord2d(img.srcX, img.srcY);
	glVertex2d(x, y);
	glTexCoord2d(img.srcX, img.srcY + img.srcHeight);
	glVertex2d(x, y + h);
	glTexCoord2d(img.srcX + img.srcWidth, img.srcY + img.srcHeight);
	glVertex2d(x + w, y + h);
	glTexCoord2d(img.srcX + img.srcWidth, img.srcY);
	glVertex2d(x + w, y);
}
glEnd();
sp.unbind();
TextureImpl.bindNone();
}

And the shaders FWIW:

passthrough.vert


void main() {
   gl_TexCoord[0] = gl_MultiTexCoord0;
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

frag.frag


uniform sampler2D tex;
uniform vec4 tint;

void main(void) {    
	gl_FragColor = texture2D(tex, floor(gl_TexCoord[0].st) / 1024.0) * tint;
}

As you can see, there’s very little to them.