I've replicated the bug with a small test case. This is the complete code:
package bugtest;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.glfw.GLFW.glfwShowWindow;
import org.lwjgl.opengl.GL;
import static org.lwjgl.opengl.GL11.GL_FALSE;
import static org.lwjgl.opengl.GL11.GL_TRUE;
import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS;
import static org.lwjgl.opengl.GL20.GL_INFO_LOG_LENGTH;
import static org.lwjgl.opengl.GL20.GL_LINK_STATUS;
import static org.lwjgl.opengl.GL20.GL_VALIDATE_STATUS;
import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER;
import static org.lwjgl.opengl.GL20.glAttachShader;
import static org.lwjgl.opengl.GL20.glCompileShader;
import static org.lwjgl.opengl.GL20.glCreateProgram;
import static org.lwjgl.opengl.GL20.glCreateShader;
import static org.lwjgl.opengl.GL20.glGetProgramInfoLog;
import static org.lwjgl.opengl.GL20.glGetProgrami;
import static org.lwjgl.opengl.GL20.glGetShaderInfoLog;
import static org.lwjgl.opengl.GL20.glGetShaderi;
import static org.lwjgl.opengl.GL20.glLinkProgram;
import static org.lwjgl.opengl.GL20.glShaderSource;
import static org.lwjgl.opengl.GL20.glValidateProgram;
import static org.lwjgl.opengl.GL30.GL_INTERLEAVED_ATTRIBS;
import static org.lwjgl.opengl.GL30.glTransformFeedbackVaryings;
import static org.lwjgl.opengl.GL32.GL_GEOMETRY_SHADER;
import org.lwjgl.system.Configuration;
import static org.lwjgl.system.MemoryUtil.NULL;
public class BugTest {
static final String nativesPath = System.getProperty("user.dir") + "\\native";
static final String[] varyings = new String[] {
"out_Position",
"out_Velocity",
"out_Color",
"out_Fade",
"out_Anim",
};
static final String stage1Source = "#version 330\n" +
"\n" +
"layout(location = 0) in vec4 in_Position;\n" +
"layout(location = 1) in vec4 in_Velocity;\n" +
"layout(location = 2) in vec4 in_Color;\n" +
"layout(location = 3) in vec4 in_Fade;\n" +
"layout(location = 4) in vec4 in_Anim;\n" +
"\n" +
"out vec4 pass_Position;\n" +
"out vec4 pass_Velocity;\n" +
"out vec4 pass_Color;\n" +
"out vec4 pass_Fade;\n" +
"out vec4 pass_Anim;\n" +
"\n" +
"void main() {\n" +
" pass_Position = in_Position;\n" +
" pass_Velocity = in_Velocity;\n" +
" pass_Color = in_Color;\n" +
" pass_Fade = in_Fade;\n" +
" pass_Anim = in_Anim;\n" +
"};";
static final String stage2Source = "#version 330 core\n" +
"\n" +
"layout(points) in;\n" +
"layout(points, max_vertices = 1) out;\n" +
"\n" +
"in vec4 pass_Position[];\n" +
"in vec4 pass_Velocity[];\n" +
"in vec4 pass_Color[];\n" +
"in vec4 pass_Fade[];\n" +
"in vec4 pass_Anim[];\n" +
"\n" +
"out vec4 out_Position;\n" +
"out vec4 out_Velocity;\n" +
"out vec4 out_Color;\n" +
"out vec4 out_Fade;\n" +
"out vec4 out_Anim;\n" +
"\n" +
"void main() {\n" +
" out_Position = pass_Position[0];\n" +
" out_Velocity = pass_Velocity[0];\n" +
" out_Color = pass_Color[0];\n" +
" out_Fade = pass_Fade[0];\n" +
" out_Anim = pass_Anim[0];\n" +
"};";
public static void main(String[] args) {
openWindow();
GL.createCapabilities();
compile();
}
static void openWindow() {
Configuration.LIBRARY_PATH.set(nativesPath);
glfwInit();
long window = glfwCreateWindow(800, 600, "", NULL, NULL);
glfwMakeContextCurrent(window);
glfwShowWindow(window);
}
static void compile() {
int program = glCreateProgram();
int stage1 = generateShader(GL_VERTEX_SHADER, stage1Source);
int stage2 = generateShader(GL_GEOMETRY_SHADER, stage2Source);
link(program, stage1, stage2);
validate(program);
}
private static int generateShader(int type, String source) {
int id = glCreateShader(type);
glShaderSource(id, source);
glCompileShader(id);
String log = glGetShaderInfoLog(id, glGetShaderi(id, GL_INFO_LOG_LENGTH));
if (log.equals("")) { log = "No error"; }
System.out.println("Compiling: \n" + log);
System.out.println();
if (glGetShaderi(id, GL_COMPILE_STATUS) == GL_FALSE) {
throw new IllegalStateException("Unable to compile");
}
return id;
}
private static void link(int program, int stage1, int stage2) {
glAttachShader(program, stage1);
glAttachShader(program, stage2);
glTransformFeedbackVaryings(program, varyings, GL_INTERLEAVED_ATTRIBS);
glLinkProgram(program);
String linkStatus = glGetProgramInfoLog(program, glGetProgrami(program, GL_INFO_LOG_LENGTH));
if (linkStatus.equals("")) { linkStatus = "No error"; }
System.out.println("Link status: \n" + linkStatus);
System.out.println("");
if (glGetProgrami(program, GL_LINK_STATUS) != GL_TRUE) {
throw new IllegalStateException("Unable to link");
}
}
private static void validate(int program) {
glValidateProgram(program);
String validateStatus = glGetProgramInfoLog(program, glGetProgrami(program, GL_INFO_LOG_LENGTH));
if (validateStatus.equals("")) { validateStatus = "No error"; }
System.out.println("Validation status: \n" + validateStatus);
System.out.println("");
if (glGetProgrami(program, GL_VALIDATE_STATUS) != GL_TRUE) {
throw new RuntimeException("Unable to validate");
}
}
}
The above code compiles a vertex+geometry shader, specifying a few varyings. Under LWJGL 3.0.0, the output is:
Compiling:
No error
Compiling:
No error
Link status:
No error
Validation status:
No error
Under version 3.0.1, the output is:
Compiling:
No error
Compiling:
No error
Link status:
Link info
---------
error: Varying (named ) specified but not present in the program object.
Exception in thread "main" java.lang.IllegalStateException: Unable to link
at bugtest.BugTest.link(BugTest.java:143)
at bugtest.BugTest.compile(BugTest.java:109)
at bugtest.BugTest.main(BugTest.java:93)
Java Result: 1