Search Unity

How to catch a GLSL error?

Discussion in 'General Graphics' started by Lex-DRL, Oct 15, 2020.

  1. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    140
    TL;DR:
    Sometimes, in some unexpected cases, for some unknown reasons, a "GLSL link error" is thrown into console. It happens in WebGL or android builds. It's not caught by a regular try-catch C# statements. Even with broad "catch (Exception e) {...}".
    Is there a way to catch or at least temporary suppress those errors from a script?

    In detail:
    I'm writing a small toolset that reliably detects shader features supported by the GPU. It does so by actually trying to render a small RT with a special shader which outputs a debug colors indicating whether the feature is supported or not.
    In the process, I use a built-in shader fallback system. Specifically, I add multiple subshaders, first of which has some "#pragma require" restriction and renders an "OK" color. And the second one is extremely simple and outputs "not OK" color. But sometimes, on some low-end devices (not just mobile ones but also outdated PCs) a GLSL error is thrown into console, even though there's that second subshader that should work on literally anything.
    So I'd like to know, how can I catch (from c# script) those graphics-API-level errors.

    Here's the error text:
    Code (csharp):
    1. GLES20: vprog textures are used, but not supported.
    2. -------- GLSL link error: No compiled vertex shader when at least one graphics shader is attached.
    It appears very rarely in WebGL. So far - only a couple of users (of a few thousands) got it. But they do.

    And here's the shader.
    It doesn't do anything fancy - just forces a texture to be read at vertex stage.
    If GPU can do that, the 1st subshader should render a green(ish) color.
    Otherwise, the 2nd subshader renders a red color.

    Code (CSharp):
    1.  
    2. Shader "y-Debug/Hardware Test/TexLod-Vert" {
    3.    Properties {
    4.        [Header(CHANGE THE SHADER IF YOU SEE THIS TEXT)]
    5.        [Header(it should only be used from script)]
    6.        [Space(40)]
    7.    
    8.        _MainTex ("Main Texture", 2D) = "white" {} // not used, declared just to make Blit happy
    9.        _TestTex ("Test Texture", 2D) = "white" {} // should be passed as black texture
    10.    
    11.        [Space] [Header(Shader Blending)]
    12.        [Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Int) = 0
    13.        [Enum(None,0,Alpha,1,RGB,14,RGBA,15)] _ColorMask ("out Color Mask", Float) = 15
    14.        [Enum(Off, 0, On, 1)] _zWrite ("Z-Write", Int) = 0
    15.        [Enum(UnityEngine.Rendering.CompareFunction)] _zTest ("Z-Test", Int) = 8 // Always
    16.    }
    17.  
    18.    CGINCLUDE
    19.        #pragma vertex vert
    20.        #pragma fragment frag
    21.    
    22.        #include "UnityCG.cginc"
    23.    
    24.        #define DRL_YES_COLOR fixed4(0.3, 0.7, 0.2, 1.0)
    25.        #define DRL_NO_COLOR fixed4(0.9, 0.25, 0.2, 1.0)
    26.    
    27.        struct appdata {
    28.            float3 vertex : POSITION;
    29.            half2 tex0 : TEXCOORD0;
    30.        };
    31.    
    32.        struct v2f {
    33.            float4 pos : SV_POSITION;
    34.            fixed4 vColor : COLOR;
    35.            half2 mainUVs : TEXCOORD0;
    36.        };
    37.    
    38.        sampler2D _TestTex;
    39.    
    40.        fixed4 frag (v2f i) : SV_Target
    41.        {
    42.            fixed4 clr = tex2D(_TestTex, i.mainUVs); // should be black, effectively keeping only vertex color
    43.            return saturate(i.vColor + clr);
    44.        }
    45.    ENDCG
    46.  
    47.    Category {
    48.        Tags {
    49.            "PreviewType"="Plane"
    50.            "RenderType"="Opaque"
    51.            "IgnoreProjector"="True"
    52.            "ForceNoShadowCasting"="True"
    53.        }
    54.    
    55.        ColorMask [_ColorMask]
    56.        Cull [_Cull]
    57.        ZTest [_zTest]
    58.        ZWrite [_zWrite]
    59.        Lighting Off
    60.    
    61.        SubShader { Pass {
    62.            CGPROGRAM
    63.                // with support
    64.                #pragma require samplelod
    65.            
    66.                v2f vert (appdata v)
    67.                {
    68.                    float3 vtx = v.vertex;
    69.                    half3 clr = tex2Dlod(_TestTex, half4(v.tex0, 0.0h, 0.0h));
    70.                    vtx.xy += (v.tex0 * 2.0h - 1.0h) * clr.rg; // expand quad verts outside
    71.                
    72.                    v2f o;
    73.                    o.pos = UnityObjectToClipPos(vtx);
    74.                    o.vColor = DRL_YES_COLOR;
    75.                    o.mainUVs = v.tex0;
    76.                    return o;
    77.                }
    78.            ENDCG
    79.        } }
    80.        SubShader { Pass {
    81.            CGPROGRAM
    82.                // no support
    83.            
    84.                v2f vert (appdata v)
    85.                {
    86.                    v2f o;
    87.                    o.pos = UnityObjectToClipPos(v.vertex);
    88.                    o.vColor = DRL_NO_COLOR;
    89.                    o.mainUVs = v.tex0;
    90.                    return o;
    91.                }
    92.            ENDCG
    93.        } }
    94.    }
    95.  
    96.    FallBack Off
    97.  
    98. }
    99.  
     
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,028
    Hi!
    The error just says that the device you're running on doesn't support reading textures in vertex shaders.
    #pragma require samplelod
    is the capability for fragment shaders to sample textures with explicit LOD - it has nothing to do with vertex texture fetch support.
    OpenGL ES 2 spec is a bit funky here - it requires 0 vertex texture units to be present. It's part of the specification, but not required.

    I suggest to file a bug report - this should be handled better (the first error comes from our code).
     
  3. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    140
    @aleksandrk
    Submitted a bug report today. Hope it helps.
     
    aleksandrk likes this.
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,028
    Thank you!
     
  5. HMJBruce

    HMJBruce

    Joined:
    Jul 19, 2019
    Posts:
    4
    Hi, i came to the similar situation, my problem is that even if my device support reading textures in vertex shaders, the error
    GLES20: vprog textures are used, but not supported
    is still there. I've tested by manually creating, compiling raw glsl shader into my device, everything goes fine. But if i use shaderlab to write a vert function that contains
    tex2dlod
    , the error occurs, even if i returned from the beginning of all the _gl* like functions in the webgl.framework.js. So i wonder if i can bypass the process in webgl.wasm that trigger the 'vprog' error, so that my shader can work?
     
  6. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,028
    Hi!
    Please submit a bug report. It sounds like the driver reports the capabilities incorrectly.
     
  7. HMJBruce

    HMJBruce

    Joined:
    Jul 19, 2019
    Posts:
    4
    Thanks for you reply! What capability does vprog texture required? I think i can just return the capability is supported, and the error will be gone?
     
  8. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,028
    We ask the driver for the capability internally, it's not something that should be touched, even if you're willing to modify the JS code.
     
  9. HMJBruce

    HMJBruce

    Joined:
    Jul 19, 2019
    Posts:
    4
    We have our own browser-like runtime in c++. May i ask what the capability exactly is, so that we can modify our c++ code to support it?
     
  10. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,028
    It's
    GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
     
  11. HMJBruce

    HMJBruce

    Joined:
    Jul 19, 2019
    Posts:
    4
    Wow!Problem solved, thx a lot!
     
    aleksandrk likes this.