DAP SHADERS - COMPATIBILITY
===========================
What DAP runs on, and the honest answer about Vulkan.


THE SHORT VERSION
  DAP Shaders runs on OpenGL, because that is the only thing an Iris or OptiFine
  shaderpack can run on. It is written so that it also renders correctly when
  OpenGL is being translated onto Vulkan, which is how a growing number of people
  actually play - Linux, the Steam Deck, Apple Silicon.


"IS IT VULKAN COMPATIBLE?"
  There is no Vulkan shaderpack format for Minecraft Java Edition. This is worth
  spelling out because it is not obvious:

    * Iris and OptiFine are OpenGL renderers. They take GLSL, compile it with the
      OpenGL driver and draw with OpenGL. The shaderpack format IS an OpenGL
      format - DRAWBUFFERS, gl_FragData, the composite pass chain, all of it.

    * VulkanMod replaces Minecraft's renderer with a Vulkan one. It does not load
      Iris shaderpacks. No shaderpack works with it, DAP included, and that is a
      property of VulkanMod rather than of this pack.

    * So "make the shaderpack Vulkan compatible" has no direct implementation.
      There is nothing to target.

  What DOES exist, and is what this file is actually about, is OpenGL running ON
  TOP of Vulkan through a translation layer. That is real, common, and something a
  shaderpack absolutely can get right or wrong:

    Zink        Mesa's OpenGL-on-Vulkan driver. Linux, Steam Deck, Asahi Linux
                on Apple Silicon.
    ANGLE       Translates OpenGL to Vulkan, Direct3D or Metal.
    MoltenVK    Vulkan on Apple hardware, underneath translated OpenGL.

  On these stacks your GPU is running Vulkan. The shader is still written in GLSL
  against OpenGL, and the layer converts it. That conversion is much stricter than
  a native NVIDIA driver, which is where packs break.


WHY STRICTNESS IS THE WHOLE PROBLEM
  GLSL has a category called UNDEFINED BEHAVIOUR: operations where the spec
  declines to say what happens. The classic one is pow() with a negative base.

  NVIDIA's compiler returns something usable. Mesa, Apple and the translation
  layers are entitled to return NaN. One NaN entering a lighting calculation
  spreads through every later step and lands on screen as a black or white pixel
  that flickers as the camera moves.

  Nothing reports an error. The shader compiles. It looks perfect on the machine
  it was written on, and is broken for everyone on a different stack. Almost every
  "this shaderpack has weird artifacts on my AMD card" report is this.

  DAP is checked for that class of bug mechanically on every build. See
  tools/portability.py in the source tree. It currently reports zero findings.


WHAT WAS FIXED FOR THIS
  * Every tonemap operator clamps its input before pow(). Scene colour should
    never be negative, but sharpening, unsharp masks and reflections all subtract
    from it, and "should never" is not a guarantee.
  * The horizon glow used pow(1.0 - abs(dir.y), 6.0). Float error can leave
    abs(dir.y) a hair above 1.0, making the base negative - a NaN pixel sitting
    right on the horizon, on some drivers only.
  * normalize() of a zero-length vector divides by zero. Normals decoded from a
    buffer that is deliberately never cleared can be zero on the first frame, so
    decoding now uses a NaN-safe normalize.
  * The volumetric fog phase function could divide by zero at one end of its
    range.
  * sqrt() and the LabPBR normal reconstruction now clamp rather than relying on
    an `if` several lines away.
  * mc_Entity, mc_midTexCoord and at_tangent were declared with `attribute`, which
    was removed from GLSL in version 1.40 and only survives under a compatibility
    profile. A core-profile or translated path may reject it outright. They are
    `in` now, which every version since 1.30 accepts and which both Iris and
    OptiFine bind identically.
  * The bloom blur measured its radius in pixels and assumed Iris's buffer
    scaling. OptiFine ignores that extension, so the same code blurred correctly
    on one renderer and twice too wide on the other. The radius is now a fraction
    of the screen, which is correct on both, at any resolution - and is better
    behaviour anyway, since bloom should cover the same proportion of the image at
    1080p and at 4K.


WHAT WAS DELIBERATELY NOT CHANGED
  The pack uses `#version 330 compatibility`, gl_FragData and the DRAWBUFFERS
  comment. Those are deprecated OpenGL, and a purist would replace them with core
  profile and explicit `out` declarations.

  They stay, because they are the format Iris and OptiFine are specified to
  consume. OptiFine on 1.16 REQUIRES DRAWBUFFERS with gl_FragData; there is no
  alternative there. Iris performs its own transformation of exactly this syntax.
  Rewriting to core profile would not make the pack more portable - it would drop
  support for half the versions DAP ships for.

  Being deprecated is not the same as being unsupported, and picking the input
  format your loader documents is the portable choice, not the sloppy one.


SUPPORT MATRIX
  Renderer / driver              Status
  ----------------------------   ------------------------------------------------
  Iris (1.16 - 26.x)             Supported. The primary target.
  OptiFine (1.16 - 1.19)         Supported.
  NVIDIA, native OpenGL          Supported.
  AMD / Intel, native OpenGL     Supported.
  Mesa, native OpenGL            Supported.
  Zink (OpenGL on Vulkan)        Should work. Written for it, not verified in
                                 game - see the note below.
  ANGLE / MoltenVK               Same: written for it, not verified in game.
  VulkanMod                      Will not work. It loads no shaderpacks at all.
  Minecraft Bedrock              Not applicable. Different format entirely.
  Minecraft 1.15 and older       Not supported.


THE HONEST CAVEAT
  Everything above about the Vulkan-backed stacks is reasoning from the GLSL
  specification, not a screenshot. The changes remove constructs whose behaviour
  the spec leaves undefined, which is the right thing to do regardless of which
  driver you are on - but "written correctly for it" is not the same claim as
  "tested on it".

  If you run DAP under Zink, ANGLE or on Apple Silicon and something looks wrong,
  that is worth reporting, and the report is useful precisely because it covers a
  case that could not be checked here.


   - DAPTIME
