Search Unity

Unity Shader Compiler? Offline? Run time? How does it take care of difference between each GPU?

Discussion in 'Shaders' started by bobozzz, Jul 18, 2018.

  1. bobozzz

    bobozzz

    Joined:
    May 27, 2015
    Posts:
    38
    Hi! Forgive me about asking a question that is so general :) I am a beginner to Unity and confused about how Unity compiler works.

    OpenGL compiles the sources at run time. The driver of each GPU can compile shader and generate binary code specifically for its hardware.

    My understanding about Unity is (Now sure if this is right): Unity has its own offline software compiler. On shader import time, Unity will do some minimal processing, and then generate either assembly code, or low-level optimized GLSL code. Then when you build the game, all the shaders will be fully compiled to binary code (not sure about this) based on the target platform you choose.
    (reference: https://docs.unity3d.com/Manual/class-Shader.html, Under Shader Compilation Details)

    Then how does Unity take care of the difference between each GPU hardware, for example, AMD and Nvidia card. Do all the hardware support pre-built binary shaders? It seems like D3D does and OpenGL doesn't.

    Thanks!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    For platforms that use HLSL, the shader code is directly compiled to the target (D3D11 or D3D12) and the resulting compiled shader are shipped with build.

    For pretty much all other platforms Unity uses a HLSL bytecode cross compiler:
    https://github.com/Unity-Technologies/HLSLcc

    For some platforms (ie: OpenGL in its many flavors) the resulting shader is GLSL text and compiled at load time, as per the OpenGL spec for shader handling. For most other platforms they cross compile or otherwise translate the HLSL code and recompile the shader for that platform. Note, that cross compiler takes compiled HLSL shaders as input, not HLSL code!

    They don't for the most part. They treat Intel, AMD and Nvidia the same in terms of the shaders they supply. Compilation target platform and the supported APIs are the only thing they really handle.

    However there's a big thing most people don't realize when they learn about the difference in shader handling between OpenGL and DirectX ... just because the shader is a binary file doesn't mean the GPU's drivers can't recompile or modify it when the game engine passes the shader to it. My comment about the fact HLSLcc takes compiled shaders was a hint at that. In fact, they do this quite often, especially for big AAA games. Many big games have hand optimized low level shaders built into the drivers such that when the game passes in the expected shader the GPU ends up using a completely different (but visually identical) one. This is why Nvidia drivers for the PC is several hundreds of megs, and why they release updates to the drivers to optimize specific games. They're not always fixing bugs, they're replacing and modifying that game's shader code at render time.
     
    Genebris, kokuzen and bobozzz like this.
  3. bobozzz

    bobozzz

    Joined:
    May 27, 2015
    Posts:
    38
    Thank you for your reply!!

    About this, what does the resulting compiled shader look like for HLSL? Is that the same as what you can see from clicking "Compile and show code" button in the shader inspector, a hardware-independent assembly code? Then during load time, driver will further process it, or like you said, replace it into gpu-specific code?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    They're in a DXBC file, though I believe they're looking to move to or have already moved to DXIL. The shader code you see when you use show code from Unity is most likely the text form of the assembly instructions those binaries store. Those are the output formats of Microsoft's official HLSL compilers, and is hardware agnostic. Those are then converted to GPU specific commands by drivers, though in the past I think some GPUs used them directly.
     
    bobozzz likes this.
  5. bobozzz

    bobozzz

    Joined:
    May 27, 2015
    Posts:
    38
    Thank you so much bgolus! So that's why Unity is not worried about GPU difference, because both OpenGL and DirectX shader code need drivers' final processing.