/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Gui module
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qrhigles2_p_p.h"
#include <QWindow>
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QtGui/private/qopenglextensions_p.h>
#include <QtGui/private/qopenglprogrambinarycache_p.h>
#include <qmath.h>

QT_BEGIN_NAMESPACE

/*
  OpenGL backend. Binding vertex attribute locations and decomposing uniform
  buffers into uniforms are handled transparently to the application via the
  reflection data (QShaderDescription). Real uniform buffers are never used,
  regardless of the GLSL version. Textures and buffers feature no special
  logic, it's all just glTexSubImage2D and glBufferSubData (with "dynamic"
  buffers set to GL_DYNAMIC_DRAW). The swapchain and the associated
  renderbuffer for depth-stencil will be dummies since we have no control over
  the underlying buffers here. While the baseline here is plain GLES 2.0, some
  modern GL(ES) features like multisample renderbuffers, blits, and compute are
  used when available. Also functional with core profile contexts.
*/

/*!
    \class QRhiGles2InitParams
    \internal
    \inmodule QtGui
    \brief OpenGL specific initialization parameters.

    An OpenGL-based QRhi needs an already created QOffscreenSurface at minimum.
    Additionally, while optional, it is recommended that the QWindow the first
    QRhiSwapChain will target is passed in as well.

    \badcode
        QOffscreenSurface *fallbackSurface = QRhiGles2InitParams::newFallbackSurface();
        QRhiGles2InitParams params;
        params.fallbackSurface = fallbackSurface;
        params.window = window;
        rhi = QRhi::create(QRhi::OpenGLES2, &params);
    \endcode

    By default QRhi creates a QOpenGLContext on its own. This approach works
    well in most cases, included threaded scenarios, where there is a dedicated
    QRhi for each rendering thread. As there will be a QOpenGLContext for each
    QRhi, the OpenGL context requirements (a context can only be current on one
    thread) are satisfied. The implicitly created context is destroyed
    automatically together with the QRhi.

    The QSurfaceFormat for the context is specified in \l format. The
    constructor sets this to QSurfaceFormat::defaultFormat() so applications
    that use QSurfaceFormat::setDefaultFormat() do not need to set the format
    again.

    \note The depth and stencil buffer sizes are set automatically to 24 and 8
    when no size was explicitly set for these buffers in \l format. As there
    are possible adjustments to \l format, applications can use
    adjustedFormat() to query the effective format that is passed to
    QOpenGLContext::setFormat() internally.

    A QOffscreenSurface has to be specified in \l fallbackSurface. In order to
    prevent mistakes in threaded situations, this is never created
    automatically by the QRhi since, like QWindow, QOffscreenSurface can only
    be created on the gui/main thread.

    As a convenience, applications can use newFallbackSurface() which creates
    and returns a QOffscreenSurface that is compatible with the QOpenGLContext
    that is going to be created by the QRhi afterwards. Note that the ownership
    of the returned QOffscreenSurface is transferred to the caller and the QRhi
    will not destroy it.

    \note QRhiSwapChain can only target QWindow instances that have their
    surface type set to QSurface::OpenGLSurface.

    \note \l window is optional. It is recommended to specify it whenever
    possible, in order to avoid problems on multi-adapter and multi-screen
    systems. When \l window is not set, the very first
    QOpenGLContext::makeCurrent() happens with \l fallbackSurface which may be
    an invisible window on some platforms (for example, Windows) and that may
    trigger unexpected problems in some cases.

    \section2 Working with existing OpenGL contexts

    When interoperating with another graphics engine, it may be necessary to
    get a QRhi instance that uses the same OpenGL context. This can be achieved
    by passing a pointer to a QRhiGles2NativeHandles to QRhi::create(). The
    \l{QRhiGles2NativeHandles::context}{context} must be set to a non-null
    value.

    An alternative approach is to create a QOpenGLContext that
    \l{QOpenGLContext::setShareContext()}{shares resources} with the other
    engine's context and passing in that context via QRhiGles2NativeHandles.

    The QRhi does not take ownership of the QOpenGLContext passed in via
    QRhiGles2NativeHandles.
 */

/*!
    \class QRhiGles2NativeHandles
    \internal
    \inmodule QtGui
    \brief Holds the OpenGL context used by the QRhi.
 */

/*!
    \class QRhiGles2TextureNativeHandles
    \internal
    \inmodule QtGui
    \brief Holds the OpenGL texture object that is backing a QRhiTexture instance.
 */

#ifndef GL_BGRA
#define GL_BGRA                           0x80E1
#endif

#ifndef GL_R8
#define GL_R8                             0x8229
#endif

#ifndef GL_R16
#define GL_R16                            0x822A
#endif

#ifndef GL_RED
#define GL_RED                            0x1903
#endif

#ifndef GL_RGBA8
#define GL_RGBA8                          0x8058
#endif

#ifndef GL_RGBA32F
#define GL_RGBA32F                        0x8814
#endif

#ifndef GL_RGBA16F
#define GL_RGBA16F                        0x881A
#endif

#ifndef GL_HALF_FLOAT
#define GL_HALF_FLOAT                     0x140B
#endif

#ifndef GL_DEPTH_COMPONENT16
#define GL_DEPTH_COMPONENT16              0x81A5
#endif

#ifndef GL_DEPTH_COMPONENT24
#define GL_DEPTH_COMPONENT24              0x81A6
#endif

#ifndef GL_DEPTH_COMPONENT32F
#define GL_DEPTH_COMPONENT32F             0x8CAC
#endif

#ifndef GL_STENCIL_INDEX
#define GL_STENCIL_INDEX                  0x1901
#endif

#ifndef GL_STENCIL_INDEX8
#define GL_STENCIL_INDEX8                 0x8D48
#endif

#ifndef GL_DEPTH24_STENCIL8
#define GL_DEPTH24_STENCIL8               0x88F0
#endif

#ifndef GL_DEPTH_STENCIL_ATTACHMENT
#define GL_DEPTH_STENCIL_ATTACHMENT       0x821A
#endif

#ifndef GL_DEPTH_STENCIL
#define GL_DEPTH_STENCIL                  0x84F9
#endif

#ifndef GL_PRIMITIVE_RESTART_FIXED_INDEX
#define GL_PRIMITIVE_RESTART_FIXED_INDEX  0x8D69
#endif

#ifndef GL_FRAMEBUFFER_SRGB
#define GL_FRAMEBUFFER_SRGB 0x8DB9
#endif

#ifndef GL_READ_FRAMEBUFFER
#define GL_READ_FRAMEBUFFER               0x8CA8
#endif

#ifndef GL_DRAW_FRAMEBUFFER
#define GL_DRAW_FRAMEBUFFER               0x8CA9
#endif

#ifndef GL_MAX_DRAW_BUFFERS
#define GL_MAX_DRAW_BUFFERS               0x8824
#endif

#ifndef GL_TEXTURE_COMPARE_MODE
#define GL_TEXTURE_COMPARE_MODE           0x884C
#endif

#ifndef GL_COMPARE_REF_TO_TEXTURE
#define GL_COMPARE_REF_TO_TEXTURE         0x884E
#endif

#ifndef GL_TEXTURE_COMPARE_FUNC
#define GL_TEXTURE_COMPARE_FUNC           0x884D
#endif

#ifndef GL_MAX_SAMPLES
#define GL_MAX_SAMPLES                    0x8D57
#endif

#ifndef GL_SHADER_STORAGE_BUFFER
#define GL_SHADER_STORAGE_BUFFER          0x90D2
#endif

#ifndef GL_READ_ONLY
#define GL_READ_ONLY                      0x88B8
#endif

#ifndef GL_WRITE_ONLY
#define GL_WRITE_ONLY                     0x88B9
#endif

#ifndef GL_READ_WRITE
#define GL_READ_WRITE                     0x88BA
#endif

#ifndef GL_COMPUTE_SHADER
#define GL_COMPUTE_SHADER                 0x91B9
#endif

#ifndef GL_ALL_BARRIER_BITS
#define GL_ALL_BARRIER_BITS               0xFFFFFFFF
#endif

#ifndef GL_VERTEX_PROGRAM_POINT_SIZE
#define GL_VERTEX_PROGRAM_POINT_SIZE      0x8642
#endif

#ifndef GL_POINT_SPRITE
#define GL_POINT_SPRITE                   0x8861
#endif

#ifndef GL_MAP_READ_BIT
#define GL_MAP_READ_BIT                   0x0001
#endif

Q_DECLARE_LOGGING_CATEGORY(lcOpenGLProgramDiskCache)

/*!
    Constructs a new QRhiGles2InitParams.

    \l format is set to QSurfaceFormat::defaultFormat().
 */
QRhiGles2InitParams::QRhiGles2InitParams()
{
    format = QSurfaceFormat::defaultFormat();
}

/*!
    \return the QSurfaceFormat that will be set on the QOpenGLContext before
    calling QOpenGLContext::create(). This format is based on \a format, but
    may be adjusted. Applicable only when QRhi creates the context.
    Applications are advised to set this format on their QWindow in order to
    avoid potential BAD_MATCH failures.
 */
QSurfaceFormat QRhiGles2InitParams::adjustedFormat(const QSurfaceFormat &format)
{
    QSurfaceFormat fmt = format;

    if (fmt.depthBufferSize() == -1)
        fmt.setDepthBufferSize(24);
    if (fmt.stencilBufferSize() == -1)
        fmt.setStencilBufferSize(8);

    return fmt;
}

/*!
    \return a new QOffscreenSurface that can be used with a QRhi by passing it
    via a QRhiGles2InitParams.

    \a format is adjusted as appropriate in order to avoid having problems
    afterwards due to an incompatible context and surface.

    \note This function must only be called on the gui/main thread.

    \note It is the application's responsibility to destroy the returned
    QOffscreenSurface on the gui/main thread once the associated QRhi has been
    destroyed. The QRhi will not destroy the QOffscreenSurface.
 */
QOffscreenSurface *QRhiGles2InitParams::newFallbackSurface(const QSurfaceFormat &format)
{
    QSurfaceFormat fmt = adjustedFormat(format);

    // To resolve all fields in the format as much as possible, create a context.
    // This may be heavy, but allows avoiding BAD_MATCH on some systems.
    QOpenGLContext tempContext;
    tempContext.setFormat(fmt);
    if (tempContext.create())
        fmt = tempContext.format();
    else
        qWarning("QRhiGles2: Failed to create temporary context");

    QOffscreenSurface *s = new QOffscreenSurface;
    s->setFormat(fmt);
    s->create();

    return s;
}

QRhiGles2::QRhiGles2(QRhiGles2InitParams *params, QRhiGles2NativeHandles *importDevice)
    : ofr(this)
{
    requestedFormat = QRhiGles2InitParams::adjustedFormat(params->format);
    fallbackSurface = params->fallbackSurface;
    maybeWindow = params->window; // may be null

    importedContext = importDevice != nullptr;
    if (importedContext) {
        ctx = importDevice->context;
        if (!ctx) {
            qWarning("No OpenGL context given, cannot import");
            importedContext = false;
        }
    }
}

bool QRhiGles2::ensureContext(QSurface *surface) const
{
    bool nativeWindowGone = false;
    if (surface && surface->surfaceClass() == QSurface::Window && !surface->surfaceHandle()) {
        surface = fallbackSurface;
        nativeWindowGone = true;
    }

    if (!surface)
        surface = fallbackSurface;

    if (needsMakeCurrent)
        needsMakeCurrent = false;
    else if (!nativeWindowGone && QOpenGLContext::currentContext() == ctx && (surface == fallbackSurface || ctx->surface() == surface))
        return true;

    if (!ctx->makeCurrent(surface)) {
        if (ctx->isValid()) {
            qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
        } else {
            qWarning("QRhiGles2: Context is lost.");
            contextLost = true;
        }
        return false;
    }

    return true;
}

bool QRhiGles2::create(QRhi::Flags flags)
{
    Q_UNUSED(flags);
    Q_ASSERT(fallbackSurface);

    if (!importedContext) {
        ctx = new QOpenGLContext;
        ctx->setFormat(requestedFormat);
        if (!ctx->create()) {
            qWarning("QRhiGles2: Failed to create context");
            delete ctx;
            ctx = nullptr;
            return false;
        }
        qCDebug(QRHI_LOG_INFO) << "Created OpenGL context" << ctx->format();
    }

    if (!ensureContext(maybeWindow ? maybeWindow : fallbackSurface)) // see 'window' discussion in QRhiGles2InitParams comments
        return false;

    f = static_cast<QOpenGLExtensions *>(ctx->extraFunctions());

    const char *vendor = reinterpret_cast<const char *>(f->glGetString(GL_VENDOR));
    const char *renderer = reinterpret_cast<const char *>(f->glGetString(GL_RENDERER));
    const char *version = reinterpret_cast<const char *>(f->glGetString(GL_VERSION));
    if (vendor && renderer && version)
        qCDebug(QRHI_LOG_INFO, "OpenGL VENDOR: %s RENDERER: %s VERSION: %s", vendor, renderer, version);

    const QSurfaceFormat actualFormat = ctx->format();

    caps.ctxMajor = actualFormat.majorVersion();
    caps.ctxMinor = actualFormat.minorVersion();

    GLint n = 0;
    f->glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &n);
    supportedCompressedFormats.resize(n);
    if (n > 0)
        f->glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, supportedCompressedFormats.data());

    f->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.maxTextureSize);

    if (caps.ctxMajor >= 3 || actualFormat.renderableType() == QSurfaceFormat::OpenGL) {
        f->glGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps.maxDrawBuffers);
        f->glGetIntegerv(GL_MAX_SAMPLES, &caps.maxSamples);
        caps.maxSamples = qMax(1, caps.maxSamples);
    } else {
        caps.maxDrawBuffers = 1;
        caps.maxSamples = 1;
    }

    caps.msaaRenderBuffer = f->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)
            && f->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);

    caps.npotTextureFull = f->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)
            && f->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat);

    caps.gles = actualFormat.renderableType() == QSurfaceFormat::OpenGLES;
    if (caps.gles)
        caps.fixedIndexPrimitiveRestart = caps.ctxMajor >= 3; // ES 3.0
    else
        caps.fixedIndexPrimitiveRestart = caps.ctxMajor > 4 || (caps.ctxMajor == 4 && caps.ctxMinor >= 3); // 4.3

    if (caps.fixedIndexPrimitiveRestart)
        f->glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);

    caps.bgraExternalFormat = f->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat);
    caps.bgraInternalFormat = caps.bgraExternalFormat && caps.gles;
    caps.r8Format = f->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats);
    caps.r16Format = f->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats);
    caps.floatFormats = caps.ctxMajor >= 3; // 3.0 or ES 3.0
    caps.depthTexture = caps.ctxMajor >= 3; // 3.0 or ES 3.0
    caps.packedDepthStencil = f->hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil);
#ifdef Q_OS_WASM
    caps.needsDepthStencilCombinedAttach = true;
#else
    caps.needsDepthStencilCombinedAttach = false;
#endif
    caps.srgbCapableDefaultFramebuffer = f->hasOpenGLExtension(QOpenGLExtensions::SRGBFrameBuffer);
    caps.coreProfile = actualFormat.profile() == QSurfaceFormat::CoreProfile;

    if (caps.gles)
        caps.uniformBuffers = caps.ctxMajor >= 3; // ES 3.0
    else
        caps.uniformBuffers = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 1); // 3.1

    caps.elementIndexUint = f->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint);
    caps.depth24 = f->hasOpenGLExtension(QOpenGLExtensions::Depth24);
    caps.rgba8Format = f->hasOpenGLExtension(QOpenGLExtensions::Sized8Formats);

    if (caps.gles)
        caps.instancing = caps.ctxMajor >= 3; // ES 3.0
    else
        caps.instancing = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 3); // 3.3

    caps.baseVertex = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 2); // 3.2 or ES 3.2

    if (caps.gles)
        caps.compute = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 1); // ES 3.1
    else
        caps.compute = caps.ctxMajor > 4 || (caps.ctxMajor == 4 && caps.ctxMinor >= 3); // 4.3

    if (caps.gles)
        caps.textureCompareMode = caps.ctxMajor >= 3; // ES 3.0
    else
        caps.textureCompareMode = true;

    // proper as in ES 3.0 (glMapBufferRange), not the old glMapBuffer
    // extension(s) (which is not in ES 3.0...messy)
    caps.properMapBuffer = f->hasOpenGLExtension(QOpenGLExtensions::MapBufferRange);

    if (caps.gles)
        caps.nonBaseLevelFramebufferTexture = caps.ctxMajor >= 3; // ES 3.0
    else
        caps.nonBaseLevelFramebufferTexture = true;

    if (!caps.gles) {
        f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
        f->glEnable(GL_POINT_SPRITE);
    } // else (with gles) these are always on

    nativeHandlesStruct.context = ctx;

    contextLost = false;

    return true;
}

