Compiler Behavior Notes

From shaderLABS

Windows

nVidia compiler

  • includes before the #version argument are not supported
    • The GLSL spec says that #version must be the first non-whitespace line in your code
  • equal conditions using floats may not work as intended
    • eg. if (a == 1.0)
    • Comparing floats this way is considered bad practice since there's multiple ways to represent a lot of numbers, meaning that they might have different values. A more reliable way is to either convert them to ints first or do something like if(abs(a - 1.0) < 0.0001)
  • constant arguments of functions get compiled as actual constants and can be used in constant expressions
    • e.g. void blah(const int a, const float b)
  • mix() is not supported in constant expressions on GeForce 500 and older
    • can be manually implemented like this #define cmix(x, y, a) (y*a + x*(1.0-a))
  • GL Extensions have to be explicitly enabled (eg. GL_ARB_shader_texture_lod )
  • GL Extension #extension GL_EXT_gpu_shader4 : enable is required for specific operations, even on GL300 and newer when using function calls with the 2D or 3D suffix (eg. texelFetch2D() )
  • NaNs may occur when not clamping the framebuffer used for the main scene color, especially on blacks
    • doing a clamp with a minimum of 1.0/k on said buffer fixes the issue, with k being the maximum amount of discreete values supported by the current buffer precision (eg. 255.0 on 8bit and 65535.0 on 16bit)
  • normalizing a vector where all components are zero results in NaN's
  • implicit casts from (u)int to float may fail to compile

AMD compiler

  • constants using built-in functions are not supported
    • e.g. const float f = const_func()
    • can be manually implemented as macro
      • e.g. #define add(x, y) (x+y) instead of float add(float x, float y) {return x + y;}
  • same might apply to constants made of other constants
  • sampling textures outside of void main() causes sampling of a wrong texture
    • sampling inside a function works fine as long as it doesn't get used outside of void main() or other functions
  • reserved words buffer, input and half
    • input is reserved for future use as part of specification
    • half is reserved as part of specification
  • allows using gl_MultiTexcoord without the compatibility profile when using GLSL > 130
    • gl_MultiTexCoord was deprecated in GLSL 130 and removed from the core profile in 140, so it shouldn't be possible to use in a core profile of 140 or later
  • some GL Extensions will be enabled automatically when used without explicitly being enabled (eg. GL_ARB_shader_texture_lod )
  • the usage of geometry shaders on terrain requires external triangulation for quad-geometry
  • using shadow mipmaps with a shadowmap resolution that is not 2^n can cause a crash on loading
  • function type casting from float to a vector type is apparently supported

Intel compiler

  • reserved word half
    • half is reserved as part of specification
  • only supports up to seven framebuffer attachments
    • GLSL specification only guarantees seven but allows more
    • GLSL 300 and newer guarantee eight framebuffer attachments
  • recursive macros are not allowed, eg. #define smoothstep(x, low, high) smoothstep(low, high, x)
  • extensions have to be declared directly after the #version directive
  • constants using built-in functions may fail to compile
    • e.g. const float f = const_func()
    • can be manually implemented as macro
      • e.g. #define add(x, y) (x+y) instead of float add(float x, float y) {return x + y;}
  • constants using struct inputs are not supported

macOS

  • Leave it alone. Just don't even bother.

Linux

AMD (Mesa)

  • only GLSL 110, 120, 130, 100 es, 300 es, 310 es, and 320 es are supported (possibly only affects APUs, update on this?)
    • on Polaris/Vega based cards GL 430 compatibility is available
  • EXT_gpu_shader_4 is not supported
    • certain features can be achieved with different extensions
  • if an image has LOD's enabled but gets overwritten in the next pass the LODs from the previous pass are still bound
    • this can lead to wrong information being read unless the LOD to be read from is explicitly declared (textureLod())

nVidia (proprietary)

  • same as on windows

nVidia (open source)

  • not compatible