unoplatform/uno · error · Exception

Vertex shader failed to compile: {infoLog}

Error message

Vertex shader failed to compile: {infoLog}

What it means

Thrown by the SimpleTriangle OpenGL sample after the GL driver reports a vertex-shader compile failure. The code calls gl.CompileShader then gl.GetShader(CompileStatus); a status other than GLEnum.True triggers the throw, appending the driver's info log. It indicates the GLSL source the sample generated is syntactically or semantically invalid for the active GL/GLES context.

Source

Thrown at src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/SimpleTriangleGlCanvasElement.cs:79

			precision highp float; // for OpenGL ES compatibility

			out vec4 out_color;
			in vec4 vertexColor;

			void main()
			{
				out_color = vertexColor;
			}
			""";

			uint vertexShader = gl.CreateShader(ShaderType.VertexShader);
			gl.ShaderSource(vertexShader, vertexCode);
			gl.CompileShader(vertexShader);

			gl.GetShader(vertexShader, ShaderParameterName.CompileStatus, out int vStatus);
			if (vStatus != (int)GLEnum.True)
			{
				throw new Exception("Vertex shader failed to compile: " + gl.GetShaderInfoLog(vertexShader));
			}

			uint fragmentShader = gl.CreateShader(ShaderType.FragmentShader);
			gl.ShaderSource(fragmentShader, fragmentCode);
			gl.CompileShader(fragmentShader);

			gl.GetShader(fragmentShader, ShaderParameterName.CompileStatus, out int fStatus);
			if (fStatus != (int)GLEnum.True)
			{
				throw new Exception("Fragment shader failed to compile: " + gl.GetShaderInfoLog(fragmentShader));
			}

			_program = gl.CreateProgram();
			gl.AttachShader(_program, vertexShader);
			gl.AttachShader(_program, fragmentShader);
			gl.LinkProgram(_program);

			gl.GetProgram(_program, ProgramPropertyARB.LinkStatus, out int lStatus);

View on GitHub (pinned to 0418340488)

Solutions

  1. Read the full message: the appended info log names the exact GLSL line and error (e.g. 'ERROR: 0:1: '' : #version must be the first non-whitespace'). Fix the shader line it points at.
  2. Verify the active context version (gl.GetStringS(StringName.Version) and StringName.ShadingLanguageVersion) and confirm versionDef matched it; flip '#version 300 es' to '#version 330' or vice versa if the branch mis-detected ES.
  3. If the driver lacks highp, change 'precision highp float;' to 'precision mediump float;' or move the precision statement only where the stage requires it.
  4. If 'layout (location=0)' is rejected, the context is pre-GLSL-1.30/GLES-1.00; ensure a 3.x core / GLES 3.0 context is created (Skia GL host configuration).
  5. On headless/remote Linux, force a real GL context via LIBGL_ALWAYS_SOFTWARE=1 or a supported GPU passthrough so the driver reports a usable shading-language version.

Example fix

// before (versionDef branch may mis-detect ES)
var versionDef = slVersion.Contains("OpenGL ES", StringComparison.InvariantCultureIgnoreCase)
    ? "#version 300 es"
    : "#version 330";
// after - log the detected versions so a mismatch is visible, and require GLES3 / GL3.3
_log.Debug($"GL={gl.GetStringS(StringName.Version)} GLSL={slVersion}");
if (!slVersion.StartsWith("3.30") && !slVersion.Contains("OpenGL ES 3"))
{
    throw new NotSupportedException($"This sample needs GLSL 3.30 or GLES 3.00, got {slVersion}");
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the GLSL version directive matches the context before compiling
var glVer = gl.GetStringS(StringName.Version);
var slVer = gl.GetStringS(StringName.ShadingLanguageVersion);
bool isES = slVer.Contains("OpenGL ES", StringComparison.InvariantCultureIgnoreCase);
if (isES && !slVer.Contains("3.")) throw new NotSupportedException($"Need GLES 3.00 shading language, got {slVer}");
if (!isES && !slVer.StartsWith("3.30")) throw new NotSupportedException($"Need GLSL 3.30, got {slVer}");

Try / catch

try { gl.CompileShader(vertexShader); }
catch (Exception ex) when (ex.Message.Contains("Vertex shader failed to compile"))
{
    _log.Error($"GLSL compile failed (version={slVersion}): {ex.Message}");
    // fall back to a known-good minimal shader or disable the sample
}

Prevention

When it happens

Trigger: Calling GLCanvasElement_SimpleTriangleElement.Init on a platform whose GL driver rejects the generated vertex shader. This happens specifically when the chosen versionDef ('#version 300 es' for OpenGL ES, '#version 330' otherwise) is wrong for the context, or when the 'precision highp float' line / 'layout (location=0)' qualifier is unsupported by the driver.

Common situations: Running the Skia GL sample on a machine whose GL context is actually desktop GL but reports an ES shading-language version (or vice versa); running on a VM/remote GPU with a limited GLSL ES profile; a driver that lacks highp in the fragment stage; GL context creation returning an unexpected version string so the versionDef branch picks the wrong directive.

Related errors


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