// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \page qtshadertools-overview.html
    \title Qt Shader Tools Overview
    \brief Provides insight into the Qt Shader Tools module.
    \ingroup explanation

    The Qt Shader Tools module builds on the SPIR-V Open Source Ecosystem as
    described at \l{https://www.khronos.org/spir/}{the Khronos SPIR-V web site}.
    For compiling into SPIR-V,
    \l{https://github.com/KhronosGroup/glslang}{glslang} is used, while
    translating and reflecting is done via
    \l{https://github.com/KhronosGroup/SPIRV-Cross}{SPIRV-Cross}.

    For shader code to be written once in Qt applications and libraries, all
    shaders are expected to be written in a single language, which is then
    compiled into SPIR-V. This shading language is Vulkan-compatible GLSL at the
    moment. This is different from what the OpenGL-style GLSL Qt 5.x expects.
    See the
    \l{https://github.com/KhronosGroup/GLSL/blob/master/extensions/khr/GL_KHR_vulkan_glsl.txt}
    {GL_KHR_vulkan_glslspecification} for an overview of the differences.

    Source code for other shading languages, such as GLSL, HLSL, and the Metal
    Shading Language, is then generated from translating the SPIR-V bytecode,
    together with reflection information (inputs, outputs, shader resources).
    For GLSL in particular, this also involves generating multiple variants,
    meaning source code suitable for different GLSL versions, such as GLSL ES
    100, GLSL ES 300, and GLSL 120 and 150. This is then packed into
    serializable QShader container objects, typically stored on disk as \c{.qsb}
    files. The Qt Rendering Hardware Interface consumes QShader instances
    directly, picking the shader source or bytecode that is best suited for the
    graphics API used at run time. A QShader object is typically deserialized
    from \c{.qsb} files shipped with the application or Qt itself in the Qt
    Resource System.

    Some platforms provide the option of compiling shader source code to an
    intermediate format similar to SPIR-V. This involves running
    platform-specific tools. With Direct 3D, the \c qsb tool provides the option
    to invoke
    \l{https://docs.microsoft.com/en-us/windows/win32/direct3dtools/fxc}{the fxc
    tool from the Windows SDK} once the HLSL source code has been generated. It
    then replaces the HLSL source code with the \c DXBC binary generated by \c
    fxc. This can have a positive effect on applications' runtime performance
    since they no longer need to do the first phase of compilation (HLSL source
    to DXBC) themselves. For macOS and iOS, the
    \l{https://developer.apple.com/documentation/metal/libraries/building_a_library_with_metal_s_command-line_tools?language=objc}{XCode
    SDK provides similar tools}. The downside of this approach is that running
    these tools is only possible on their respective platforms. Therefore, this
    is best suited for use in combination with qsb's CMake integration since
    doing shader conditioning at application build time implicitly comes with
    the knowledge needed about the target platform and what platform-specific
    tools can be invoked.

    The following diagram describes the steps that happen during an invocation
    of the \c qsb tool:

    \image shaderconditioning.png

    The main components of the Qt shader conditioning system are:

    \list
    \li the \c qsb command-line tool
    \li CMake integration for the \c qsb tool
    \li QShader (part of the QtGui module)
    \li QShaderBaker (part of this module, the library equivalent of the \c qsb
    tool)
    \endlist

    \section1 Typical Usage with Qt Quick

    Application developers typically work with custom shader code in Qt Quick
    scenes that have one of the following:

    \list
        \li \l ShaderEffect items
        \li \l QQuickItem subclasses that use scene graph nodes in combination
        with custom materials built by subclassing \l QSGMaterial.
    \endlist

    For example, consider the following QML snippet:

    \qml
    ShaderEffect {
        width: 100; height: 100
        fragmentShader: "myeffect.frag.qsb"
    }
    \endqml

    Here the \l{ShaderEffect::fragmentShader}{fragmentShader} URL refers to a
    \c{.qsb} file relative to the \c{.qml} file's location. The application is
    expected to ship \c{myeffect.frag.qsb} next to the \c{.qml} file. To generate
    that file from the Vulkan-style GLSL source (which itself does not need to be
    shipped with the application), the application must use the \c qsb tool either
    directly or via CMake.

    \section1 Typical Usage with Qt Quick 3D

    Qt Quick 3D uses the Shader Tools module directly to perform shader conditioning
    at run time. In addition, it provides solutions for pre-generating shaders for
    materials at build time, in case a runtime dependency to shader compilers and
    other tools is not seen ideal. In either case, developers don't need to work
    directly with the \c qsb tool since it's encapsulated by the Qt Quick 3D's own
    framework and tools.

*/