void QRhiGles2::destroy()
{
    if (!f)
        return;

    ensureContext();
    executeDeferredReleases();

    if (vao) {
        f->glDeleteVertexArrays(1, &vao);
        vao = 0;
    }

    for (uint shader : m_shaderCache)
        f->glDeleteShader(shader);
    m_shaderCache.clear();

    if (!importedContext) {
        delete ctx;
        ctx = nullptr;
    }

    f = nullptr;
}

void QRhiGles2::executeDeferredReleases()
{
    for (int i = releaseQueue.count() - 1; i >= 0; --i) {
        const QRhiGles2::DeferredReleaseEntry &e(releaseQueue[i]);
        switch (e.type) {
        case QRhiGles2::DeferredReleaseEntry::Buffer:
            f->glDeleteBuffers(1, &e.buffer.buffer);
            break;
        case QRhiGles2::DeferredReleaseEntry::Pipeline:
            f->glDeleteProgram(e.pipeline.program);
            break;
        case QRhiGles2::DeferredReleaseEntry::Texture:
            f->glDeleteTextures(1, &e.texture.texture);
            break;
        case QRhiGles2::DeferredReleaseEntry::RenderBuffer:
            f->glDeleteRenderbuffers(1, &e.renderbuffer.renderbuffer);
            f->glDeleteRenderbuffers(1, &e.renderbuffer.renderbuffer2);
            break;
        case QRhiGles2::DeferredReleaseEntry::TextureRenderTarget:
            f->glDeleteFramebuffers(1, &e.textureRenderTarget.framebuffer);
            break;
        default:
            Q_UNREACHABLE();
            break;
        }
        releaseQueue.removeAt(i);
    }
}

QVector<int> QRhiGles2::supportedSampleCounts() const
{
    if (supportedSampleCountList.isEmpty()) {
        // 1, 2, 4, 8, ...
        for (int i = 1; i <= caps.maxSamples; i *= 2)
            supportedSampleCountList.append(i);
    }
    return supportedSampleCountList;
}

int QRhiGles2::effectiveSampleCount(int sampleCount) const
{
    // Stay compatible with QSurfaceFormat and friends where samples == 0 means the same as 1.
    const int s = qBound(1, sampleCount, 64);
    if (!supportedSampleCounts().contains(s)) {
        qWarning("Attempted to set unsupported sample count %d", sampleCount);
        return 1;
    }
    return s;
}

QRhiSwapChain *QRhiGles2::createSwapChain()
{
    return new QGles2SwapChain(this);
}

QRhiBuffer *QRhiGles2::createBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, int size)
{
    return new QGles2Buffer(this, type, usage, size);
}

int QRhiGles2::ubufAlignment() const
{
    // No real uniform buffers are used so no need to pretend there is any
    // alignment requirement.
    return 1;
}

bool QRhiGles2::isYUpInFramebuffer() const
{
    return true;
}

bool QRhiGles2::isYUpInNDC() const
{
    return true;
}

bool QRhiGles2::isClipDepthZeroToOne() const
{
    return false;
}

QMatrix4x4 QRhiGles2::clipSpaceCorrMatrix() const
{
    return QMatrix4x4(); // identity
}

static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags)
{
    const bool srgb = flags.testFlag(QRhiTexture::sRGB);
    switch (format) {
    case QRhiTexture::BC1:
        return srgb ? 0x8C4C : 0x83F0;
    case QRhiTexture::BC3:
        return srgb ? 0x8C4E : 0x83F2;
    case QRhiTexture::BC5:
        return srgb ? 0x8C4F : 0x83F3;

    case QRhiTexture::ETC2_RGB8:
        return srgb ? 0x9275 : 0x9274;
    case QRhiTexture::ETC2_RGB8A1:
        return srgb ? 0x9277 : 0x9276;
    case QRhiTexture::ETC2_RGBA8:
        return srgb ? 0x9279 : 0x9278;

    case QRhiTexture::ASTC_4x4:
        return srgb ? 0x93D0 : 0x93B0;
    case QRhiTexture::ASTC_5x4:
        return srgb ? 0x93D1 : 0x93B1;
    case QRhiTexture::ASTC_5x5:
        return srgb ? 0x93D2 : 0x93B2;
    case QRhiTexture::ASTC_6x5:
        return srgb ? 0x93D3 : 0x93B3;
    case QRhiTexture::ASTC_6x6:
        return srgb ? 0x93D4 : 0x93B4;
    case QRhiTexture::ASTC_8x5:
        return srgb ? 0x93D5 : 0x93B5;
    case QRhiTexture::ASTC_8x6:
        return srgb ? 0x93D6 : 0x93B6;
    case QRhiTexture::ASTC_8x8:
        return srgb ? 0x93D7 : 0x93B7;
    case QRhiTexture::ASTC_10x5:
        return srgb ? 0x93D8 : 0x93B8;
    case QRhiTexture::ASTC_10x6:
        return srgb ? 0x93D9 : 0x93B9;
    case QRhiTexture::ASTC_10x8:
        return srgb ? 0x93DA : 0x93BA;
    case QRhiTexture::ASTC_10x10:
        return srgb ? 0x93DB : 0x93BB;
    case QRhiTexture::ASTC_12x10:
        return srgb ? 0x93DC : 0x93BC;
    case QRhiTexture::ASTC_12x12:
        return srgb ? 0x93DD : 0x93BD;

    default:
        return 0; // this is reachable, just return an invalid format
    }
}

bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
    if (isCompressedFormat(format))
        return supportedCompressedFormats.contains(GLint(toGlCompressedTextureFormat(format, flags)));

    switch (format) {
    case QRhiTexture::D16:
        Q_FALLTHROUGH();
    case QRhiTexture::D32F:
        return caps.depthTexture;

    case QRhiTexture::BGRA8:
        return caps.bgraExternalFormat;

    case QRhiTexture::R8:
        return caps.r8Format;

    case QRhiTexture::R16:
        return caps.r16Format;

    case QRhiTexture::RGBA16F:
        Q_FALLTHROUGH();
    case QRhiTexture::RGBA32F:
        return caps.floatFormats;

    default:
        break;
    }

    return true;
}

bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
{
    switch (feature) {
    case QRhi::MultisampleTexture:
        return false;
    case QRhi::MultisampleRenderBuffer:
        return caps.msaaRenderBuffer;
    case QRhi::DebugMarkers:
        return false;
    case QRhi::Timestamps:
        return false;
    case QRhi::Instancing:
        return caps.instancing;
    case QRhi::CustomInstanceStepRate:
        return false;
    case QRhi::PrimitiveRestart:
        return caps.fixedIndexPrimitiveRestart;
    case QRhi::NonDynamicUniformBuffers:
        return true;
    case QRhi::NonFourAlignedEffectiveIndexBufferOffset:
        return true;
    case QRhi::NPOTTextureRepeat:
        return caps.npotTextureFull;
    case QRhi::RedOrAlpha8IsRed:
        return caps.coreProfile;
    case QRhi::ElementIndexUint:
        return caps.elementIndexUint;
    case QRhi::Compute:
        return caps.compute;
    case QRhi::WideLines:
        return true;
    case QRhi::VertexShaderPointSize:
        return true;
    case QRhi::BaseVertex:
        return caps.baseVertex;
    case QRhi::BaseInstance:
        return false; // not in ES 3.2, so won't bother
    case QRhi::TriangleFanTopology:
        return true;
    case QRhi::ReadBackNonUniformBuffer:
        return !caps.gles || caps.properMapBuffer;
    case QRhi::ReadBackNonBaseMipLevel:
        return caps.nonBaseLevelFramebufferTexture;
    default:
        Q_UNREACHABLE();
        return false;
    }
}

int QRhiGles2::resourceLimit(QRhi::ResourceLimit limit) const
{
    switch (limit) {
    case QRhi::TextureSizeMin:
        return 1;
    case QRhi::TextureSizeMax:
        return caps.maxTextureSize;
    case QRhi::MaxColorAttachments:
        return caps.maxDrawBuffers;
    case QRhi::FramesInFlight:
        return 2; // dummy
    default:
        Q_UNREACHABLE();
        return 0;
    }
}

const QRhiNativeHandles *QRhiGles2::nativeHandles()
{
    return &nativeHandlesStruct;
}

void QRhiGles2::sendVMemStatsToProfiler()
{
    // nothing to do here
}

bool QRhiGles2::makeThreadLocalNativeContextCurrent()
{
    if (inFrame && !ofr.active)
        return ensureContext(currentSwapChain->surface);
    else
        return ensureContext();
}

void QRhiGles2::releaseCachedResources()
{
    if (!ensureContext())
        return;

    for (uint shader : m_shaderCache)
        f->glDeleteShader(shader);

    m_shaderCache.clear();
}

bool QRhiGles2::isDeviceLost() const
{
    return contextLost;
}

QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
                                                int sampleCount, QRhiRenderBuffer::Flags flags)
{
    return new QGles2RenderBuffer(this, type, pixelSize, sampleCount, flags);
}

QRhiTexture *QRhiGles2::createTexture(QRhiTexture::Format format, const QSize &pixelSize,
                                      int sampleCount, QRhiTexture::Flags flags)
{
    return new QGles2Texture(this, format, pixelSize, sampleCount, flags);
}

QRhiSampler *QRhiGles2::createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter,
                                      QRhiSampler::Filter mipmapMode,
                                      QRhiSampler::AddressMode u, QRhiSampler::AddressMode v)
{
    return new QGles2Sampler(this, magFilter, minFilter, mipmapMode, u, v);
}

QRhiTextureRenderTarget *QRhiGles2::createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
                                                              QRhiTextureRenderTarget::Flags flags)
{
    return new QGles2TextureRenderTarget(this, desc, flags);
}

QRhiGraphicsPipeline *QRhiGles2::createGraphicsPipeline()
{
    return new QGles2GraphicsPipeline(this);
}

QRhiShaderResourceBindings *QRhiGles2::createShaderResourceBindings()
{
    return new QGles2ShaderResourceBindings(this);
}

QRhiComputePipeline *QRhiGles2::createComputePipeline()
{
    return new QGles2ComputePipeline(this);
}

void QRhiGles2::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline *ps)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);
    QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, ps);
    const bool pipelineChanged = cbD->currentGraphicsPipeline != ps || cbD->currentPipelineGeneration != psD->generation;

    if (pipelineChanged) {
        cbD->currentGraphicsPipeline = ps;
        cbD->currentComputePipeline = nullptr;
        cbD->currentPipelineGeneration = psD->generation;

        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::BindGraphicsPipeline;
        cmd.args.bindGraphicsPipeline.ps = ps;
        cbD->commands.append(cmd);
    }
}

void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb,
                                   int dynamicOffsetCount,
                                   const QRhiCommandBuffer::DynamicOffset *dynamicOffsets)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass != QGles2CommandBuffer::NoPass);
    QGles2GraphicsPipeline *gfxPsD = QRHI_RES(QGles2GraphicsPipeline, cbD->currentGraphicsPipeline);
    QGles2ComputePipeline *compPsD = QRHI_RES(QGles2ComputePipeline, cbD->currentComputePipeline);

    if (!srb) {
        if (gfxPsD)
            srb = gfxPsD->m_shaderResourceBindings;
        else
            srb = compPsD->m_shaderResourceBindings;
    }

    QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);
    QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb);
    bool hasDynamicOffsetInSrb = false;
    for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
        const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data();
        switch (b->type) {
        case QRhiShaderResourceBinding::UniformBuffer:
            // no BufUniformRead / AccessUniform because no real uniform buffers are used
            if (b->u.ubuf.hasDynamicOffset)
                hasDynamicOffsetInSrb = true;
            break;
        case QRhiShaderResourceBinding::SampledTexture:
            trackedRegisterTexture(&passResTracker,
                                   QRHI_RES(QGles2Texture, b->u.stex.tex),
                                   QRhiPassResourceTracker::TexSample,
                                   QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage));
            break;
        case QRhiShaderResourceBinding::ImageLoad:
            Q_FALLTHROUGH();
        case QRhiShaderResourceBinding::ImageStore:
            Q_FALLTHROUGH();
        case QRhiShaderResourceBinding::ImageLoadStore:
        {
            QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex);
            QRhiPassResourceTracker::TextureAccess access;
            if (b->type == QRhiShaderResourceBinding::ImageLoad)
                access = QRhiPassResourceTracker::TexStorageLoad;
            else if (b->type == QRhiShaderResourceBinding::ImageStore)
                access = QRhiPassResourceTracker::TexStorageStore;
            else
                access = QRhiPassResourceTracker::TexStorageLoadStore;
            trackedRegisterTexture(&passResTracker, texD, access,
                                   QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage));
        }
            break;
        case QRhiShaderResourceBinding::BufferLoad:
            Q_FALLTHROUGH();
        case QRhiShaderResourceBinding::BufferStore:
            Q_FALLTHROUGH();
        case QRhiShaderResourceBinding::BufferLoadStore:
        {
            QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
            QRhiPassResourceTracker::BufferAccess access;
            if (b->type == QRhiShaderResourceBinding::BufferLoad)
                access = QRhiPassResourceTracker::BufStorageLoad;
            else if (b->type == QRhiShaderResourceBinding::BufferStore)
                access = QRhiPassResourceTracker::BufStorageStore;
            else
                access = QRhiPassResourceTracker::BufStorageLoadStore;
            trackedRegisterBuffer(&passResTracker, bufD, access,
                                  QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage));
        }
            break;
        default:
            break;
        }
    }

    const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb);
    const bool srbRebuilt = cbD->currentSrbGeneration != srbD->generation;

    if (srbChanged || srbRebuilt || hasDynamicOffsetInSrb) {
        if (gfxPsD) {
            cbD->currentGraphicsSrb = srb;
            cbD->currentComputeSrb = nullptr;
        } else {
            cbD->currentGraphicsSrb = nullptr;
            cbD->currentComputeSrb = srb;
        }
        cbD->currentSrbGeneration = srbD->generation;

        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::BindShaderResources;
        cmd.args.bindShaderResources.maybeGraphicsPs = gfxPsD;
        cmd.args.bindShaderResources.maybeComputePs = compPsD;
        cmd.args.bindShaderResources.srb = srb;
        cmd.args.bindShaderResources.dynamicOffsetCount = 0;
        if (hasDynamicOffsetInSrb) {
            if (dynamicOffsetCount < QGles2CommandBuffer::Command::MAX_UBUF_BINDINGS) {
                cmd.args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount;
                uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
                for (int i = 0; i < dynamicOffsetCount; ++i) {
                    const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
                    *p++ = uint(dynOfs.first);
                    *p++ = dynOfs.second;
                }
            } else {
                qWarning("Too many dynamic offsets (%d, max is %d)",
                         dynamicOffsetCount, QGles2CommandBuffer::Command::MAX_UBUF_BINDINGS);
            }
        }
        cbD->commands.append(cmd);
    }
}

void QRhiGles2::setVertexInput(QRhiCommandBuffer *cb,
                               int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings,
                               QRhiBuffer *indexBuf, quint32 indexOffset, QRhiCommandBuffer::IndexFormat indexFormat)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);
    QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);

    for (int i = 0; i < bindingCount; ++i) {
        QRhiBuffer *buf = bindings[i].first;
        quint32 ofs = bindings[i].second;
        QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, buf);
        Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::VertexBuffer));

        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::BindVertexBuffer;
        cmd.args.bindVertexBuffer.ps = cbD->currentGraphicsPipeline;
        cmd.args.bindVertexBuffer.buffer = bufD->buffer;
        cmd.args.bindVertexBuffer.offset = ofs;
        cmd.args.bindVertexBuffer.binding = startBinding + i;
        cbD->commands.append(cmd);

        trackedRegisterBuffer(&passResTracker, bufD, QRhiPassResourceTracker::BufVertexInput,
                              QRhiPassResourceTracker::BufVertexInputStage);
    }

    if (indexBuf) {
        QGles2Buffer *ibufD = QRHI_RES(QGles2Buffer, indexBuf);
        Q_ASSERT(ibufD->m_usage.testFlag(QRhiBuffer::IndexBuffer));

        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::BindIndexBuffer;
        cmd.args.bindIndexBuffer.buffer = ibufD->buffer;
        cmd.args.bindIndexBuffer.offset = indexOffset;
        cmd.args.bindIndexBuffer.type = indexFormat == QRhiCommandBuffer::IndexUInt16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
        cbD->commands.append(cmd);

        trackedRegisterBuffer(&passResTracker, ibufD, QRhiPassResourceTracker::BufIndexRead,
                              QRhiPassResourceTracker::BufVertexInputStage);
    }
}

void QRhiGles2::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);

    QGles2CommandBuffer::Command cmd;
    cmd.cmd = QGles2CommandBuffer::Command::Viewport;
    const std::array<float, 4> r = viewport.viewport();
    // A negative width or height is an error. A negative x or y is not.
    if (r[2] < 0.0f || r[3] < 0.0f)
        return;

    cmd.args.viewport.x = r[0];
    cmd.args.viewport.y = r[1];
    cmd.args.viewport.w = r[2];
    cmd.args.viewport.h = r[3];
    cmd.args.viewport.d0 = viewport.minDepth();
    cmd.args.viewport.d1 = viewport.maxDepth();
    cbD->commands.append(cmd);
}

