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
- 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.
- 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.
- If the driver lacks highp, change 'precision highp float;' to 'precision mediump float;' or move the precision statement only where the stage requires it.
- 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).
- 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
- Log the active GL + shading-language version at Init so version mismatch is visible before the throw.
- Keep the version directive selection in one place and assert the branch taken.
- On CI, run GL samples under a documented context (software rasterizer or known GPU).
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
- Fragment shader failed to compile: {infoLog}
- Program link failed: {infoLog}
- {type} compile failed: {infoLog}
- Program link failed: {infoLog}
- {type} compile failed: {infoLog}
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/2dcfa5a47774ab1b.
Report an issue: GitHub.