Quick answer: SPIR-V Cross output with different attribute layouts between vertex and fragment? Translator infers locations from order, which can differ - declare explicit locations in source.

GLSL vertex shader and fragment shader both declare 'in vec2 uv'. Crossed output puts them at different locations; link fails.

Explicit layout(location=N)

layout(location = 0) in vec2 uv;

Pin the location. Translator emits consistently; link succeeds.

Or use a shared header

#include a layout-defining header in both stages. Single source of truth.

Validate with linker

Run the linker (glslang -V, or platform-specific). Mismatched locations are caught before runtime.

“Implicit attribute locations are translator-dependent. Explicit is portable.”

Make explicit locations a project style rule. The cost is one keyword per attribute; the saved debugging time is significant.

Related reading