void QRhiGles2::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);

    QGles2CommandBuffer::Command cmd;
    cmd.cmd = QGles2CommandBuffer::Command::Scissor;
    const std::array<int, 4> r = scissor.scissor();
    // A negative width or height is an error. A negative x or y is not.
    if (r[2] < 0 || r[3] < 0)
        return;

    cmd.args.scissor.x = r[0];
    cmd.args.scissor.y = r[1];
    cmd.args.scissor.w = r[2];
    cmd.args.scissor.h = r[3];
    cbD->commands.append(cmd);
}

void QRhiGles2::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);

    QGles2CommandBuffer::Command cmd;
    cmd.cmd = QGles2CommandBuffer::Command::BlendConstants;
    cmd.args.blendConstants.r = float(c.redF());
    cmd.args.blendConstants.g = float(c.greenF());
    cmd.args.blendConstants.b = float(c.blueF());
    cmd.args.blendConstants.a = float(c.alphaF());
    cbD->commands.append(cmd);
}

void QRhiGles2::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);

    QGles2CommandBuffer::Command cmd;
    cmd.cmd = QGles2CommandBuffer::Command::StencilRef;
    cmd.args.stencilRef.ref = refValue;
    cmd.args.stencilRef.ps = cbD->currentGraphicsPipeline;
    cbD->commands.append(cmd);
}

void QRhiGles2::draw(QRhiCommandBuffer *cb, quint32 vertexCount,
                     quint32 instanceCount, quint32 firstVertex, quint32 firstInstance)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);

    QGles2CommandBuffer::Command cmd;
    cmd.cmd = QGles2CommandBuffer::Command::Draw;
    cmd.args.draw.ps = cbD->currentGraphicsPipeline;
    cmd.args.draw.vertexCount = vertexCount;
    cmd.args.draw.firstVertex = firstVertex;
    cmd.args.draw.instanceCount = instanceCount;
    cmd.args.draw.baseInstance = firstInstance;
    cbD->commands.append(cmd);
}

void QRhiGles2::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
                            quint32 instanceCount, quint32 firstIndex, qint32 vertexOffset, quint32 firstInstance)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);

    QGles2CommandBuffer::Command cmd;
    cmd.cmd = QGles2CommandBuffer::Command::DrawIndexed;
    cmd.args.drawIndexed.ps = cbD->currentGraphicsPipeline;
    cmd.args.drawIndexed.indexCount = indexCount;
    cmd.args.drawIndexed.firstIndex = firstIndex;
    cmd.args.drawIndexed.instanceCount = instanceCount;
    cmd.args.drawIndexed.baseInstance = firstInstance;
    cmd.args.drawIndexed.baseVertex = vertexOffset;
    cbD->commands.append(cmd);
}

void QRhiGles2::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
{
    if (!debugMarkers)
        return;

    Q_UNUSED(cb);
    Q_UNUSED(name);
}

void QRhiGles2::debugMarkEnd(QRhiCommandBuffer *cb)
{
    if (!debugMarkers)
        return;

    Q_UNUSED(cb);
}

void QRhiGles2::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
{
    if (!debugMarkers)
        return;

    Q_UNUSED(cb);
    Q_UNUSED(msg);
}

const QRhiNativeHandles *QRhiGles2::nativeHandles(QRhiCommandBuffer *cb)
{
    Q_UNUSED(cb);
    return nullptr;
}

static void addBoundaryCommand(QGles2CommandBuffer *cbD, QGles2CommandBuffer::Command::Cmd type)
{
    QGles2CommandBuffer::Command cmd;
    cmd.cmd = type;
    cbD->commands.append(cmd);
}

void QRhiGles2::beginExternal(QRhiCommandBuffer *cb)
{
    if (ofr.active) {
        Q_ASSERT(!currentSwapChain);
        if (!ensureContext())
            return;
    } else {
        Q_ASSERT(currentSwapChain);
        if (!ensureContext(currentSwapChain->surface))
            return;
    }

    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    executeCommandBuffer(cbD);
    cbD->resetCommands();

    if (vao)
        f->glBindVertexArray(0);
}

void QRhiGles2::endExternal(QRhiCommandBuffer *cb)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->commands.isEmpty() && cbD->currentPassResTrackerIndex == -1);

    cbD->resetCachedState();

    if (cbD->recordingPass != QGles2CommandBuffer::NoPass) {
        // Commands that come after this point need a resource tracker and also
        // a BarriersForPass command enqueued. (the ones we had from
        // beginPass() are now gone since beginExternal() processed all that
        // due to calling executeCommandBuffer()).
        enqueueBarriersForPass(cbD);
    }

    addBoundaryCommand(cbD, QGles2CommandBuffer::Command::ResetFrame);

    if (cbD->currentTarget)
        enqueueBindFramebuffer(cbD->currentTarget, cbD);
}

QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags)
{
    Q_UNUSED(flags);

    QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
    if (!ensureContext(swapChainD->surface))
        return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;

    currentSwapChain = swapChainD;

    QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
    QRHI_PROF_F(beginSwapChainFrame(swapChain));

    executeDeferredReleases();
    swapChainD->cb.resetState();

    addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::BeginFrame);

    return QRhi::FrameOpSuccess;
}

QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags)
{
    QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
    Q_ASSERT(currentSwapChain == swapChainD);

    addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame);

    if (!ensureContext(swapChainD->surface))
        return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;

    executeCommandBuffer(&swapChainD->cb);

    QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
    // this must be done before the swap
    QRHI_PROF_F(endSwapChainFrame(swapChain, swapChainD->frameCount + 1));

    if (swapChainD->surface && !flags.testFlag(QRhi::SkipPresent)) {
        ctx->swapBuffers(swapChainD->surface);
        needsMakeCurrent = true;
    } else {
        f->glFlush();
    }

    swapChainD->frameCount += 1;
    currentSwapChain = nullptr;
    return QRhi::FrameOpSuccess;
}

QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags)
{
    Q_UNUSED(flags);
    if (!ensureContext())
        return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;

    ofr.active = true;

    executeDeferredReleases();
    ofr.cbWrapper.resetState();

    addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::BeginFrame);
    *cb = &ofr.cbWrapper;

    return QRhi::FrameOpSuccess;
}

QRhi::FrameOpResult QRhiGles2::endOffscreenFrame(QRhi::EndFrameFlags flags)
{
    Q_UNUSED(flags);
    Q_ASSERT(ofr.active);
    ofr.active = false;

    addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame);

    if (!ensureContext())
        return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;

    executeCommandBuffer(&ofr.cbWrapper);

    return QRhi::FrameOpSuccess;
}

QRhi::FrameOpResult QRhiGles2::finish()
{
    if (inFrame) {
        if (ofr.active) {
            Q_ASSERT(!currentSwapChain);
            Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass);
            if (!ensureContext())
                return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
            executeCommandBuffer(&ofr.cbWrapper);
            ofr.cbWrapper.resetCommands();
        } else {
            Q_ASSERT(currentSwapChain);
            Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass);
            if (!ensureContext(currentSwapChain->surface))
                return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
            executeCommandBuffer(&currentSwapChain->cb);
            currentSwapChain->cb.resetCommands();
        }
    }
    return QRhi::FrameOpSuccess;
}

void QRhiGles2::trackedBufferBarrier(QGles2CommandBuffer *cbD, QGles2Buffer *bufD, QGles2Buffer::Access access)
{
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::NoPass); // this is for resource updates only
    const QGles2Buffer::Access prevAccess = bufD->usageState.access;
    if (access == prevAccess)
        return;

    if (prevAccess == QGles2Buffer::AccessStorageWrite || prevAccess == QGles2Buffer::AccessStorageReadWrite) {
        // Generating the minimal barrier set is way too complicated to do
        // correctly (prevAccess is overwritten so we won't have proper
        // tracking across multiple passes) so setting all barrier bits will do
        // for now.
        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::Barrier;
        cmd.args.barrier.barriers = GL_ALL_BARRIER_BITS;
        cbD->commands.append(cmd);
    }

    bufD->usageState.access = access;
}

void QRhiGles2::trackedImageBarrier(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Texture::Access access)
{
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::NoPass); // this is for resource updates only
    const QGles2Texture::Access prevAccess = texD->usageState.access;
    if (access == prevAccess)
        return;

    if (prevAccess == QGles2Texture::AccessStorageWrite || prevAccess == QGles2Texture::AccessStorageReadWrite) {
        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::Barrier;
        cmd.args.barrier.barriers = GL_ALL_BARRIER_BITS;
        cbD->commands.append(cmd);
    }

    texD->usageState.access = access;
}

void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cbD,
                                    int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc)
{
    trackedImageBarrier(cbD, texD, QGles2Texture::AccessUpdate);
    const bool isCompressed = isCompressedFormat(texD->m_format);
    const bool isCubeMap = texD->m_flags.testFlag(QRhiTexture::CubeMap);
    const GLenum faceTargetBase = isCubeMap ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
    const QPoint dp = subresDesc.destinationTopLeft();
    const QByteArray rawData = subresDesc.data();
    if (!subresDesc.image().isNull()) {
        QImage img = subresDesc.image();
        QSize size = img.size();
        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::SubImage;
        if (!subresDesc.sourceSize().isEmpty() || !subresDesc.sourceTopLeft().isNull()) {
            const QPoint sp = subresDesc.sourceTopLeft();
            if (!subresDesc.sourceSize().isEmpty())
                size = subresDesc.sourceSize();
            img = img.copy(sp.x(), sp.y(), size.width(), size.height());
        }
        cmd.args.subImage.target = texD->target;
        cmd.args.subImage.texture = texD->texture;
        cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
        cmd.args.subImage.level = level;
        cmd.args.subImage.dx = dp.x();
        cmd.args.subImage.dy = dp.y();
        cmd.args.subImage.w = size.width();
        cmd.args.subImage.h = size.height();
        cmd.args.subImage.glformat = texD->glformat;
        cmd.args.subImage.gltype = texD->gltype;
        cmd.args.subImage.rowStartAlign = 4;
        cmd.args.subImage.data = cbD->retainImage(img);
        cbD->commands.append(cmd);
    } else if (!rawData.isEmpty() && isCompressed) {
        const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
                                                             : subresDesc.sourceSize();
        if (texD->specified) {
            QGles2CommandBuffer::Command cmd;
            cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage;
            cmd.args.compressedSubImage.target = texD->target;
            cmd.args.compressedSubImage.texture = texD->texture;
            cmd.args.compressedSubImage.faceTarget = faceTargetBase + uint(layer);
            cmd.args.compressedSubImage.level = level;
            cmd.args.compressedSubImage.dx = dp.x();
            cmd.args.compressedSubImage.dy = dp.y();
            cmd.args.compressedSubImage.w = size.width();
            cmd.args.compressedSubImage.h = size.height();
            cmd.args.compressedSubImage.glintformat = texD->glintformat;
            cmd.args.compressedSubImage.size = rawData.size();
            cmd.args.compressedSubImage.data = cbD->retainData(rawData);
            cbD->commands.append(cmd);
        } else {
            QGles2CommandBuffer::Command cmd;
            cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
            cmd.args.compressedImage.target = texD->target;
            cmd.args.compressedImage.texture = texD->texture;
            cmd.args.compressedImage.faceTarget = faceTargetBase + uint(layer);
            cmd.args.compressedImage.level = level;
            cmd.args.compressedImage.glintformat = texD->glintformat;
            cmd.args.compressedImage.w = size.width();
            cmd.args.compressedImage.h = size.height();
            cmd.args.compressedImage.size = rawData.size();
            cmd.args.compressedImage.data = cbD->retainData(rawData);
            cbD->commands.append(cmd);
        }
    } else if (!rawData.isEmpty()) {
        const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
                                                             : subresDesc.sourceSize();
        quint32 bpl = 0;
        textureFormatInfo(texD->m_format, size, &bpl, nullptr);
        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::SubImage;
        cmd.args.subImage.target = texD->target;
        cmd.args.subImage.texture = texD->texture;
        cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
        cmd.args.subImage.level = level;
        cmd.args.subImage.dx = dp.x();
        cmd.args.subImage.dy = dp.y();
        cmd.args.subImage.w = size.width();
        cmd.args.subImage.h = size.height();
        cmd.args.subImage.glformat = texD->glformat;
        cmd.args.subImage.gltype = texD->gltype;
        // Default unpack alignment (row start aligment
        // requirement) is 4. QImage guarantees 4 byte aligned
        // row starts, but our raw data here does not.
        cmd.args.subImage.rowStartAlign = (bpl & 3) ? 1 : 4;
        cmd.args.subImage.data = cbD->retainData(rawData);
        cbD->commands.append(cmd);
    } else {
        qWarning("Invalid texture upload for %p layer=%d mip=%d", texD, layer, level);
    }
}

void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);

    for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
        if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
            QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
            Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
            if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
                memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
            } else {
                trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
                QGles2CommandBuffer::Command cmd;
                cmd.cmd = QGles2CommandBuffer::Command::BufferSubData;
                cmd.args.bufferSubData.target = bufD->targetForDataOps;
                cmd.args.bufferSubData.buffer = bufD->buffer;
                cmd.args.bufferSubData.offset = u.offset;
                cmd.args.bufferSubData.size = u.data.size();
                cmd.args.bufferSubData.data = cbD->retainData(u.data);
                cbD->commands.append(cmd);
            }
        } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::StaticUpload) {
            QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
            Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
            Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
            if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
                memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
            } else {
                trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
                QGles2CommandBuffer::Command cmd;
                cmd.cmd = QGles2CommandBuffer::Command::BufferSubData;
                cmd.args.bufferSubData.target = bufD->targetForDataOps;
                cmd.args.bufferSubData.buffer = bufD->buffer;
                cmd.args.bufferSubData.offset = u.offset;
                cmd.args.bufferSubData.size = u.data.size();
                cmd.args.bufferSubData.data = cbD->retainData(u.data);
                cbD->commands.append(cmd);
            }
        } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
            QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
            if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
                u.result->data.resize(u.readSize);
                memcpy(u.result->data.data(), bufD->ubuf.constData() + u.offset, size_t(u.readSize));
                if (u.result->completed)
                    u.result->completed();
            } else {
                QGles2CommandBuffer::Command cmd;
                cmd.cmd = QGles2CommandBuffer::Command::GetBufferSubData;
                cmd.args.getBufferSubData.result = u.result;
                cmd.args.getBufferSubData.target = bufD->targetForDataOps;
                cmd.args.getBufferSubData.buffer = bufD->buffer;
                cmd.args.getBufferSubData.offset = u.offset;
                cmd.args.getBufferSubData.size = u.readSize;
                cbD->commands.append(cmd);
            }
        }
    }

    for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
        if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
            QGles2Texture *texD = QRHI_RES(QGles2Texture, u.dst);
            for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
                for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
                    for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level]))
                        enqueueSubresUpload(texD, cbD, layer, level, subresDesc);
                }
            }
            texD->specified = true;
        } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Copy) {
            Q_ASSERT(u.src && u.dst);
            QGles2Texture *srcD = QRHI_RES(QGles2Texture, u.src);
            QGles2Texture *dstD = QRHI_RES(QGles2Texture, u.dst);

            trackedImageBarrier(cbD, srcD, QGles2Texture::AccessRead);
            trackedImageBarrier(cbD, dstD, QGles2Texture::AccessUpdate);

            const QSize mipSize = q->sizeForMipLevel(u.desc.sourceLevel(), srcD->m_pixelSize);
            const QSize copySize = u.desc.pixelSize().isEmpty() ? mipSize : u.desc.pixelSize();
            // do not translate coordinates, even if sp is bottom-left from gl's pov
            const QPoint sp = u.desc.sourceTopLeft();
            const QPoint dp = u.desc.destinationTopLeft();

            const GLenum srcFaceTargetBase = srcD->m_flags.testFlag(QRhiTexture::CubeMap)
                    ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : srcD->target;
            const GLenum dstFaceTargetBase = dstD->m_flags.testFlag(QRhiTexture::CubeMap)
                    ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : dstD->target;

            QGles2CommandBuffer::Command cmd;
            cmd.cmd = QGles2CommandBuffer::Command::CopyTex;

            cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + uint(u.desc.sourceLayer());
            cmd.args.copyTex.srcTexture = srcD->texture;
            cmd.args.copyTex.srcLevel = u.desc.sourceLevel();
            cmd.args.copyTex.srcX = sp.x();
            cmd.args.copyTex.srcY = sp.y();

            cmd.args.copyTex.dstTarget = dstD->target;
            cmd.args.copyTex.dstTexture = dstD->texture;
            cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + uint(u.desc.destinationLayer());
            cmd.args.copyTex.dstLevel = u.desc.destinationLevel();
            cmd.args.copyTex.dstX = dp.x();
            cmd.args.copyTex.dstY = dp.y();

            cmd.args.copyTex.w = copySize.width();
            cmd.args.copyTex.h = copySize.height();

            cbD->commands.append(cmd);
        } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
            QGles2CommandBuffer::Command cmd;
            cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
            cmd.args.readPixels.result = u.result;
            QGles2Texture *texD = QRHI_RES(QGles2Texture, u.rb.texture());
            if (texD)
                trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead);
            cmd.args.readPixels.texture = texD ? texD->texture : 0;
            if (texD) {
                const QSize readImageSize = q->sizeForMipLevel(u.rb.level(), texD->m_pixelSize);
                cmd.args.readPixels.w = readImageSize.width();
                cmd.args.readPixels.h = readImageSize.height();
                cmd.args.readPixels.format = texD->m_format;
                const GLenum faceTargetBase = texD->m_flags.testFlag(QRhiTexture::CubeMap)
                        ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
                cmd.args.readPixels.readTarget = faceTargetBase + uint(u.rb.layer());
                cmd.args.readPixels.level = u.rb.level();
            }
            cbD->commands.append(cmd);
        } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
            QGles2Texture *texD = QRHI_RES(QGles2Texture, u.dst);
            trackedImageBarrier(cbD, texD, QGles2Texture::AccessFramebuffer);
            QGles2CommandBuffer::Command cmd;
            cmd.cmd = QGles2CommandBuffer::Command::GenMip;
            cmd.args.genMip.target = texD->target;
            cmd.args.genMip.texture = texD->texture;
            cbD->commands.append(cmd);
        }
    }

    ud->free();
}

