unoplatform/uno · error · Exception

Program link failed: {infoLog}

Error message

Program link failed: {infoLog}

What it means

CreateProgram in MRTBlitGlCanvasElement links the MRT/MSAA/resolve sample's shaders and throws the info log on link failure. Because this sample renders to MRT and blits MSAA, link failures commonly come from MRT fragment-output declarations not matching the framebuffer's color attachment count or types.

Source

Thrown at src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/MRTBlitGlCanvasElement.cs:293

			gl.BindVertexArray(_quadVao);
			gl.DrawArrays(PrimitiveType.Triangles, 0, 6);
			gl.ActiveTexture(TextureUnit.Texture0);

			Invalidate();
		}

		private static uint CreateProgram(GL gl, string vertexSource, string fragmentSource)
		{
			var vs = CompileShader(gl, ShaderType.VertexShader, vertexSource);
			var fs = CompileShader(gl, ShaderType.FragmentShader, fragmentSource);
			var prog = gl.CreateProgram();
			gl.AttachShader(prog, vs);
			gl.AttachShader(prog, fs);
			gl.LinkProgram(prog);
			gl.GetProgram(prog, ProgramPropertyARB.LinkStatus, out int linkStatus);
			if (linkStatus != (int)GLEnum.True)
			{
				throw new Exception("Program link failed: " + gl.GetProgramInfoLog(prog));
			}
			gl.DetachShader(prog, vs);
			gl.DetachShader(prog, fs);
			gl.DeleteShader(vs);
			gl.DeleteShader(fs);
			return prog;
		}

		private static uint CompileShader(GL gl, ShaderType type, string source)
		{
			var sh = gl.CreateShader(type);
			gl.ShaderSource(sh, source);
			gl.CompileShader(sh);
			gl.GetShader(sh, ShaderParameterName.CompileStatus, out int status);
			if (status != (int)GLEnum.True)
			{
				throw new Exception($"{type} compile failed: " + gl.GetShaderInfoLog(sh));
			}

View on GitHub (pinned to 0418340488)

Solutions

  1. Read the info log for the unresolved output or varying.
  2. Declare exactly as many `layout(location=N) out` fragment outputs as the FBO has color attachments.
  3. Match vertex `out` / fragment `in` varyings exactly.
  4. Use #version 300 es / GL 330 for explicit MRT output locations.

Example fix

// before — one output, two-attachment MRT FBO
out vec4 fragColor;

// after — match both attachments
layout(location = 0) out vec4 fragColor0;
layout(location = 1) out vec4 fragColor1;
Defensive patterns

Strategy: validation

Validate before calling

// Confirm fragment output count matches MRT color attachment count
int outputCount = CountFragmentOutputs(fragmentSource);
if (outputCount < 2) throw new InvalidOperationException("MRT FBO has 2 color attachments; fragment shader must declare 2 outputs.");

Try / catch

try { return CreateProgram(gl, vert, frag); }
catch (Exception ex) { Log.Error($"MRT link failed: {ex.Message}"); throw; }

Prevention

When it happens

Trigger: Fragment shader declares one output but the FBO has two color attachments (or vice-versa); output location qualifiers collide; varying mismatch between stages; #version too low for MRT (gl_FragData vs location outputs); sampler/uniform mismatch.

Common situations: Refactor added a second MRT target but the fragment shader wasn't updated to two outputs; ES2 using gl_FragData where only one slot exists; location qualifier typo.

Related errors


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/5c2add03ea5520bc. Report an issue: GitHub.