Search Unity

GLSL Compiling for Android?

Discussion in 'Shaders' started by tenderclawsJK, Jul 3, 2019.

  1. tenderclawsJK


    Jan 12, 2019
    How exactly does shader compiling for Android platform work? Does Unity translate HLSL/CG code to GLSL, which then gets compiled on the device itself?

    Either way, I'm not really understanding why the "compiled" GLSL code looks the way it does. For example, this line in CG:
    o.vertex.x *= sign(_FloatParam);

    Gets translated to:
    u_xlati0 = int((0.0 < _FloatParam) ? -1 : 0);
    u_xlati3 = int((_FloatParam < 0.0) ? -1 : 0);
    u_xlati0 = (-u_xlati0) + u_xlati3;
    u_xlat0 = float(u_xlati0);
    gl_Position.x = u_xlat0 * u_xlat1.x;

    While I understand that there is an attempt at optimization going on here, wouldn't it be best to leave it up to the device to determine which instructions it will compile the sign intrinsic (which is also valid in GLSL) to? Why not just translate it to
    gl_Position.x = sign(_FloatParam) * u_xlat1.x;

    Is there a limited subset of GLSL that Android shader compiler is able to understand? Is this a precautionary measure to ensure that every Android GPU will be able to handle a limited subset of GLSL? Or am I just totally off base with my understanding of what's going on?
    Last edited: Jul 3, 2019
  2. aleksandrk


    Unity Technologies

    Jul 3, 2017
    It's... complicated for historical reasons :)
    Right now (for OpenGL ES anyway), HLSL gets compiled using the DX compiler (which optimizes things) and then the bytecode output is translated to GLSL using HLSLcc. With this setup there's no way to preserve the original "sign", as it gets expanded into what you see in your second code snippet.
    Also, different GPUs have different GLSL compilers, and some of those have bugs. The emitted code tries to work around those bugs, and produces the code that will work everywhere.
    tenderclawsJK likes this.