static inline GLenum toGlTopology(QRhiGraphicsPipeline::Topology t)
{
    switch (t) {
    case QRhiGraphicsPipeline::Triangles:
        return GL_TRIANGLES;
    case QRhiGraphicsPipeline::TriangleStrip:
        return GL_TRIANGLE_STRIP;
    case QRhiGraphicsPipeline::TriangleFan:
        return GL_TRIANGLE_FAN;
    case QRhiGraphicsPipeline::Lines:
        return GL_LINES;
    case QRhiGraphicsPipeline::LineStrip:
        return GL_LINE_STRIP;
    case QRhiGraphicsPipeline::Points:
        return GL_POINTS;
    default:
        Q_UNREACHABLE();
        return GL_TRIANGLES;
    }
}

static inline GLenum toGlCullMode(QRhiGraphicsPipeline::CullMode c)
{
    switch (c) {
    case QRhiGraphicsPipeline::Front:
        return GL_FRONT;
    case QRhiGraphicsPipeline::Back:
        return GL_BACK;
    default:
        Q_UNREACHABLE();
        return GL_BACK;
    }
}

static inline GLenum toGlFrontFace(QRhiGraphicsPipeline::FrontFace f)
{
    switch (f) {
    case QRhiGraphicsPipeline::CCW:
        return GL_CCW;
    case QRhiGraphicsPipeline::CW:
        return GL_CW;
    default:
        Q_UNREACHABLE();
        return GL_CCW;
    }
}

static inline GLenum toGlBlendFactor(QRhiGraphicsPipeline::BlendFactor f)
{
    switch (f) {
    case QRhiGraphicsPipeline::Zero:
        return GL_ZERO;
    case QRhiGraphicsPipeline::One:
        return GL_ONE;
    case QRhiGraphicsPipeline::SrcColor:
        return GL_SRC_COLOR;
    case QRhiGraphicsPipeline::OneMinusSrcColor:
        return GL_ONE_MINUS_SRC_COLOR;
    case QRhiGraphicsPipeline::DstColor:
        return GL_DST_COLOR;
    case QRhiGraphicsPipeline::OneMinusDstColor:
        return GL_ONE_MINUS_DST_COLOR;
    case QRhiGraphicsPipeline::SrcAlpha:
        return GL_SRC_ALPHA;
    case QRhiGraphicsPipeline::OneMinusSrcAlpha:
        return GL_ONE_MINUS_SRC_ALPHA;
    case QRhiGraphicsPipeline::DstAlpha:
        return GL_DST_ALPHA;
    case QRhiGraphicsPipeline::OneMinusDstAlpha:
        return GL_ONE_MINUS_DST_ALPHA;
    case QRhiGraphicsPipeline::ConstantColor:
        return GL_CONSTANT_COLOR;
    case QRhiGraphicsPipeline::OneMinusConstantColor:
        return GL_ONE_MINUS_CONSTANT_COLOR;
    case QRhiGraphicsPipeline::ConstantAlpha:
        return GL_CONSTANT_ALPHA;
    case QRhiGraphicsPipeline::OneMinusConstantAlpha:
        return GL_ONE_MINUS_CONSTANT_ALPHA;
    case QRhiGraphicsPipeline::SrcAlphaSaturate:
        return GL_SRC_ALPHA_SATURATE;
    case QRhiGraphicsPipeline::Src1Color:
        Q_FALLTHROUGH();
    case QRhiGraphicsPipeline::OneMinusSrc1Color:
        Q_FALLTHROUGH();
    case QRhiGraphicsPipeline::Src1Alpha:
        Q_FALLTHROUGH();
    case QRhiGraphicsPipeline::OneMinusSrc1Alpha:
        qWarning("Unsupported blend factor %d", f);
        return GL_ZERO;
    default:
        Q_UNREACHABLE();
        return GL_ZERO;
    }
}

static inline GLenum toGlBlendOp(QRhiGraphicsPipeline::BlendOp op)
{
    switch (op) {
    case QRhiGraphicsPipeline::Add:
        return GL_FUNC_ADD;
    case QRhiGraphicsPipeline::Subtract:
        return GL_FUNC_SUBTRACT;
    case QRhiGraphicsPipeline::ReverseSubtract:
        return GL_FUNC_REVERSE_SUBTRACT;
    case QRhiGraphicsPipeline::Min:
        return GL_MIN;
    case QRhiGraphicsPipeline::Max:
        return GL_MAX;
    default:
        Q_UNREACHABLE();
        return GL_FUNC_ADD;
    }
}

static inline GLenum toGlCompareOp(QRhiGraphicsPipeline::CompareOp op)
{
    switch (op) {
    case QRhiGraphicsPipeline::Never:
        return GL_NEVER;
    case QRhiGraphicsPipeline::Less:
        return GL_LESS;
    case QRhiGraphicsPipeline::Equal:
        return GL_EQUAL;
    case QRhiGraphicsPipeline::LessOrEqual:
        return GL_LEQUAL;
    case QRhiGraphicsPipeline::Greater:
        return GL_GREATER;
    case QRhiGraphicsPipeline::NotEqual:
        return GL_NOTEQUAL;
    case QRhiGraphicsPipeline::GreaterOrEqual:
        return GL_GEQUAL;
    case QRhiGraphicsPipeline::Always:
        return GL_ALWAYS;
    default:
        Q_UNREACHABLE();
        return GL_ALWAYS;
    }
}

static inline GLenum toGlStencilOp(QRhiGraphicsPipeline::StencilOp op)
{
    switch (op) {
    case QRhiGraphicsPipeline::StencilZero:
        return GL_ZERO;
    case QRhiGraphicsPipeline::Keep:
        return GL_KEEP;
    case QRhiGraphicsPipeline::Replace:
        return GL_REPLACE;
    case QRhiGraphicsPipeline::IncrementAndClamp:
        return GL_INCR;
    case QRhiGraphicsPipeline::DecrementAndClamp:
        return GL_DECR;
    case QRhiGraphicsPipeline::Invert:
        return GL_INVERT;
    case QRhiGraphicsPipeline::IncrementAndWrap:
        return GL_INCR_WRAP;
    case QRhiGraphicsPipeline::DecrementAndWrap:
        return GL_DECR_WRAP;
    default:
        Q_UNREACHABLE();
        return GL_KEEP;
    }
}

static inline GLenum toGlMinFilter(QRhiSampler::Filter f, QRhiSampler::Filter m)
{
    switch (f) {
    case QRhiSampler::Nearest:
        if (m == QRhiSampler::None)
            return GL_NEAREST;
        else
            return m == QRhiSampler::Nearest ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_LINEAR;
    case QRhiSampler::Linear:
        if (m == QRhiSampler::None)
            return GL_LINEAR;
        else
            return m == QRhiSampler::Nearest ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR;
    default:
        Q_UNREACHABLE();
        return GL_LINEAR;
    }
}

static inline GLenum toGlMagFilter(QRhiSampler::Filter f)
{
    switch (f) {
    case QRhiSampler::Nearest:
        return GL_NEAREST;
    case QRhiSampler::Linear:
        return GL_LINEAR;
    default:
        Q_UNREACHABLE();
        return GL_LINEAR;
    }
}

static inline GLenum toGlWrapMode(QRhiSampler::AddressMode m)
{
    switch (m) {
    case QRhiSampler::Repeat:
        return GL_REPEAT;
    case QRhiSampler::ClampToEdge:
        return GL_CLAMP_TO_EDGE;
    case QRhiSampler::Mirror:
        return GL_MIRRORED_REPEAT;
    case QRhiSampler::MirrorOnce:
        Q_FALLTHROUGH();
    case QRhiSampler::Border:
        qWarning("Unsupported wrap mode %d", m);
        return GL_CLAMP_TO_EDGE;
    default:
        Q_UNREACHABLE();
        return GL_CLAMP_TO_EDGE;
    }
}

static inline GLenum toGlTextureCompareFunc(QRhiSampler::CompareOp op)
{
    switch (op) {
    case QRhiSampler::Never:
        return GL_NEVER;
    case QRhiSampler::Less:
        return GL_LESS;
    case QRhiSampler::Equal:
        return GL_EQUAL;
    case QRhiSampler::LessOrEqual:
        return GL_LEQUAL;
    case QRhiSampler::Greater:
        return GL_GREATER;
    case QRhiSampler::NotEqual:
        return GL_NOTEQUAL;
    case QRhiSampler::GreaterOrEqual:
        return GL_GEQUAL;
    case QRhiSampler::Always:
        return GL_ALWAYS;
    default:
        Q_UNREACHABLE();
        return GL_NEVER;
    }
}

static inline QGles2Buffer::Access toGlAccess(QRhiPassResourceTracker::BufferAccess access)
{
    switch (access) {
    case QRhiPassResourceTracker::BufVertexInput:
        return QGles2Buffer::AccessVertex;
    case QRhiPassResourceTracker::BufIndexRead:
        return QGles2Buffer::AccessIndex;
    case QRhiPassResourceTracker::BufUniformRead:
        return QGles2Buffer::AccessUniform;
    case QRhiPassResourceTracker::BufStorageLoad:
        return QGles2Buffer::AccessStorageRead;
    case QRhiPassResourceTracker::BufStorageStore:
        return QGles2Buffer::AccessStorageWrite;
    case QRhiPassResourceTracker::BufStorageLoadStore:
        return QGles2Buffer::AccessStorageReadWrite;
    default:
        Q_UNREACHABLE();
        break;
    }
    return QGles2Buffer::AccessNone;
}

static inline QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const QGles2Buffer::UsageState &bufUsage)
{
    QRhiPassResourceTracker::UsageState u;
    u.layout = 0; // N/A
    u.access = bufUsage.access;
    u.stage = 0; // N/A
    return u;
}

static inline QGles2Texture::Access toGlAccess(QRhiPassResourceTracker::TextureAccess access)
{
    switch (access) {
    case QRhiPassResourceTracker::TexSample:
        return QGles2Texture::AccessSample;
    case QRhiPassResourceTracker::TexColorOutput:
        return QGles2Texture::AccessFramebuffer;
    case QRhiPassResourceTracker::TexDepthOutput:
        return QGles2Texture::AccessFramebuffer;
    case QRhiPassResourceTracker::TexStorageLoad:
        return QGles2Texture::AccessStorageRead;
    case QRhiPassResourceTracker::TexStorageStore:
        return QGles2Texture::AccessStorageWrite;
    case QRhiPassResourceTracker::TexStorageLoadStore:
        return QGles2Texture::AccessStorageReadWrite;
    default:
        Q_UNREACHABLE();
        break;
    }
    return QGles2Texture::AccessNone;
}

static inline QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const QGles2Texture::UsageState &texUsage)
{
    QRhiPassResourceTracker::UsageState u;
    u.layout = 0; // N/A
    u.access = texUsage.access;
    u.stage = 0; // N/A
    return u;
}

void QRhiGles2::trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker,
                                      QGles2Buffer *bufD,
                                      QRhiPassResourceTracker::BufferAccess access,
                                      QRhiPassResourceTracker::BufferStage stage)
{
    QGles2Buffer::UsageState &u(bufD->usageState);
    passResTracker->registerBuffer(bufD, 0, &access, &stage, toPassTrackerUsageState(u));
    u.access = toGlAccess(access);
}

void QRhiGles2::trackedRegisterTexture(QRhiPassResourceTracker *passResTracker,
                                       QGles2Texture *texD,
                                       QRhiPassResourceTracker::TextureAccess access,
                                       QRhiPassResourceTracker::TextureStage stage)
{
    QGles2Texture::UsageState &u(texD->usageState);
    passResTracker->registerTexture(texD, &access, &stage, toPassTrackerUsageState(u));
    u.access = toGlAccess(access);
}

