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

/*!
    \example hellovulkantriangle
    \meta installpath vulkan
    \ingroup examples-vulkan
    \title Hello Vulkan Triangle Example
    \brief Shows the basics of rendering with QVulkanWindow and the Vulkan API.
    \examplecategory {Graphics & Multimedia}

    The \e{Hello Vulkan Triangle Example} creates a full graphics pipeline,
    including a vertex and fragment shader, to render a triangle.

    \image hellovulkantriangle.png

    \section1 Startup

    Each Qt application using Vulkan will have to have a \c{Vulkan instance}
    which encapsulates application-level state and initializes a Vulkan library.

    A QVulkanWindow must always be associated with a QVulkanInstance and hence
    the example performs instance creation before the window. The
    QVulkanInstance object must also outlive the window.

    \snippet hellovulkantriangle/main.cpp 0

    The example enables validation layers, when supported. When the requested
    layers are not present, the request will be ignored. Additional layers and
    extensions can be enabled in a similar manner.

    \snippet hellovulkantriangle/main.cpp 1

    Once the instance is ready, it is time to create a window. Note that \c w
    lives on the stack and is declared after \c inst.

    \section1 The QVulkanWindow Subclass

    To add custom functionality to a QVulkanWindow, subclassing is used. This
    follows the existing patterns from QOpenGLWindow and QOpenGLWidget.
    However, QVulkanWindow utilizes a separate QVulkanWindowRenderer object.

    The QVulkanWindow subclass reimplements the factory function
    QVulkanWindow::createRenderer(). This simply returns a new instance of the
    QVulkanWindowRenderer subclass. In order to be able to access various
    Vulkan resources via the window object, a pointer to the window is passed
    and stored via the constructor.

    \snippet hellovulkantriangle/main.cpp 2

    \section1 The Actual Rendering

    QVulkanWindow subclasses queue their draw calls in their reimplementation
    of QVulkanWindowRenderer::startNextFrame(). Once done, they are required to
    call back QVulkanWindow::frameReady(). The example has no asynchronous
    command generation, so the frameReady() call is made directly from
    startNextFrame(). To get continuous updates, the example simply invokes
    QWindow::requestUpdate() in order to schedule a repaint.

    The example also demonstrates multisample antialiasing. Based on the
    supported sample counts reported by QVulkanWindow::supportedSampleCounts()
    the example chooses between 8x, 4x, or no multisampling. Once configured
    via QVulkanWindow::setSamples(), QVulkanWindow takes care of the rest: the
    additional multisample color buffers are created automatically, and
    resolving into the swapchain buffers is performed at the end of the default
    render pass for each frame.

    \include examples-run.qdocinc
*/