void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    GLenum indexType = GL_UNSIGNED_SHORT;
    quint32 indexStride = sizeof(quint16);
    quint32 indexOffset = 0;

    for (const QGles2CommandBuffer::Command &cmd : qAsConst(cbD->commands)) {
        switch (cmd.cmd) {
        case QGles2CommandBuffer::Command::BeginFrame:
            if (caps.coreProfile) {
                if (!vao)
                    f->glGenVertexArrays(1, &vao);
                f->glBindVertexArray(vao);
            }
            break;
        case QGles2CommandBuffer::Command::EndFrame:
            if (vao)
                f->glBindVertexArray(0);
            break;
        case QGles2CommandBuffer::Command::ResetFrame:
            if (vao)
                f->glBindVertexArray(vao);
            break;
        case QGles2CommandBuffer::Command::Viewport:
            f->glViewport(GLint(cmd.args.viewport.x), GLint(cmd.args.viewport.y), GLsizei(cmd.args.viewport.w), GLsizei(cmd.args.viewport.h));
            f->glDepthRangef(cmd.args.viewport.d0, cmd.args.viewport.d1);
            break;
        case QGles2CommandBuffer::Command::Scissor:
            f->glScissor(cmd.args.scissor.x, cmd.args.scissor.y, cmd.args.scissor.w, cmd.args.scissor.h);
            break;
        case QGles2CommandBuffer::Command::BlendConstants:
            f->glBlendColor(cmd.args.blendConstants.r, cmd.args.blendConstants.g, cmd.args.blendConstants.b, cmd.args.blendConstants.a);
            break;
        case QGles2CommandBuffer::Command::StencilRef:
        {
            QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.stencilRef.ps);
            if (psD) {
                f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
                f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
            } else {
                qWarning("No graphics pipeline active for setStencilRef; ignored");
            }
        }
            break;
        case QGles2CommandBuffer::Command::BindVertexBuffer:
        {
            QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.bindVertexBuffer.ps);
            if (psD) {
                for (auto it = psD->m_vertexInputLayout.cbeginAttributes(), itEnd = psD->m_vertexInputLayout.cendAttributes();
                     it != itEnd; ++it)
                {
                    const int bindingIdx = it->binding();
                    if (bindingIdx != cmd.args.bindVertexBuffer.binding)
                        continue;

                    // we do not support more than one vertex buffer
                    f->glBindBuffer(GL_ARRAY_BUFFER, cmd.args.bindVertexBuffer.buffer);

                    const QRhiVertexInputBinding *inputBinding = psD->m_vertexInputLayout.bindingAt(bindingIdx);
                    const int stride = int(inputBinding->stride());
                    int size = 1;
                    GLenum type = GL_FLOAT;
                    bool normalize = false;
                    switch (it->format()) {
                    case QRhiVertexInputAttribute::Float4:
                        type = GL_FLOAT;
                        size = 4;
                        break;
                    case QRhiVertexInputAttribute::Float3:
                        type = GL_FLOAT;
                        size = 3;
                        break;
                    case QRhiVertexInputAttribute::Float2:
                        type = GL_FLOAT;
                        size = 2;
                        break;
                    case QRhiVertexInputAttribute::Float:
                        type = GL_FLOAT;
                        size = 1;
                        break;
                    case QRhiVertexInputAttribute::UNormByte4:
                        type = GL_UNSIGNED_BYTE;
                        normalize = true;
                        size = 4;
                        break;
                    case QRhiVertexInputAttribute::UNormByte2:
                        type = GL_UNSIGNED_BYTE;
                        normalize = true;
                        size = 2;
                        break;
                    case QRhiVertexInputAttribute::UNormByte:
                        type = GL_UNSIGNED_BYTE;
                        normalize = true;
                        size = 1;
                        break;
                    default:
                        break;
                    }

                    const int locationIdx = it->location();
                    quint32 ofs = it->offset() + cmd.args.bindVertexBuffer.offset;
                    f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride,
                                             reinterpret_cast<const GLvoid *>(quintptr(ofs)));
                    f->glEnableVertexAttribArray(GLuint(locationIdx));
                    if (inputBinding->classification() == QRhiVertexInputBinding::PerInstance && caps.instancing)
                        f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(inputBinding->instanceStepRate()));
                }
            } else {
                qWarning("No graphics pipeline active for setVertexInput; ignored");
            }
        }
            break;
        case QGles2CommandBuffer::Command::BindIndexBuffer:
            indexType = cmd.args.bindIndexBuffer.type;
            indexStride = indexType == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32);
            indexOffset = cmd.args.bindIndexBuffer.offset;
            f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cmd.args.bindIndexBuffer.buffer);
            break;
        case QGles2CommandBuffer::Command::Draw:
        {
            QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.draw.ps);
            if (psD) {
                if (cmd.args.draw.instanceCount == 1 || !caps.instancing) {
                    f->glDrawArrays(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount));
                } else {
                    f->glDrawArraysInstanced(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount),
                                             GLsizei(cmd.args.draw.instanceCount));
                }
            } else {
                qWarning("No graphics pipeline active for draw; ignored");
            }
        }
            break;
        case QGles2CommandBuffer::Command::DrawIndexed:
        {
            QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.drawIndexed.ps);
            if (psD) {
                const GLvoid *ofs = reinterpret_cast<const GLvoid *>(
                            quintptr(cmd.args.drawIndexed.firstIndex * indexStride + indexOffset));
                if (cmd.args.drawIndexed.instanceCount == 1 || !caps.instancing) {
                    if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
                        f->glDrawElementsBaseVertex(psD->drawMode,
                                                    GLsizei(cmd.args.drawIndexed.indexCount),
                                                    indexType,
                                                    ofs,
                                                    cmd.args.drawIndexed.baseVertex);
                    } else {
                        f->glDrawElements(psD->drawMode,
                                          GLsizei(cmd.args.drawIndexed.indexCount),
                                          indexType,
                                          ofs);
                    }
                } else {
                    if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
                        f->glDrawElementsInstancedBaseVertex(psD->drawMode,
                                                             GLsizei(cmd.args.drawIndexed.indexCount),
                                                             indexType,
                                                             ofs,
                                                             GLsizei(cmd.args.drawIndexed.instanceCount),
                                                             cmd.args.drawIndexed.baseVertex);
                    } else {
                        f->glDrawElementsInstanced(psD->drawMode,
                                                   GLsizei(cmd.args.drawIndexed.indexCount),
                                                   indexType,
                                                   ofs,
                                                   GLsizei(cmd.args.drawIndexed.instanceCount));
                    }
                }
            } else {
                qWarning("No graphics pipeline active for drawIndexed; ignored");
            }
        }
            break;
        case QGles2CommandBuffer::Command::BindGraphicsPipeline:
            executeBindGraphicsPipeline(cmd.args.bindGraphicsPipeline.ps);
            break;
        case QGles2CommandBuffer::Command::BindShaderResources:
            bindShaderResources(cmd.args.bindShaderResources.maybeGraphicsPs,
                                cmd.args.bindShaderResources.maybeComputePs,
                                cmd.args.bindShaderResources.srb,
                                cmd.args.bindShaderResources.dynamicOffsetPairs,
                                cmd.args.bindShaderResources.dynamicOffsetCount);
            break;
        case QGles2CommandBuffer::Command::BindFramebuffer:
            if (cmd.args.bindFramebuffer.fbo) {
                f->glBindFramebuffer(GL_FRAMEBUFFER, cmd.args.bindFramebuffer.fbo);
                if (caps.maxDrawBuffers > 1) {
                    const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount;
                    QVarLengthArray<GLenum, 8> bufs;
                    for (int i = 0; i < colorAttCount; ++i)
                        bufs.append(GL_COLOR_ATTACHMENT0 + uint(i));
                    f->glDrawBuffers(colorAttCount, bufs.constData());
                }
            } else {
                f->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
                if (caps.maxDrawBuffers > 1) {
                    GLenum bufs = GL_BACK;
                    f->glDrawBuffers(1, &bufs);
                }
            }
            if (caps.srgbCapableDefaultFramebuffer) {
                if (cmd.args.bindFramebuffer.srgb)
                    f->glEnable(GL_FRAMEBUFFER_SRGB);
                else
                    f->glDisable(GL_FRAMEBUFFER_SRGB);
            }
            break;
        case QGles2CommandBuffer::Command::Clear:
            f->glDisable(GL_SCISSOR_TEST);
            if (cmd.args.clear.mask & GL_COLOR_BUFFER_BIT) {
                f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
                f->glClearColor(cmd.args.clear.c[0], cmd.args.clear.c[1], cmd.args.clear.c[2], cmd.args.clear.c[3]);
            }
            if (cmd.args.clear.mask & GL_DEPTH_BUFFER_BIT) {
                f->glDepthMask(GL_TRUE);
                f->glClearDepthf(cmd.args.clear.d);
            }
            if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT)
                f->glClearStencil(GLint(cmd.args.clear.s));
            f->glClear(cmd.args.clear.mask);
            break;
        case QGles2CommandBuffer::Command::BufferSubData:
            f->glBindBuffer(cmd.args.bufferSubData.target, cmd.args.bufferSubData.buffer);
            f->glBufferSubData(cmd.args.bufferSubData.target, cmd.args.bufferSubData.offset, cmd.args.bufferSubData.size,
                               cmd.args.bufferSubData.data);
            break;
        case QGles2CommandBuffer::Command::GetBufferSubData:
        {
            QRhiBufferReadbackResult *result = cmd.args.getBufferSubData.result;
            f->glBindBuffer(cmd.args.getBufferSubData.target, cmd.args.getBufferSubData.buffer);
            if (caps.gles) {
                if (caps.properMapBuffer) {
                    void *p = f->glMapBufferRange(cmd.args.getBufferSubData.target,
                                                  cmd.args.getBufferSubData.offset,
                                                  cmd.args.getBufferSubData.size,
                                                  GL_MAP_READ_BIT);
                    if (p) {
                        result->data.resize(cmd.args.getBufferSubData.size);
                        memcpy(result->data.data(), p, size_t(cmd.args.getBufferSubData.size));
                        f->glUnmapBuffer(cmd.args.getBufferSubData.target);
                    }
                }
            } else {
                result->data.resize(cmd.args.getBufferSubData.size);
                f->glGetBufferSubData(cmd.args.getBufferSubData.target,
                                      cmd.args.getBufferSubData.offset,
                                      cmd.args.getBufferSubData.size,
                                      result->data.data());
            }
            if (result->completed)
                result->completed();
        }
            break;
        case QGles2CommandBuffer::Command::CopyTex:
        {
            GLuint fbo;
            f->glGenFramebuffers(1, &fbo);
            f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                      cmd.args.copyTex.srcFaceTarget, cmd.args.copyTex.srcTexture, cmd.args.copyTex.srcLevel);
            f->glBindTexture(cmd.args.copyTex.dstTarget, cmd.args.copyTex.dstTexture);
            f->glCopyTexSubImage2D(cmd.args.copyTex.dstFaceTarget, cmd.args.copyTex.dstLevel,
                                   cmd.args.copyTex.dstX, cmd.args.copyTex.dstY,
                                   cmd.args.copyTex.srcX, cmd.args.copyTex.srcY,
                                   cmd.args.copyTex.w, cmd.args.copyTex.h);
            f->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
            f->glDeleteFramebuffers(1, &fbo);
        }
            break;
        case QGles2CommandBuffer::Command::ReadPixels:
        {
            QRhiReadbackResult *result = cmd.args.readPixels.result;
            GLuint tex = cmd.args.readPixels.texture;
            GLuint fbo = 0;
            int mipLevel = 0;
            if (tex) {
                result->pixelSize = QSize(cmd.args.readPixels.w, cmd.args.readPixels.h);
                result->format = cmd.args.readPixels.format;
                mipLevel = cmd.args.readPixels.level;
                if (mipLevel == 0 || caps.nonBaseLevelFramebufferTexture) {
                    f->glGenFramebuffers(1, &fbo);
                    f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
                    f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                              cmd.args.readPixels.readTarget, cmd.args.readPixels.texture, mipLevel);
                }
            } else {
                result->pixelSize = currentSwapChain->pixelSize;
                result->format = QRhiTexture::RGBA8;
                // readPixels handles multisample resolving implicitly
            }
            result->data.resize(result->pixelSize.width() * result->pixelSize.height() * 4);
            if (mipLevel == 0 || caps.nonBaseLevelFramebufferTexture) {
                // With GLES (2.0?) GL_RGBA is the only mandated readback format, so stick with it.
                f->glReadPixels(0, 0, result->pixelSize.width(), result->pixelSize.height(),
                                GL_RGBA, GL_UNSIGNED_BYTE,
                                result->data.data());
            } else {
                result->data.fill('\0');
            }
            if (fbo) {
                f->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
                f->glDeleteFramebuffers(1, &fbo);
            }
            if (result->completed)
                result->completed();
        }
            break;
        case QGles2CommandBuffer::Command::SubImage:
            f->glBindTexture(cmd.args.subImage.target, cmd.args.subImage.texture);
            if (cmd.args.subImage.rowStartAlign != 4)
                f->glPixelStorei(GL_UNPACK_ALIGNMENT, cmd.args.subImage.rowStartAlign);
            f->glTexSubImage2D(cmd.args.subImage.faceTarget, cmd.args.subImage.level,
                               cmd.args.subImage.dx, cmd.args.subImage.dy,
                               cmd.args.subImage.w, cmd.args.subImage.h,
                               cmd.args.subImage.glformat, cmd.args.subImage.gltype,
                               cmd.args.subImage.data);
            if (cmd.args.subImage.rowStartAlign != 4)
                f->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
            break;
        case QGles2CommandBuffer::Command::CompressedImage:
            f->glBindTexture(cmd.args.compressedImage.target, cmd.args.compressedImage.texture);
            f->glCompressedTexImage2D(cmd.args.compressedImage.faceTarget, cmd.args.compressedImage.level,
                                      cmd.args.compressedImage.glintformat,
                                      cmd.args.compressedImage.w, cmd.args.compressedImage.h, 0,
                                      cmd.args.compressedImage.size, cmd.args.compressedImage.data);
            break;
        case QGles2CommandBuffer::Command::CompressedSubImage:
            f->glBindTexture(cmd.args.compressedSubImage.target, cmd.args.compressedSubImage.texture);
            f->glCompressedTexSubImage2D(cmd.args.compressedSubImage.faceTarget, cmd.args.compressedSubImage.level,
                                         cmd.args.compressedSubImage.dx, cmd.args.compressedSubImage.dy,
                                         cmd.args.compressedSubImage.w, cmd.args.compressedSubImage.h,
                                         cmd.args.compressedSubImage.glintformat,
                                         cmd.args.compressedSubImage.size, cmd.args.compressedSubImage.data);
            break;
        case QGles2CommandBuffer::Command::BlitFromRenderbuffer:
        {
            GLuint fbo[2];
            f->glGenFramebuffers(2, fbo);
            f->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[0]);
            f->glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                         GL_RENDERBUFFER, cmd.args.blitFromRb.renderbuffer);
            f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);

            f->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cmd.args.blitFromRb.target,
                                      cmd.args.blitFromRb.texture, cmd.args.blitFromRb.dstLevel);
            f->glBlitFramebuffer(0, 0, cmd.args.blitFromRb.w, cmd.args.blitFromRb.h,
                                 0, 0, cmd.args.blitFromRb.w, cmd.args.blitFromRb.h,
                                 GL_COLOR_BUFFER_BIT,
                                 GL_LINEAR);
            f->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
        }
            break;
        case QGles2CommandBuffer::Command::GenMip:
            f->glBindTexture(cmd.args.genMip.target, cmd.args.genMip.texture);
            f->glGenerateMipmap(cmd.args.genMip.target);
            break;
        case QGles2CommandBuffer::Command::BindComputePipeline:
        {
            QGles2ComputePipeline *psD = QRHI_RES(QGles2ComputePipeline, cmd.args.bindComputePipeline.ps);
            f->glUseProgram(psD->program);
        }
            break;
        case QGles2CommandBuffer::Command::Dispatch:
            f->glDispatchCompute(cmd.args.dispatch.x, cmd.args.dispatch.y, cmd.args.dispatch.z);
            break;
        case QGles2CommandBuffer::Command::BarriersForPass:
        {
            GLbitfield barriers = 0;
            QRhiPassResourceTracker &tracker(cbD->passResTrackers[cmd.args.barriersForPass.trackerIndex]);
            // we only care about after-write, not any other accesses, and
            // cannot tell if something was written in a shader several passes
            // ago: now the previously written resource may be used with an
            // access that was not in the previous passes, result in a missing
            // barrier in theory. Hence setting all barrier bits whenever
            // something previously written is used for the first time in a
            // subsequent pass.
            for (auto it = tracker.cbeginBuffers(), itEnd = tracker.cendBuffers(); it != itEnd; ++it) {
                QGles2Buffer::Access accessBeforePass = QGles2Buffer::Access(it->stateAtPassBegin.access);
                if (accessBeforePass == QGles2Buffer::AccessStorageWrite
                        || accessBeforePass == QGles2Buffer::AccessStorageReadWrite)
                {
                    barriers |= GL_ALL_BARRIER_BITS;
                }
            }
            for (auto it = tracker.cbeginTextures(), itEnd = tracker.cendTextures(); it != itEnd; ++it) {
                QGles2Texture::Access accessBeforePass = QGles2Texture::Access(it->stateAtPassBegin.access);
                if (accessBeforePass == QGles2Texture::AccessStorageWrite
                        || accessBeforePass == QGles2Texture::AccessStorageReadWrite)
                {
                    barriers |= GL_ALL_BARRIER_BITS;
                }
            }
            if (barriers)
                f->glMemoryBarrier(barriers);
        }
            break;
        case QGles2CommandBuffer::Command::Barrier:
            f->glMemoryBarrier(cmd.args.barrier.barriers);
            break;
        default:
            break;
        }
    }
}

void QRhiGles2::executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps)
{
    QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, ps);

    // No state tracking logic as of now. Could introduce something to reduce
    // the number of gl* calls (when using and changing between multiple
    // pipelines), but then begin/endExternal() should invalidate the cached
    // state as appropriate.

    if (psD->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor))
        f->glEnable(GL_SCISSOR_TEST);
    else
        f->glDisable(GL_SCISSOR_TEST);
    if (psD->m_cullMode == QRhiGraphicsPipeline::None) {
        f->glDisable(GL_CULL_FACE);
    } else {
        f->glEnable(GL_CULL_FACE);
        f->glCullFace(toGlCullMode(psD->m_cullMode));
    }
    f->glFrontFace(toGlFrontFace(psD->m_frontFace));
    if (!psD->m_targetBlends.isEmpty()) {
        const QRhiGraphicsPipeline::TargetBlend &blend(psD->m_targetBlends.first()); // no MRT
        GLboolean wr = blend.colorWrite.testFlag(QRhiGraphicsPipeline::R);
        GLboolean wg = blend.colorWrite.testFlag(QRhiGraphicsPipeline::G);
        GLboolean wb = blend.colorWrite.testFlag(QRhiGraphicsPipeline::B);
        GLboolean wa = blend.colorWrite.testFlag(QRhiGraphicsPipeline::A);
        f->glColorMask(wr, wg, wb, wa);
        if (blend.enable) {
            f->glEnable(GL_BLEND);
            f->glBlendFuncSeparate(toGlBlendFactor(blend.srcColor),
                                   toGlBlendFactor(blend.dstColor),
                                   toGlBlendFactor(blend.srcAlpha),
                                   toGlBlendFactor(blend.dstAlpha));
            f->glBlendEquationSeparate(toGlBlendOp(blend.opColor), toGlBlendOp(blend.opAlpha));
        } else {
            f->glDisable(GL_BLEND);
        }
    } else {
        f->glDisable(GL_BLEND);
        f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    }
    if (psD->m_depthTest)
        f->glEnable(GL_DEPTH_TEST);
    else
        f->glDisable(GL_DEPTH_TEST);
    if (psD->m_depthWrite)
        f->glDepthMask(GL_TRUE);
    else
        f->glDepthMask(GL_FALSE);
    f->glDepthFunc(toGlCompareOp(psD->m_depthOp));
    if (psD->m_stencilTest) {
        f->glEnable(GL_STENCIL_TEST);
        f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), 0, psD->m_stencilReadMask);
        f->glStencilOpSeparate(GL_FRONT,
                               toGlStencilOp(psD->m_stencilFront.failOp),
                               toGlStencilOp(psD->m_stencilFront.depthFailOp),
                               toGlStencilOp(psD->m_stencilFront.passOp));
        f->glStencilMaskSeparate(GL_FRONT, psD->m_stencilWriteMask);
        f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), 0, psD->m_stencilReadMask);
        f->glStencilOpSeparate(GL_BACK,
                               toGlStencilOp(psD->m_stencilBack.failOp),
                               toGlStencilOp(psD->m_stencilBack.depthFailOp),
                               toGlStencilOp(psD->m_stencilBack.passOp));
        f->glStencilMaskSeparate(GL_BACK, psD->m_stencilWriteMask);
    } else {
        f->glDisable(GL_STENCIL_TEST);
    }

    if (psD->topology() == QRhiGraphicsPipeline::Lines || psD->topology() == QRhiGraphicsPipeline::LineStrip)
        f->glLineWidth(psD->m_lineWidth);

    f->glUseProgram(psD->program);
}

void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiComputePipeline *maybeComputePs,
                                    QRhiShaderResourceBindings *srb,
                                    const uint *dynOfsPairs, int dynOfsCount)
{
    QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb);
    int texUnit = 0;

    for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
        const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data();

        switch (b->type) {
        case QRhiShaderResourceBinding::UniformBuffer:
        {
            int viewOffset = b->u.ubuf.offset;
            if (dynOfsCount) {
                for (int j = 0; j < dynOfsCount; ++j) {
                    if (dynOfsPairs[2 * j] == uint(b->binding)) {
                        viewOffset = int(dynOfsPairs[2 * j + 1]);
                        break;
                    }
                }
            }
            QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.ubuf.buf);
            const QByteArray bufView = QByteArray::fromRawData(bufD->ubuf.constData() + viewOffset,
                                                               b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size);
            QVector<QGles2UniformDescription> &uniforms(maybeGraphicsPs ? QRHI_RES(QGles2GraphicsPipeline, maybeGraphicsPs)->uniforms
                                                                        : QRHI_RES(QGles2ComputePipeline, maybeComputePs)->uniforms);
            for (QGles2UniformDescription &uniform : uniforms) {
                if (uniform.binding == b->binding) {
                    // in a uniform buffer everything is at least 4 byte aligned
                    // so this should not cause unaligned reads
                    const void *src = bufView.constData() + uniform.offset;

                    switch (uniform.type) {
                    case QShaderDescription::Float:
                        f->glUniform1f(uniform.glslLocation, *reinterpret_cast<const float *>(src));
                        break;
                    case QShaderDescription::Vec2:
                        f->glUniform2fv(uniform.glslLocation, 1, reinterpret_cast<const float *>(src));
                        break;
                    case QShaderDescription::Vec3:
                        f->glUniform3fv(uniform.glslLocation, 1, reinterpret_cast<const float *>(src));
                        break;
                    case QShaderDescription::Vec4:
                        f->glUniform4fv(uniform.glslLocation, 1, reinterpret_cast<const float *>(src));
                        break;
                    case QShaderDescription::Mat2:
                        f->glUniformMatrix2fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src));
                        break;
                    case QShaderDescription::Mat3:
                        f->glUniformMatrix3fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src));
                        break;
                    case QShaderDescription::Mat4:
                        f->glUniformMatrix4fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src));
                        break;
                    case QShaderDescription::Int:
                        f->glUniform1i(uniform.glslLocation, *reinterpret_cast<const qint32 *>(src));
                        break;
                    case QShaderDescription::Int2:
                        f->glUniform2iv(uniform.glslLocation, 1, reinterpret_cast<const qint32 *>(src));
                        break;
                    case QShaderDescription::Int3:
                        f->glUniform3iv(uniform.glslLocation, 1, reinterpret_cast<const qint32 *>(src));
                        break;
                    case QShaderDescription::Int4:
                        f->glUniform4iv(uniform.glslLocation, 1, reinterpret_cast<const qint32 *>(src));
                        break;
                    case QShaderDescription::Uint:
                        f->glUniform1ui(uniform.glslLocation, *reinterpret_cast<const quint32 *>(src));
                        break;
                    case QShaderDescription::Uint2:
                        f->glUniform2uiv(uniform.glslLocation, 1, reinterpret_cast<const quint32 *>(src));
                        break;
                    case QShaderDescription::Uint3:
                        f->glUniform3uiv(uniform.glslLocation, 1, reinterpret_cast<const quint32 *>(src));
                        break;
                    case QShaderDescription::Uint4:
                        f->glUniform4uiv(uniform.glslLocation, 1, reinterpret_cast<const quint32 *>(src));
                        break;
                    case QShaderDescription::Bool: // a glsl bool is 4 bytes, like (u)int
                        f->glUniform1i(uniform.glslLocation, *reinterpret_cast<const qint32 *>(src));
                        break;
                    case QShaderDescription::Bool2:
                        f->glUniform2iv(uniform.glslLocation, 1, reinterpret_cast<const qint32 *>(src));
                        break;
                    case QShaderDescription::Bool3:
                        f->glUniform3iv(uniform.glslLocation, 1, reinterpret_cast<const qint32 *>(src));
                        break;
                    case QShaderDescription::Bool4:
                        f->glUniform4iv(uniform.glslLocation, 1, reinterpret_cast<const qint32 *>(src));
                        break;
                    // ### more types
                    default:
                        break;
                    }
                }
            }
        }
            break;
        case QRhiShaderResourceBinding::SampledTexture:
        {
            QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.stex.tex);
            QGles2Sampler *samplerD = QRHI_RES(QGles2Sampler, b->u.stex.sampler);
            QVector<QGles2SamplerDescription> &samplers(maybeGraphicsPs ? QRHI_RES(QGles2GraphicsPipeline, maybeGraphicsPs)->samplers
                                                                        : QRHI_RES(QGles2ComputePipeline, maybeComputePs)->samplers);

            for (QGles2SamplerDescription &sampler : samplers) {
                if (sampler.binding == b->binding) {
                    f->glActiveTexture(GL_TEXTURE0 + uint(texUnit));
                    f->glBindTexture(texD->target, texD->texture);

                    if (texD->samplerState != samplerD->d) {
                        f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, GLint(samplerD->d.glminfilter));
                        f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, GLint(samplerD->d.glmagfilter));
                        f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, GLint(samplerD->d.glwraps));
                        f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, GLint(samplerD->d.glwrapt));
                        // 3D textures not supported by GLES 2.0 or by us atm...
                        //f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_R, samplerD->d.glwrapr);
                        if (caps.textureCompareMode) {
                            if (samplerD->d.gltexcomparefunc != GL_NEVER) {
                                f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
                                f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, GLint(samplerD->d.gltexcomparefunc));
                            } else {
                                f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
                            }
                        }
                        texD->samplerState = samplerD->d;
                    }

                    f->glUniform1i(sampler.glslLocation, texUnit);
                    ++texUnit;
                }
            }
        }
            break;
        case QRhiShaderResourceBinding::ImageLoad:
            Q_FALLTHROUGH();
        case QRhiShaderResourceBinding::ImageStore:
            Q_FALLTHROUGH();
        case QRhiShaderResourceBinding::ImageLoadStore:
        {
            QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex);
            const bool layered = texD->m_flags.testFlag(QRhiTexture::CubeMap);
            GLenum access = GL_READ_WRITE;
            if (b->type == QRhiShaderResourceBinding::ImageLoad)
                access = GL_READ_ONLY;
            else if (b->type == QRhiShaderResourceBinding::ImageStore)
                access = GL_WRITE_ONLY;
            f->glBindImageTexture(GLuint(b->binding), texD->texture,
                                  b->u.simage.level, layered, 0,
                                  access, texD->glsizedintformat);
        }
            break;
        case QRhiShaderResourceBinding::BufferLoad:
            Q_FALLTHROUGH();
        case QRhiShaderResourceBinding::BufferStore:
            Q_FALLTHROUGH();
        case QRhiShaderResourceBinding::BufferLoadStore:
        {
            QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
            if (b->u.sbuf.offset == 0 && b->u.sbuf.maybeSize == 0)
                f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer);
            else
                f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer,
                                     b->u.sbuf.offset, b->u.sbuf.maybeSize ? b->u.sbuf.maybeSize : bufD->m_size);
        }
            break;
        default:
            Q_UNREACHABLE();
            break;
        }
    }

    if (texUnit > 1)
        f->glActiveTexture(GL_TEXTURE0);
}

void QRhiGles2::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
{
    Q_ASSERT(QRHI_RES(QGles2CommandBuffer, cb)->recordingPass == QGles2CommandBuffer::NoPass);

    enqueueResourceUpdates(cb, resourceUpdates);
}

QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt, QGles2CommandBuffer *cbD,
                                                          bool *wantsColorClear, bool *wantsDsClear)
{
    QGles2RenderTargetData *rtD = nullptr;
    QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);

    QGles2CommandBuffer::Command fbCmd;
    fbCmd.cmd = QGles2CommandBuffer::Command::BindFramebuffer;

    switch (rt->resourceType()) {
    case QRhiResource::RenderTarget:
        rtD = &QRHI_RES(QGles2ReferenceRenderTarget, rt)->d;
        if (wantsColorClear)
            *wantsColorClear = true;
        if (wantsDsClear)
            *wantsDsClear = true;
        fbCmd.args.bindFramebuffer.fbo = 0;
        fbCmd.args.bindFramebuffer.colorAttCount = 1;
        break;
    case QRhiResource::TextureRenderTarget:
    {
        QGles2TextureRenderTarget *rtTex = QRHI_RES(QGles2TextureRenderTarget, rt);
        rtD = &rtTex->d;
        if (wantsColorClear)
            *wantsColorClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents);
        if (wantsDsClear)
            *wantsDsClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents);
        fbCmd.args.bindFramebuffer.fbo = rtTex->framebuffer;
        fbCmd.args.bindFramebuffer.colorAttCount = rtD->colorAttCount;

        for (auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments();
             it != itEnd; ++it)
        {
            const QRhiColorAttachment &colorAtt(*it);
            QGles2Texture *texD = QRHI_RES(QGles2Texture, colorAtt.texture());
            QGles2Texture *resolveTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
            if (texD) {
                trackedRegisterTexture(&passResTracker, texD,
                                       QRhiPassResourceTracker::TexColorOutput,
                                       QRhiPassResourceTracker::TexColorOutputStage);
            }
            if (resolveTexD) {
                trackedRegisterTexture(&passResTracker, resolveTexD,
                                       QRhiPassResourceTracker::TexColorOutput,
                                       QRhiPassResourceTracker::TexColorOutputStage);
            }
            // renderbuffers cannot be written in shaders (no image store) so
            // they do not matter here
        }
        if (rtTex->m_desc.depthTexture()) {
            trackedRegisterTexture(&passResTracker, QRHI_RES(QGles2Texture, rtTex->m_desc.depthTexture()),
                                   QRhiPassResourceTracker::TexDepthOutput,
                                   QRhiPassResourceTracker::TexDepthOutputStage);
        }
    }
        break;
    default:
        Q_UNREACHABLE();
        break;
    }

    fbCmd.args.bindFramebuffer.srgb = rtD->srgbUpdateAndBlend;
    cbD->commands.append(fbCmd);

    return rtD;
}

void QRhiGles2::enqueueBarriersForPass(QGles2CommandBuffer *cbD)
{
    cbD->passResTrackers.append(QRhiPassResourceTracker());
    cbD->currentPassResTrackerIndex = cbD->passResTrackers.count() - 1;
    QGles2CommandBuffer::Command cmd;
    cmd.cmd = QGles2CommandBuffer::Command::BarriersForPass;
    cmd.args.barriersForPass.trackerIndex = cbD->currentPassResTrackerIndex;
    cbD->commands.append(cmd);
}

void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
                          QRhiRenderTarget *rt,
                          const QColor &colorClearValue,
                          const QRhiDepthStencilClearValue &depthStencilClearValue,
                          QRhiResourceUpdateBatch *resourceUpdates)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::NoPass);

    if (resourceUpdates)
        enqueueResourceUpdates(cb, resourceUpdates);

    // Get a new resource tracker. Then add a command that will generate
    // glMemoryBarrier() calls based on that tracker when submitted.
    enqueueBarriersForPass(cbD);

    bool wantsColorClear, wantsDsClear;
    QGles2RenderTargetData *rtD = enqueueBindFramebuffer(rt, cbD, &wantsColorClear, &wantsDsClear);

    QGles2CommandBuffer::Command clearCmd;
    clearCmd.cmd = QGles2CommandBuffer::Command::Clear;
    clearCmd.args.clear.mask = 0;
    if (rtD->colorAttCount && wantsColorClear)
        clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
    if (rtD->dsAttCount && wantsDsClear)
        clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
    clearCmd.args.clear.c[0] = float(colorClearValue.redF());
    clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
    clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
    clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
    clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
    clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
    cbD->commands.append(clearCmd);

    cbD->recordingPass = QGles2CommandBuffer::RenderPass;
    cbD->currentTarget = rt;

    cbD->resetCachedState();
}

void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass);

    if (cbD->currentTarget->resourceType() == QRhiResource::TextureRenderTarget) {
        QGles2TextureRenderTarget *rtTex = QRHI_RES(QGles2TextureRenderTarget, cbD->currentTarget);
        if (rtTex->m_desc.cbeginColorAttachments() != rtTex->m_desc.cendColorAttachments()) {
            // handle only 1 color attachment and only (msaa) renderbuffer
            const QRhiColorAttachment &colorAtt(*rtTex->m_desc.cbeginColorAttachments());
            if (colorAtt.resolveTexture()) {
                Q_ASSERT(colorAtt.renderBuffer());
                QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, colorAtt.renderBuffer());
                const QSize size = colorAtt.resolveTexture()->pixelSize();
                if (rbD->pixelSize() != size) {
                    qWarning("Resolve source (%dx%d) and target (%dx%d) size does not match",
                             rbD->pixelSize().width(), rbD->pixelSize().height(), size.width(), size.height());
                }
                QGles2CommandBuffer::Command cmd;
                cmd.cmd = QGles2CommandBuffer::Command::BlitFromRenderbuffer;
                cmd.args.blitFromRb.renderbuffer = rbD->renderbuffer;
                cmd.args.blitFromRb.w = size.width();
                cmd.args.blitFromRb.h = size.height();
                QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
                const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X
                                                                                                : colorTexD->target;
                cmd.args.blitFromRb.target = faceTargetBase + uint(colorAtt.resolveLayer());
                cmd.args.blitFromRb.texture = colorTexD->texture;
                cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel();
                cbD->commands.append(cmd);
            }
        }
    }

    cbD->recordingPass = QGles2CommandBuffer::NoPass;
    cbD->currentTarget = nullptr;

    if (resourceUpdates)
        enqueueResourceUpdates(cb, resourceUpdates);
}

void QRhiGles2::beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::NoPass);

    if (resourceUpdates)
        enqueueResourceUpdates(cb, resourceUpdates);

    enqueueBarriersForPass(cbD);

    cbD->recordingPass = QGles2CommandBuffer::ComputePass;

    cbD->resetCachedState();
}

void QRhiGles2::endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::ComputePass);

    cbD->recordingPass = QGles2CommandBuffer::NoPass;

    if (resourceUpdates)
        enqueueResourceUpdates(cb, resourceUpdates);
}

void QRhiGles2::setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::ComputePass);
    QGles2ComputePipeline *psD = QRHI_RES(QGles2ComputePipeline, ps);
    const bool pipelineChanged = cbD->currentComputePipeline != ps || cbD->currentPipelineGeneration != psD->generation;

    if (pipelineChanged) {
        cbD->currentGraphicsPipeline = nullptr;
        cbD->currentComputePipeline = ps;
        cbD->currentPipelineGeneration = psD->generation;

        QGles2CommandBuffer::Command cmd;
        cmd.cmd = QGles2CommandBuffer::Command::BindComputePipeline;
        cmd.args.bindComputePipeline.ps = ps;
        cbD->commands.append(cmd);
    }
}

void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
{
    QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
    Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::ComputePass);

    QGles2CommandBuffer::Command cmd;
    cmd.cmd = QGles2CommandBuffer::Command::Dispatch;
    cmd.args.dispatch.x = GLuint(x);
    cmd.args.dispatch.y = GLuint(y);
    cmd.args.dispatch.z = GLuint(z);
    cbD->commands.append(cmd);
}

static inline GLenum toGlShaderType(QRhiShaderStage::Type type)
{
    switch (type) {
    case QRhiShaderStage::Vertex:
        return GL_VERTEX_SHADER;
    case QRhiShaderStage::Fragment:
        return GL_FRAGMENT_SHADER;
    case QRhiShaderStage::Compute:
        return GL_COMPUTE_SHADER;
    default:
        Q_UNREACHABLE();
        return GL_VERTEX_SHADER;
    }
}

QByteArray QRhiGles2::shaderSource(const QRhiShaderStage &shaderStage, int *glslVersion)
{
    const QShader bakedShader = shaderStage.shader();
    QVector<int> versionsToTry;
    QByteArray source;
    if (caps.gles) {
        if (caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 2)) {
            versionsToTry << 320 << 310 << 300 << 100;
        } else if (caps.ctxMajor == 3 && caps.ctxMinor == 1) {
            versionsToTry << 310 << 300 << 100;
        } else if (caps.ctxMajor == 3 && caps.ctxMinor == 0) {
            versionsToTry << 300 << 100;
        } else {
            versionsToTry << 100;
        }
        for (int v : versionsToTry) {
            QShaderVersion ver(v, QShaderVersion::GlslEs);
            source = bakedShader.shader({ QShader::GlslShader, ver, shaderStage.shaderVariant() }).shader();
            if (!source.isEmpty()) {
                if (glslVersion)
                    *glslVersion = v;
                break;
            }
        }
    } else {
        if (caps.ctxMajor > 4 || (caps.ctxMajor == 4 && caps.ctxMinor >= 6)) {
            versionsToTry << 460 << 450 << 440 << 430 << 420 << 410 << 400 << 330 << 150;
        } else if (caps.ctxMajor == 4 && caps.ctxMinor == 5) {
            versionsToTry << 450 << 440 << 430 << 420 << 410 << 400 << 330 << 150;
        } else if (caps.ctxMajor == 4 && caps.ctxMinor == 4) {
            versionsToTry << 440 << 430 << 420 << 410 << 400 << 330 << 150;
        } else if (caps.ctxMajor == 4 && caps.ctxMinor == 3) {
            versionsToTry << 430 << 420 << 410 << 400 << 330 << 150;
        } else if (caps.ctxMajor == 4 && caps.ctxMinor == 2) {
            versionsToTry << 420 << 410 << 400 << 330 << 150;
        } else if (caps.ctxMajor == 4 && caps.ctxMinor == 1) {
            versionsToTry << 410 << 400 << 330 << 150;
        } else if (caps.ctxMajor == 4 && caps.ctxMinor == 0) {
            versionsToTry << 400 << 330 << 150;
        } else if (caps.ctxMajor == 3 && caps.ctxMinor == 3) {
            versionsToTry << 330 << 150;
        } else if (caps.ctxMajor == 3 && caps.ctxMinor == 2) {
            versionsToTry << 150;
        }
        if (!caps.coreProfile)
            versionsToTry << 120;
        for (int v : versionsToTry) {
            source = bakedShader.shader({ QShader::GlslShader, v, shaderStage.shaderVariant() }).shader();
            if (!source.isEmpty()) {
                if (glslVersion)
                    *glslVersion = v;
                break;
            }
        }
    }
    if (source.isEmpty()) {
        qWarning() << "No GLSL shader code found (versions tried: " << versionsToTry
                   << ") in baked shader" << bakedShader;
    }
    return source;
}

bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage, int *glslVersion)
{
    const QByteArray source = shaderSource(shaderStage, glslVersion);
    if (source.isEmpty())
        return false;

    GLuint shader;
    auto cacheIt = m_shaderCache.constFind(shaderStage);
    if (cacheIt != m_shaderCache.constEnd()) {
        shader = *cacheIt;
    } else {
        shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
        const char *srcStr = source.constData();
        const GLint srcLength = source.count();
        f->glShaderSource(shader, 1, &srcStr, &srcLength);
        f->glCompileShader(shader);
        GLint compiled = 0;
        f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        if (!compiled) {
            GLint infoLogLength = 0;
            f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
            QByteArray log;
            if (infoLogLength > 1) {
                GLsizei length = 0;
                log.resize(infoLogLength);
                f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
            }
            qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
            return false;
        }
        if (m_shaderCache.count() >= MAX_SHADER_CACHE_ENTRIES) {
            // Use the simplest strategy: too many cached shaders -> drop them all.
            for (uint shader : m_shaderCache)
                f->glDeleteShader(shader); // does not actually get released yet when attached to a not-yet-released program
            m_shaderCache.clear();
        }
        m_shaderCache.insert(shaderStage, shader);
    }

    f->glAttachShader(program, shader);

    return true;
}

bool QRhiGles2::linkProgram(GLuint program)
{
    f->glLinkProgram(program);
    GLint linked = 0;
    f->glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (!linked) {
        GLint infoLogLength = 0;
        f->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
        QByteArray log;
        if (infoLogLength > 1) {
            GLsizei length = 0;
            log.resize(infoLogLength);
            f->glGetProgramInfoLog(program, infoLogLength, &length, log.data());
        }
        qWarning("Failed to link shader program: %s", log.constData());
        return false;
    }
    return true;
}

void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub,
                               QVector<QGles2UniformDescription> *dst)
{
    const QByteArray prefix = ub.structName.toUtf8() + '.';
    for (const QShaderDescription::BlockVariable &blockMember : ub.members) {
        // ### no array support for now
        QGles2UniformDescription uniform;
        uniform.type = blockMember.type;
        const QByteArray name = prefix + blockMember.name.toUtf8();
        uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
        if (uniform.glslLocation >= 0) {
            uniform.binding = ub.binding;
            uniform.offset = uint(blockMember.offset);
            uniform.size = blockMember.size;
            dst->append(uniform);
        }
    }
}

void QRhiGles2::gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v,
                               QVector<QGles2SamplerDescription> *dst)
{
    QGles2SamplerDescription sampler;
    const QByteArray name = v.name.toUtf8();
    sampler.glslLocation = f->glGetUniformLocation(program, name.constData());
    if (sampler.glslLocation >= 0) {
        sampler.binding = v.binding;
        dst->append(sampler);
    }
}

bool QRhiGles2::isProgramBinaryDiskCacheEnabled() const
{
    static QOpenGLProgramBinarySupportCheckWrapper checker;
    return checker.get(ctx)->isSupported();
}

Q_GLOBAL_STATIC(QOpenGLProgramBinaryCache, qrhi_programBinaryCache);

static inline QShader::Stage toShaderStage(QRhiShaderStage::Type type)
{
    switch (type) {
    case QRhiShaderStage::Vertex:
        return QShader::VertexStage;
    case QRhiShaderStage::Fragment:
        return QShader::FragmentStage;
    case QRhiShaderStage::Compute:
        return QShader::ComputeStage;
    default:
        Q_UNREACHABLE();
        return QShader::VertexStage;
    }
}

QRhiGles2::DiskCacheResult QRhiGles2::tryLoadFromDiskCache(const QRhiShaderStage *stages, int stageCount,
                                                           GLuint program, QByteArray *cacheKey)
{
    QRhiGles2::DiskCacheResult result = QRhiGles2::DiskCacheMiss;
    QByteArray diskCacheKey;

    if (isProgramBinaryDiskCacheEnabled()) {
        QOpenGLProgramBinaryCache::ProgramDesc binaryProgram;
        for (int i = 0; i < stageCount; ++i) {
            const QRhiShaderStage &stage(stages[i]);
            const QByteArray source = shaderSource(stage, nullptr);
            if (source.isEmpty())
                return QRhiGles2::DiskCacheError;
            binaryProgram.shaders.append(QOpenGLProgramBinaryCache::ShaderDesc(toShaderStage(stage.type()), source));
        }

        diskCacheKey = binaryProgram.cacheKey();
        if (qrhi_programBinaryCache()->load(diskCacheKey, program)) {
            qCDebug(lcOpenGLProgramDiskCache, "Program binary received from cache, program %u, key %s",
                    program, diskCacheKey.constData());
            result = QRhiGles2::DiskCacheHit;
        }
    }

    if (cacheKey)
        *cacheKey = diskCacheKey;

    return result;
}

void QRhiGles2::trySaveToDiskCache(GLuint program, const QByteArray &cacheKey)
{
    if (isProgramBinaryDiskCacheEnabled()) {
        qCDebug(lcOpenGLProgramDiskCache, "Saving program binary, program %u, key %s",
                program, cacheKey.constData());
        qrhi_programBinaryCache()->save(cacheKey, program);
    }
}

QGles2Buffer::QGles2Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, int size)
    : QRhiBuffer(rhi, type, usage, size)
{
}

QGles2Buffer::~QGles2Buffer()
{
    release();
}

void QGles2Buffer::release()
{
    if (!buffer)
        return;

    QRhiGles2::DeferredReleaseEntry e;
    e.type = QRhiGles2::DeferredReleaseEntry::Buffer;

    e.buffer.buffer = buffer;

    buffer = 0;

    QRHI_RES_RHI(QRhiGles2);
    rhiD->releaseQueue.append(e);
    QRHI_PROF;
    QRHI_PROF_F(releaseBuffer(this));
    rhiD->unregisterResource(this);
}

bool QGles2Buffer::build()
{
    if (buffer)
        release();

    QRHI_RES_RHI(QRhiGles2);
    QRHI_PROF;

    const int nonZeroSize = m_size <= 0 ? 256 : m_size;

    if (m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
        if (int(m_usage) != QRhiBuffer::UniformBuffer) {
            qWarning("Uniform buffer: multiple usages specified, this is not supported by the OpenGL backend");
            return false;
        }
        ubuf.resize(nonZeroSize);
        QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 0, 1));
        return true;
    }

    if (!rhiD->ensureContext())
        return false;

    targetForDataOps = GL_ARRAY_BUFFER;
    if (m_usage.testFlag(QRhiBuffer::IndexBuffer))
        targetForDataOps = GL_ELEMENT_ARRAY_BUFFER;
    else if (m_usage.testFlag(QRhiBuffer::StorageBuffer))
        targetForDataOps = GL_SHADER_STORAGE_BUFFER;

    rhiD->f->glGenBuffers(1, &buffer);
    rhiD->f->glBindBuffer(targetForDataOps, buffer);
    rhiD->f->glBufferData(targetForDataOps, nonZeroSize, nullptr, m_type == Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);

    usageState.access = AccessNone;

    QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 1, 0));
    rhiD->registerResource(this);
    return true;
}

QGles2RenderBuffer::QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
                                       int sampleCount, QRhiRenderBuffer::Flags flags)
    : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags)
{
}

QGles2RenderBuffer::~QGles2RenderBuffer()
{
    release();
}

void QGles2RenderBuffer::release()
{
    if (!renderbuffer)
        return;

    QRhiGles2::DeferredReleaseEntry e;
    e.type = QRhiGles2::DeferredReleaseEntry::RenderBuffer;

    e.renderbuffer.renderbuffer = renderbuffer;
    e.renderbuffer.renderbuffer2 = stencilRenderbuffer;

    renderbuffer = 0;
    stencilRenderbuffer = 0;

    QRHI_RES_RHI(QRhiGles2);
    rhiD->releaseQueue.append(e);
    QRHI_PROF;
    QRHI_PROF_F(releaseRenderBuffer(this));
    rhiD->unregisterResource(this);
}

bool QGles2RenderBuffer::build()
{
    if (renderbuffer)
        release();

    QRHI_RES_RHI(QRhiGles2);
    QRHI_PROF;
    samples = rhiD->effectiveSampleCount(m_sampleCount);

    if (m_flags.testFlag(UsedWithSwapChainOnly)) {
        if (m_type == DepthStencil) {
            QRHI_PROF_F(newRenderBuffer(this, false, true, samples));
            return true;
        }

        qWarning("RenderBuffer: UsedWithSwapChainOnly is meaningless in combination with Color");
    }

    if (!rhiD->ensureContext())
        return false;

    rhiD->f->glGenRenderbuffers(1, &renderbuffer);
    rhiD->f->glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);

    const QSize size = m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize;

    switch (m_type) {
    case QRhiRenderBuffer::DepthStencil:
        if (rhiD->caps.msaaRenderBuffer && samples > 1) {
            rhiD->f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8,
                                                      size.width(), size.height());
            stencilRenderbuffer = 0;
        } else if (rhiD->caps.packedDepthStencil || rhiD->caps.needsDepthStencilCombinedAttach) {
            const GLenum storage = rhiD->caps.needsDepthStencilCombinedAttach ? GL_DEPTH_STENCIL : GL_DEPTH24_STENCIL8;
            rhiD->f->glRenderbufferStorage(GL_RENDERBUFFER, storage,
                                           size.width(), size.height());
            stencilRenderbuffer = 0;
        } else {
            GLenum depthStorage = GL_DEPTH_COMPONENT;
            if (rhiD->caps.gles) {
                if (rhiD->caps.depth24)
                    depthStorage = GL_DEPTH_COMPONENT24;
                else
                    depthStorage = GL_DEPTH_COMPONENT16; // plain ES 2.0 only has this
            }
            const GLenum stencilStorage = rhiD->caps.gles ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
            rhiD->f->glRenderbufferStorage(GL_RENDERBUFFER, depthStorage,
                                           size.width(), size.height());
            rhiD->f->glGenRenderbuffers(1, &stencilRenderbuffer);
            rhiD->f->glBindRenderbuffer(GL_RENDERBUFFER, stencilRenderbuffer);
            rhiD->f->glRenderbufferStorage(GL_RENDERBUFFER, stencilStorage,
                                           size.width(), size.height());
        }
        QRHI_PROF_F(newRenderBuffer(this, false, false, samples));
        break;
    case QRhiRenderBuffer::Color:
        if (rhiD->caps.msaaRenderBuffer && samples > 1)
            rhiD->f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8,
                                                      size.width(), size.height());
        else
            rhiD->f->glRenderbufferStorage(GL_RENDERBUFFER, rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA4,
                                           size.width(), size.height());
        QRHI_PROF_F(newRenderBuffer(this, false, false, samples));
        break;
    default:
        Q_UNREACHABLE();
        break;
    }

    rhiD->registerResource(this);
    return true;
}

QRhiTexture::Format QGles2RenderBuffer::backingFormat() const
{
    return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat;
}

QGles2Texture::QGles2Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize,
                             int sampleCount, Flags flags)
    : QRhiTexture(rhi, format, pixelSize, sampleCount, flags)
{
}

QGles2Texture::~QGles2Texture()
{
    release();
}

void QGles2Texture::release()
{
    if (!texture)
        return;

    QRhiGles2::DeferredReleaseEntry e;
    e.type = QRhiGles2::DeferredReleaseEntry::Texture;

    e.texture.texture = texture;

    texture = 0;
    specified = false;
    nativeHandlesStruct.texture = 0;

    QRHI_RES_RHI(QRhiGles2);
    if (owns)
        rhiD->releaseQueue.append(e);
    QRHI_PROF;
    QRHI_PROF_F(releaseTexture(this));
    rhiD->unregisterResource(this);
}

bool QGles2Texture::prepareBuild(QSize *adjustedSize)
{
    if (texture)
        release();

    QRHI_RES_RHI(QRhiGles2);
    if (!rhiD->ensureContext())
        return false;

    const QSize size = m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize;

    const bool isCube = m_flags.testFlag(CubeMap);
    const bool hasMipMaps = m_flags.testFlag(MipMapped);
    const bool isCompressed = rhiD->isCompressedFormat(m_format);

    target = isCube ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
    mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
    gltype = GL_UNSIGNED_BYTE;

    if (isCompressed) {
        if (m_flags.testFlag(UsedWithLoadStore)) {
            qWarning("Compressed texture cannot be used with image load/store");
            return false;
        }
        glintformat = toGlCompressedTextureFormat(m_format, m_flags);
        if (!glintformat) {
            qWarning("Compressed format %d not mappable to GL compressed format", m_format);
            return false;
        }
        glsizedintformat = glintformat;
        glformat = GL_RGBA;
    } else {
        switch (m_format) {
        case QRhiTexture::RGBA8:
            glintformat = GL_RGBA;
            glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA;
            glformat = GL_RGBA;
            break;
        case QRhiTexture::BGRA8:
            glintformat = rhiD->caps.bgraInternalFormat ? GL_BGRA : GL_RGBA;
            glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA;
            glformat = GL_BGRA;
            break;
        case QRhiTexture::R16:
            glintformat = GL_R16;
            glsizedintformat = glintformat;
            glformat = GL_RED;
            gltype = GL_UNSIGNED_SHORT;
            break;
        case QRhiTexture::R8:
            glintformat = GL_R8;
            glsizedintformat = glintformat;
            glformat = GL_RED;
            break;
        case QRhiTexture::RED_OR_ALPHA8:
            glintformat = rhiD->caps.coreProfile ? GL_R8 : GL_ALPHA;
            glsizedintformat = glintformat;
            glformat = rhiD->caps.coreProfile ? GL_RED : GL_ALPHA;
            break;
        case QRhiTexture::RGBA16F:
            glintformat = GL_RGBA16F;
            glsizedintformat = glintformat;
            glformat = GL_RGBA;
            gltype = GL_HALF_FLOAT;
            break;
        case QRhiTexture::RGBA32F:
            glintformat = GL_RGBA32F;
            glsizedintformat = glintformat;
            glformat = GL_RGBA;
            gltype = GL_FLOAT;
            break;
        case QRhiTexture::D16:
            glintformat = GL_DEPTH_COMPONENT16;
            glsizedintformat = glintformat;
            glformat = GL_DEPTH_COMPONENT;
            gltype = GL_UNSIGNED_SHORT;
            break;
        case QRhiTexture::D32F:
            glintformat = GL_DEPTH_COMPONENT32F;
            glsizedintformat = glintformat;
            glformat = GL_DEPTH_COMPONENT;
            gltype = GL_FLOAT;
            break;
        default:
            Q_UNREACHABLE();
            glintformat = GL_RGBA;
            glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA;
            glformat = GL_RGBA;
            break;
        }
    }

    samplerState = QGles2SamplerData();

    usageState.access = AccessNone;

    if (adjustedSize)
        *adjustedSize = size;

    return true;
}

bool QGles2Texture::build()
{
    QSize size;
    if (!prepareBuild(&size))
        return false;

    QRHI_RES_RHI(QRhiGles2);
    rhiD->f->glGenTextures(1, &texture);

    const bool isCube = m_flags.testFlag(CubeMap);
    const bool hasMipMaps = m_flags.testFlag(MipMapped);
    const bool isCompressed = rhiD->isCompressedFormat(m_format);
    if (!isCompressed) {
        rhiD->f->glBindTexture(target, texture);
        if (!m_flags.testFlag(UsedWithLoadStore)) {
            if (hasMipMaps || isCube) {
                const GLenum faceTargetBase = isCube ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
                for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) {
                    for (int level = 0; level != mipLevelCount; ++level) {
                        const QSize mipSize = rhiD->q->sizeForMipLevel(level, size);
                        rhiD->f->glTexImage2D(faceTargetBase + uint(layer), level, GLint(glintformat),
                                              mipSize.width(), mipSize.height(), 0,
                                              glformat, gltype, nullptr);
                    }
                }
            } else {
                rhiD->f->glTexImage2D(target, 0, GLint(glintformat), size.width(), size.height(),
                                      0, glformat, gltype, nullptr);
            }
        } else {
            // Must be specified with immutable storage functions otherwise
            // bindImageTexture may fail. Also, the internal format must be a
            // sized format here.
            rhiD->f->glTexStorage2D(target, mipLevelCount, glsizedintformat, size.width(), size.height());
        }
        specified = true;
    } else {
        // Cannot use glCompressedTexImage2D without valid data, so defer.
        // Compressed textures will not be used as render targets so this is
        // not an issue.
        specified = false;
    }

    QRHI_PROF;
    QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, 1));

    owns = true;
    nativeHandlesStruct.texture = texture;

    generation += 1;
    rhiD->registerResource(this);
    return true;
}

bool QGles2Texture::buildFrom(const QRhiNativeHandles *src)
{
    const QRhiGles2TextureNativeHandles *h = static_cast<const QRhiGles2TextureNativeHandles *>(src);
    if (!h || !h->texture)
        return false;

    if (!prepareBuild())
        return false;

    texture = h->texture;
    specified = true;

    QRHI_RES_RHI(QRhiGles2);
    QRHI_PROF;
    QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, 1));

    owns = false;
    nativeHandlesStruct.texture = texture;

    generation += 1;
    rhiD->registerResource(this);
    return true;
}

const QRhiNativeHandles *QGles2Texture::nativeHandles()
{
    return &nativeHandlesStruct;
}

QGles2Sampler::QGles2Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
                             AddressMode u, AddressMode v)
    : QRhiSampler(rhi, magFilter, minFilter, mipmapMode, u, v)
{
}

QGles2Sampler::~QGles2Sampler()
{
    release();
}

void QGles2Sampler::release()
{
    // nothing to do here
}

bool QGles2Sampler::build()
{
    d.glminfilter = toGlMinFilter(m_minFilter, m_mipmapMode);
    d.glmagfilter = toGlMagFilter(m_magFilter);
    d.glwraps = toGlWrapMode(m_addressU);
    d.glwrapt = toGlWrapMode(m_addressV);
    d.glwrapr = toGlWrapMode(m_addressW);
    d.gltexcomparefunc = toGlTextureCompareFunc(m_compareOp);

    generation += 1;
    return true;
}

// dummy, no Vulkan-style RenderPass+Framebuffer concept here
QGles2RenderPassDescriptor::QGles2RenderPassDescriptor(QRhiImplementation *rhi)
    : QRhiRenderPassDescriptor(rhi)
{
}

QGles2RenderPassDescriptor::~QGles2RenderPassDescriptor()
{
    release();
}

void QGles2RenderPassDescriptor::release()
{
    // nothing to do here
}

QGles2ReferenceRenderTarget::QGles2ReferenceRenderTarget(QRhiImplementation *rhi)
    : QRhiRenderTarget(rhi),
      d(rhi)
{
}

QGles2ReferenceRenderTarget::~QGles2ReferenceRenderTarget()
{
    release();
}

void QGles2ReferenceRenderTarget::release()
{
    // nothing to do here
}

QSize QGles2ReferenceRenderTarget::pixelSize() const
{
    return d.pixelSize;
}

float QGles2ReferenceRenderTarget::devicePixelRatio() const
{
    return d.dpr;
}

int QGles2ReferenceRenderTarget::sampleCount() const
{
    return d.sampleCount;
}

QGles2TextureRenderTarget::QGles2TextureRenderTarget(QRhiImplementation *rhi,
                                                     const QRhiTextureRenderTargetDescription &desc,
                                                     Flags flags)
    : QRhiTextureRenderTarget(rhi, desc, flags),
      d(rhi)
{
}

QGles2TextureRenderTarget::~QGles2TextureRenderTarget()
{
    release();
}

void QGles2TextureRenderTarget::release()
{
    if (!framebuffer)
        return;

    QRhiGles2::DeferredReleaseEntry e;
    e.type = QRhiGles2::DeferredReleaseEntry::TextureRenderTarget;

    e.textureRenderTarget.framebuffer = framebuffer;

    framebuffer = 0;

    QRHI_RES_RHI(QRhiGles2);
    rhiD->releaseQueue.append(e);

    rhiD->unregisterResource(this);
}

QRhiRenderPassDescriptor *QGles2TextureRenderTarget::newCompatibleRenderPassDescriptor()
{
    return new QGles2RenderPassDescriptor(m_rhi);
}

bool QGles2TextureRenderTarget::build()
{
    QRHI_RES_RHI(QRhiGles2);

    if (framebuffer)
        release();

    const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments();
    Q_ASSERT(hasColorAttachments || m_desc.depthTexture());
    Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture());
    const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture();

    if (hasColorAttachments) {
        const int count = m_desc.cendColorAttachments() - m_desc.cbeginColorAttachments();
        if (count > rhiD->caps.maxDrawBuffers) {
            qWarning("QGles2TextureRenderTarget: Too many color attachments (%d, max is %d)",
                     count, rhiD->caps.maxDrawBuffers);
        }
    }
    if (m_desc.depthTexture() && !rhiD->caps.depthTexture)
        qWarning("QGles2TextureRenderTarget: Depth texture is not supported and will be ignored");

    if (!rhiD->ensureContext())
        return false;

    rhiD->f->glGenFramebuffers(1, &framebuffer);
    rhiD->f->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    d.colorAttCount = 0;
    int attIndex = 0;
    for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
        d.colorAttCount += 1;
        const QRhiColorAttachment &colorAtt(*it);
        QRhiTexture *texture = colorAtt.texture();
        QRhiRenderBuffer *renderBuffer = colorAtt.renderBuffer();
        Q_ASSERT(texture || renderBuffer);
        if (texture) {
            QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
            Q_ASSERT(texD->texture && texD->specified);
            const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
            rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(attIndex), faceTargetBase + uint(colorAtt.layer()),
                                            texD->texture, colorAtt.level());
            if (attIndex == 0) {
                d.pixelSize = texD->pixelSize();
                d.sampleCount = 1;
            }
        } else if (renderBuffer) {
            QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer);
            rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(attIndex), GL_RENDERBUFFER, rbD->renderbuffer);
            if (attIndex == 0) {
                d.pixelSize = rbD->pixelSize();
                d.sampleCount = rbD->samples;
            }
        }
    }

    if (hasDepthStencil) {
        if (m_desc.depthStencilBuffer()) {
            QGles2RenderBuffer *depthRbD = QRHI_RES(QGles2RenderBuffer, m_desc.depthStencilBuffer());
            if (rhiD->caps.needsDepthStencilCombinedAttach) {
                rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                                   depthRbD->renderbuffer);
            } else {
                rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                                   depthRbD->renderbuffer);
                if (depthRbD->stencilRenderbuffer)
                    rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                                       depthRbD->stencilRenderbuffer);
                else // packed
                    rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                                       depthRbD->renderbuffer);
            }
            if (d.colorAttCount == 0) {
                d.pixelSize = depthRbD->pixelSize();
                d.sampleCount = depthRbD->samples;
            }
        } else {
            QGles2Texture *depthTexD = QRHI_RES(QGles2Texture, m_desc.depthTexture());
            rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexD->texture, 0);
            if (d.colorAttCount == 0) {
                d.pixelSize = depthTexD->pixelSize();
                d.sampleCount = 1;
            }
        }
        d.dsAttCount = 1;
    } else {
        d.dsAttCount = 0;
    }

    d.dpr = 1;
    d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);

    GLenum status = rhiD->f->glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_NO_ERROR && status != GL_FRAMEBUFFER_COMPLETE) {
        qWarning("Framebuffer incomplete: 0x%x", status);
        return false;
    }

    rhiD->registerResource(this);
    return true;
}

QSize QGles2TextureRenderTarget::pixelSize() const
{
    return d.pixelSize;
}

float QGles2TextureRenderTarget::devicePixelRatio() const
{
    return d.dpr;
}

int QGles2TextureRenderTarget::sampleCount() const
{
    return d.sampleCount;
}

QGles2ShaderResourceBindings::QGles2ShaderResourceBindings(QRhiImplementation *rhi)
    : QRhiShaderResourceBindings(rhi)
{
}

QGles2ShaderResourceBindings::~QGles2ShaderResourceBindings()
{
    release();
}

void QGles2ShaderResourceBindings::release()
{
    // nothing to do here
}

bool QGles2ShaderResourceBindings::build()
{
    generation += 1;
    return true;
}

QGles2GraphicsPipeline::QGles2GraphicsPipeline(QRhiImplementation *rhi)
    : QRhiGraphicsPipeline(rhi)
{
}

QGles2GraphicsPipeline::~QGles2GraphicsPipeline()
{
    release();
}

void QGles2GraphicsPipeline::release()
{
    if (!program)
        return;

    QRhiGles2::DeferredReleaseEntry e;
    e.type = QRhiGles2::DeferredReleaseEntry::Pipeline;

    e.pipeline.program = program;

    program = 0;
    uniforms.clear();
    samplers.clear();

    QRHI_RES_RHI(QRhiGles2);
    rhiD->releaseQueue.append(e);

    rhiD->unregisterResource(this);
}

bool QGles2GraphicsPipeline::build()
{
    QRHI_RES_RHI(QRhiGles2);

    if (program)
        release();

    if (!rhiD->ensureContext())
        return false;

    if (!rhiD->sanityCheckGraphicsPipeline(this))
        return false;

    drawMode = toGlTopology(m_topology);

    program = rhiD->f->glCreateProgram();

    QByteArray diskCacheKey;
    QRhiGles2::DiskCacheResult diskCacheResult = rhiD->tryLoadFromDiskCache(m_shaderStages.constData(),
                                                                            m_shaderStages.count(),
                                                                            program,
                                                                            &diskCacheKey);
    if (diskCacheResult == QRhiGles2::DiskCacheError)
        return false;

    const bool needsCompile = diskCacheResult == QRhiGles2::DiskCacheMiss;

    QShaderDescription vsDesc;
    QShaderDescription fsDesc;
    for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
        const bool isVertex = shaderStage.type() == QRhiShaderStage::Vertex;
        const bool isFragment = shaderStage.type() == QRhiShaderStage::Fragment;
        if (isVertex) {
            if (needsCompile && !rhiD->compileShader(program, shaderStage, nullptr))
                return false;
            vsDesc = shaderStage.shader().description();
        } else if (isFragment) {
            if (needsCompile && !rhiD->compileShader(program, shaderStage, nullptr))
                return false;
            fsDesc = shaderStage.shader().description();
        }
    }

    for (auto inVar : vsDesc.inputVariables()) {
        const QByteArray name = inVar.name.toUtf8();
        rhiD->f->glBindAttribLocation(program, GLuint(inVar.location), name.constData());
    }

    if (needsCompile && !rhiD->linkProgram(program))
        return false;

    if (needsCompile)
        rhiD->trySaveToDiskCache(program, diskCacheKey);

    for (const QShaderDescription::UniformBlock &ub : vsDesc.uniformBlocks())
        rhiD->gatherUniforms(program, ub, &uniforms);

    for (const QShaderDescription::UniformBlock &ub : fsDesc.uniformBlocks())
        rhiD->gatherUniforms(program, ub, &uniforms);

    for (const QShaderDescription::InOutVariable &v : vsDesc.combinedImageSamplers())
        rhiD->gatherSamplers(program, v, &samplers);

    for (const QShaderDescription::InOutVariable &v : fsDesc.combinedImageSamplers())
        rhiD->gatherSamplers(program, v, &samplers);

    generation += 1;
    rhiD->registerResource(this);
    return true;
}

QGles2ComputePipeline::QGles2ComputePipeline(QRhiImplementation *rhi)
    : QRhiComputePipeline(rhi)
{
}

QGles2ComputePipeline::~QGles2ComputePipeline()
{
    release();
}

void QGles2ComputePipeline::release()
{
    if (!program)
        return;

    QRhiGles2::DeferredReleaseEntry e;
    e.type = QRhiGles2::DeferredReleaseEntry::Pipeline;

    e.pipeline.program = program;

    program = 0;
    uniforms.clear();
    samplers.clear();

    QRHI_RES_RHI(QRhiGles2);
    rhiD->releaseQueue.append(e);

    rhiD->unregisterResource(this);
}

bool QGles2ComputePipeline::build()
{
    QRHI_RES_RHI(QRhiGles2);

    if (program)
        release();

    if (!rhiD->ensureContext())
        return false;

    program = rhiD->f->glCreateProgram();
    QShaderDescription csDesc;

    QByteArray diskCacheKey;
    QRhiGles2::DiskCacheResult diskCacheResult = rhiD->tryLoadFromDiskCache(&m_shaderStage, 1, program, &diskCacheKey);
    if (diskCacheResult == QRhiGles2::DiskCacheError)
        return false;

    const bool needsCompile = diskCacheResult == QRhiGles2::DiskCacheMiss;

    if (needsCompile && !rhiD->compileShader(program, m_shaderStage, nullptr))
        return false;

    csDesc = m_shaderStage.shader().description();

    if (needsCompile && !rhiD->linkProgram(program))
        return false;

    if (needsCompile)
        rhiD->trySaveToDiskCache(program, diskCacheKey);

    for (const QShaderDescription::UniformBlock &ub : csDesc.uniformBlocks())
        rhiD->gatherUniforms(program, ub, &uniforms);
    for (const QShaderDescription::InOutVariable &v : csDesc.combinedImageSamplers())
        rhiD->gatherSamplers(program, v, &samplers);

    // storage images and buffers need no special steps here

    generation += 1;
    rhiD->registerResource(this);
    return true;
}

QGles2CommandBuffer::QGles2CommandBuffer(QRhiImplementation *rhi)
    : QRhiCommandBuffer(rhi)
{
    resetState();
}

QGles2CommandBuffer::~QGles2CommandBuffer()
{
    release();
}

void QGles2CommandBuffer::release()
{
    // nothing to do here
}

QGles2SwapChain::QGles2SwapChain(QRhiImplementation *rhi)
    : QRhiSwapChain(rhi),
      rt(rhi),
      cb(rhi)
{
}

QGles2SwapChain::~QGles2SwapChain()
{
    release();
}

void QGles2SwapChain::release()
{
    QRHI_PROF;
    QRHI_PROF_F(releaseSwapChain(this));
}

QRhiCommandBuffer *QGles2SwapChain::currentFrameCommandBuffer()
{
    return &cb;
}

QRhiRenderTarget *QGles2SwapChain::currentFrameRenderTarget()
{
    return &rt;
}

QSize QGles2SwapChain::surfacePixelSize()
{
    Q_ASSERT(m_window);
    return m_window->size() * m_window->devicePixelRatio();
}

QRhiRenderPassDescriptor *QGles2SwapChain::newCompatibleRenderPassDescriptor()
{
    return new QGles2RenderPassDescriptor(m_rhi);
}

bool QGles2SwapChain::buildOrResize()
{
    surface = m_window;
    m_currentPixelSize = surfacePixelSize();
    pixelSize = m_currentPixelSize;

    if (m_depthStencil && m_depthStencil->flags().testFlag(QRhiRenderBuffer::UsedWithSwapChainOnly)
            && m_depthStencil->pixelSize() != pixelSize)
    {
        m_depthStencil->setPixelSize(pixelSize);
        m_depthStencil->build();
    }

    rt.d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
    rt.d.pixelSize = pixelSize;
    rt.d.dpr = float(m_window->devicePixelRatio());
    rt.d.sampleCount = qBound(1, m_sampleCount, 64);
    rt.d.colorAttCount = 1;
    rt.d.dsAttCount = m_depthStencil ? 1 : 0;
    rt.d.srgbUpdateAndBlend = m_flags.testFlag(QRhiSwapChain::sRGB);

    frameCount = 0;

    QRHI_PROF;
    // make something up
    QRHI_PROF_F(resizeSwapChain(this, 2, m_sampleCount > 1 ? 2 : 0, m_sampleCount));

    return true;
}

QT_END_NAMESPACE
