qrhigles2_p.h 20.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt RHI module
**
** $QT_BEGIN_LICENSE:GPL$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QRHIGLES2_P_H
#define QRHIGLES2_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include "qrhigles2.h"
#include "qrhi_p.h"
Laszlo Agocs's avatar
Laszlo Agocs committed
46 47
#include <qopengl.h>
#include <QSurface>
48 49 50 51
#include <QShaderDescription>

QT_BEGIN_NAMESPACE

Laszlo Agocs's avatar
Laszlo Agocs committed
52 53
class QOpenGLExtensions;

54 55 56 57 58 59 60 61 62
struct QGles2Buffer : public QRhiBuffer
{
    QGles2Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, int size);
    void release() override;
    bool build() override;

    GLuint buffer = 0;
    GLenum target;
    QByteArray ubuf;
Laszlo Agocs's avatar
Laszlo Agocs committed
63
    friend class QRhiGles2;
64 65 66 67 68
};

struct QGles2RenderBuffer : public QRhiRenderBuffer
{
    QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
Laszlo Agocs's avatar
Laszlo Agocs committed
69
                       int sampleCount, QRhiRenderBuffer::Flags flags);
70 71
    void release() override;
    bool build() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
72
    QRhiTexture::Format backingFormat() const override;
73 74

    GLuint renderbuffer = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
75
    int samples;
Laszlo Agocs's avatar
Laszlo Agocs committed
76
    friend class QRhiGles2;
77 78 79 80
};

struct QGles2Texture : public QRhiTexture
{
Laszlo Agocs's avatar
Laszlo Agocs committed
81 82
    QGles2Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize,
                  int sampleCount, Flags flags);
83 84
    void release() override;
    bool build() override;
85 86
    bool buildFrom(const QRhiNativeHandles *src) override;
    const QRhiNativeHandles *nativeHandles() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
87 88

    bool prepareBuild(QSize *adjustedSize = nullptr);
89 90

    GLuint texture = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
91
    bool owns = true;
92 93 94 95
    GLenum target;
    GLenum glintformat;
    GLenum glformat;
    GLenum gltype;
96
    bool specified = false;
Laszlo Agocs's avatar
Laszlo Agocs committed
97 98
    int mipLevelCount = 0;
    QRhiGles2TextureNativeHandles nativeHandlesStruct;
Laszlo Agocs's avatar
Laszlo Agocs committed
99 100

    uint generation = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
101
    friend class QRhiGles2;
102 103 104 105 106 107 108 109 110 111 112 113 114 115
};

struct QGles2Sampler : public QRhiSampler
{
    QGles2Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
                  AddressMode u, AddressMode v, AddressMode w);
    void release() override;
    bool build() override;

    GLenum glminfilter;
    GLenum glmagfilter;
    GLenum glwraps;
    GLenum glwrapt;
    GLenum glwrapr;
Laszlo Agocs's avatar
Laszlo Agocs committed
116 117

    uint generation = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
118
    friend class QRhiGles2;
119 120
};

121
struct QGles2RenderPassDescriptor : public QRhiRenderPassDescriptor
122
{
123
    QGles2RenderPassDescriptor(QRhiImplementation *rhi);
124 125 126
    void release() override;
};

127
struct QGles2RenderTargetData
128
{
129
    QGles2RenderTargetData(QRhiImplementation *) { }
130

131
    QGles2RenderPassDescriptor *rp = nullptr;
132
    QSize pixelSize;
Laszlo Agocs's avatar
Laszlo Agocs committed
133
    float dpr = 1;
134
    int sampleCount = 1;
135 136
    int colorAttCount = 0;
    int dsAttCount = 0;
137
    bool srgbUpdateAndBlend = false;
138 139
};

140
struct QGles2ReferenceRenderTarget : public QRhiRenderTarget
141 142 143
{
    QGles2ReferenceRenderTarget(QRhiImplementation *rhi);
    void release() override;
144

145
    Type type() const override;
146
    QSize pixelSize() const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
147
    float devicePixelRatio() const override;
148
    int sampleCount() const override;
149

150
    QGles2RenderTargetData d;
151 152 153 154 155 156
};

struct QGles2TextureRenderTarget : public QRhiTextureRenderTarget
{
    QGles2TextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
    void release() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
157

158
    Type type() const override;
159
    QSize pixelSize() const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
160
    float devicePixelRatio() const override;
161
    int sampleCount() const override;
162

163
    QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
164 165
    bool build() override;

166
    QGles2RenderTargetData d;
167
    GLuint framebuffer = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
168
    friend class QRhiGles2;
169 170 171 172 173 174 175 176
};

struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings
{
    QGles2ShaderResourceBindings(QRhiImplementation *rhi);
    void release() override;
    bool build() override;

Laszlo Agocs's avatar
Laszlo Agocs committed
177
    struct BoundSampledTextureData {
Laszlo Agocs's avatar
Laszlo Agocs committed
178
        quint64 texId;
Laszlo Agocs's avatar
Laszlo Agocs committed
179
        uint texGeneration;
Laszlo Agocs's avatar
Laszlo Agocs committed
180
        quint64 samplerId;
Laszlo Agocs's avatar
Laszlo Agocs committed
181 182 183 184 185 186 187 188 189
        uint samplerGeneration;
    };
    struct BoundResourceData {
        union {
            BoundSampledTextureData stex;
        };
    };
    QVector<BoundResourceData> boundResourceData;

190
    uint generation = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
191
    friend class QRhiGles2;
192 193
};

Laszlo Agocs's avatar
Laszlo Agocs committed
194 195
Q_DECLARE_TYPEINFO(QGles2ShaderResourceBindings::BoundResourceData, Q_MOVABLE_TYPE);

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
struct QGles2GraphicsPipeline : public QRhiGraphicsPipeline
{
    QGles2GraphicsPipeline(QRhiImplementation *rhi);
    void release() override;
    bool build() override;

    GLuint program = 0;
    GLenum drawMode = GL_TRIANGLES;
    QShaderDescription vsDesc;
    QShaderDescription fsDesc;

    struct Uniform {
        QShaderDescription::VarType type;
        int glslLocation;
        int binding;
        uint offset;
        QByteArray data;
    };
    QVector<Uniform> uniforms;

    struct Sampler {
        int glslLocation;
        int binding;
    };
    QVector<Sampler> samplers;
Laszlo Agocs's avatar
Laszlo Agocs committed
221

Laszlo Agocs's avatar
Laszlo Agocs committed
222
    uint generation = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
223
    friend class QRhiGles2;
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
};

Q_DECLARE_TYPEINFO(QGles2GraphicsPipeline::Uniform, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QGles2GraphicsPipeline::Sampler, Q_MOVABLE_TYPE);

struct QGles2CommandBuffer : public QRhiCommandBuffer
{
    QGles2CommandBuffer(QRhiImplementation *rhi);
    void release() override;

    struct Command {
        enum Cmd {
            Viewport,
            Scissor,
            BlendConstants,
            StencilRef,
            BindVertexBuffer,
            BindIndexBuffer,
            Draw,
            DrawIndexed,
            BindGraphicsPipeline,
245
            BindShaderResources,
246
            BindFramebuffer,
247
            Clear,
248 249 250 251 252 253
            BufferData,
            BufferSubData,
            CopyTex,
            ReadPixels,
            SubImage,
            CompressedImage,
Laszlo Agocs's avatar
Laszlo Agocs committed
254
            CompressedSubImage,
Laszlo Agocs's avatar
Laszlo Agocs committed
255 256
            BlitFromRenderbuffer,
            GenMip
257 258
        };
        Cmd cmd;
259 260 261 262 263

        static const int MAX_UBUF_BINDINGS = 32; // should be more than enough

        // QRhi*/QGles2* references should be kept at minimum (so no
        // QRhiTexture/Buffer/etc. pointers).
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
        union {
            struct {
                float x, y, w, h;
                float d0, d1;
            } viewport;
            struct {
                int x, y, w, h;
            } scissor;
            struct {
                float r, g, b, a;
            } blendConstants;
            struct {
                quint32 ref;
                QRhiGraphicsPipeline *ps;
            } stencilRef;
            struct {
                QRhiGraphicsPipeline *ps;
                GLuint buffer;
                quint32 offset;
                int binding;
            } bindVertexBuffer;
            struct {
                GLuint buffer;
                quint32 offset;
                GLenum type;
            } bindIndexBuffer;
            struct {
                QRhiGraphicsPipeline *ps;
                quint32 vertexCount;
                quint32 firstVertex;
            } draw;
            struct {
                QRhiGraphicsPipeline *ps;
                quint32 indexCount;
                quint32 firstIndex;
            } drawIndexed;
            struct {
                QRhiGraphicsPipeline *ps;
            } bindGraphicsPipeline;
303 304 305 306 307 308
            struct {
                QRhiGraphicsPipeline *ps;
                QRhiShaderResourceBindings *srb;
                int dynamicOffsetCount;
                uint dynamicOffsetPairs[MAX_UBUF_BINDINGS * 2]; // binding, offsetInConstants
            } bindShaderResources;
309 310 311 312 313 314 315
            struct {
                GLbitfield mask;
                float c[4];
                float d;
                quint32 s;
            } clear;
            struct {
316
                GLuint fbo;
317
                bool srgb;
318
            } bindFramebuffer;
319 320 321 322 323 324 325 326
            struct {
                GLenum target;
                GLuint buffer;
                int offset;
                int size;
                const void *data; // must come from retainData()
            } bufferSubData;
            struct {
327
                GLenum srcFaceTarget;
328 329 330 331
                GLuint srcTexture;
                int srcLevel;
                int srcX;
                int srcY;
332 333
                GLenum dstTarget;
                GLuint dstTexture;
334
                GLenum dstFaceTarget;
335 336 337 338 339 340 341 342
                int dstLevel;
                int dstX;
                int dstY;
                int w;
                int h;
            } copyTex;
            struct {
                QRhiReadbackResult *result;
343 344 345 346 347
                GLuint texture;
                int w;
                int h;
                QRhiTexture::Format format;
                GLenum readTarget;
348 349
                int level;
            } readPixels;
350
            struct {
351 352
                GLenum target;
                GLuint texture;
353
                GLenum faceTarget;
354 355 356 357 358 359 360 361 362 363
                int level;
                int dx;
                int dy;
                int w;
                int h;
                GLenum glformat;
                GLenum gltype;
                const void *data; // must come from retainImage()
            } subImage;
            struct {
364 365
                GLenum target;
                GLuint texture;
366
                GLenum faceTarget;
367 368 369 370 371 372 373 374
                int level;
                GLenum glintformat;
                int w;
                int h;
                int size;
                const void *data; // must come from retainData()
            } compressedImage;
            struct {
375 376
                GLenum target;
                GLuint texture;
377
                GLenum faceTarget;
378 379 380 381 382 383 384 385 386
                int level;
                int dx;
                int dy;
                int w;
                int h;
                GLenum glintformat;
                int size;
                const void *data; // must come from retainData()
            } compressedSubImage;
Laszlo Agocs's avatar
Laszlo Agocs committed
387 388 389 390
            struct {
                GLuint renderbuffer;
                int w;
                int h;
391 392
                GLenum target;
                GLuint texture;
Laszlo Agocs's avatar
Laszlo Agocs committed
393 394
                int dstLevel;
            } blitFromRb;
Laszlo Agocs's avatar
Laszlo Agocs committed
395
            struct {
396 397
                GLenum target;
                GLuint texture;
Laszlo Agocs's avatar
Laszlo Agocs committed
398
            } genMip;
399 400 401 402 403 404 405 406 407 408
        } args;
    };

    QVector<Command> commands;
    QRhiRenderTarget *currentTarget;
    QRhiGraphicsPipeline *currentPipeline;
    uint currentPipelineGeneration;
    QRhiShaderResourceBindings *currentSrb;
    uint currentSrbGeneration;

409 410 411 412 413 414 415 416 417 418 419 420
    QVector<QByteArray> dataRetainPool;
    QVector<QImage> imageRetainPool;

    // relies heavily on implicit sharing (no copies of the actual data will be made)
    const void *retainData(const QByteArray &data) {
        dataRetainPool.append(data);
        return dataRetainPool.constLast().constData();
    }
    const void *retainImage(const QImage &image) {
        imageRetainPool.append(image);
        return imageRetainPool.constLast().constBits();
    }
421
    void resetCommands() {
422
        commands.clear();
423 424
        dataRetainPool.clear();
        imageRetainPool.clear();
425 426 427
    }
    void resetState() {
        resetCommands();
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
        currentTarget = nullptr;
        currentPipeline = nullptr;
        currentPipelineGeneration = 0;
        currentSrb = nullptr;
        currentSrbGeneration = 0;
    }
};

Q_DECLARE_TYPEINFO(QGles2CommandBuffer::Command, Q_MOVABLE_TYPE);

struct QGles2SwapChain : public QRhiSwapChain
{
    QGles2SwapChain(QRhiImplementation *rhi);
    void release() override;

    QRhiCommandBuffer *currentFrameCommandBuffer() override;
    QRhiRenderTarget *currentFrameRenderTarget() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
445

446
    QSize surfacePixelSize() override;
447

448
    QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
449
    bool buildOrResize() override;
450 451 452 453 454

    QSurface *surface = nullptr;
    QSize pixelSize;
    QGles2ReferenceRenderTarget rt;
    QGles2CommandBuffer cb;
455
    int frameCount = 0;
456 457 458 459 460
};

class QRhiGles2 : public QRhiImplementation
{
public:
461
    QRhiGles2(QRhiGles2InitParams *params, QRhiGles2NativeHandles *importDevice = nullptr);
462

463
    bool create(QRhi::Flags flags) override;
464
    void destroy() override;
465 466 467 468 469 470 471 472 473

    QRhiGraphicsPipeline *createGraphicsPipeline() override;
    QRhiShaderResourceBindings *createShaderResourceBindings() override;
    QRhiBuffer *createBuffer(QRhiBuffer::Type type,
                             QRhiBuffer::UsageFlags usage,
                             int size) override;
    QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type,
                                         const QSize &pixelSize,
                                         int sampleCount,
Laszlo Agocs's avatar
Laszlo Agocs committed
474
                                         QRhiRenderBuffer::Flags flags) override;
475 476
    QRhiTexture *createTexture(QRhiTexture::Format format,
                               const QSize &pixelSize,
Laszlo Agocs's avatar
Laszlo Agocs committed
477
                               int sampleCount,
478 479 480 481 482 483 484 485 486
                               QRhiTexture::Flags flags) override;
    QRhiSampler *createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter,
                               QRhiSampler::Filter mipmapMode,
                               QRhiSampler:: AddressMode u, QRhiSampler::AddressMode v, QRhiSampler::AddressMode w) override;

    QRhiTextureRenderTarget *createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
                                                       QRhiTextureRenderTarget::Flags flags) override;

    QRhiSwapChain *createSwapChain() override;
487 488
    QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override;
    QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override;
489
    QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) override;
490 491
    QRhi::FrameOpResult endOffscreenFrame() override;
    QRhi::FrameOpResult finish() override;
492

493 494 495 496
    void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;

    void beginPass(QRhiCommandBuffer *cb,
                   QRhiRenderTarget *rt,
497 498 499
                   const QRhiColorClearValue &colorClearValue,
                   const QRhiDepthStencilClearValue &depthStencilClearValue,
                   QRhiResourceUpdateBatch *resourceUpdates) override;
500
    void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
501 502

    void setGraphicsPipeline(QRhiCommandBuffer *cb,
503 504 505 506 507
                             QRhiGraphicsPipeline *ps) override;

    void setShaderResources(QRhiCommandBuffer *cb,
                            QRhiShaderResourceBindings *srb,
                            const QVector<QRhiCommandBuffer::DynamicOffset> &dynamicOffsets) override;
508 509

    void setVertexInput(QRhiCommandBuffer *cb,
510
                        int startBinding, const QVector<QRhiCommandBuffer::VertexInput> &bindings,
511
                        QRhiBuffer *indexBuf, quint32 indexOffset,
512
                        QRhiCommandBuffer::IndexFormat indexFormat) override;
513 514 515 516 517 518 519 520 521 522 523 524 525

    void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override;
    void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override;
    void setBlendConstants(QRhiCommandBuffer *cb, const QVector4D &c) override;
    void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override;

    void draw(QRhiCommandBuffer *cb, quint32 vertexCount,
              quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override;

    void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
                     quint32 instanceCount, quint32 firstIndex,
                     qint32 vertexOffset, quint32 firstInstance) override;

526 527 528 529
    void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
    void debugMarkEnd(QRhiCommandBuffer *cb) override;
    void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;

530 531 532
    QVector<int> supportedSampleCounts() const override;
    int ubufAlignment() const override;
    bool isYUpInFramebuffer() const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
533
    bool isYUpInNDC() const override;
534
    QMatrix4x4 clipSpaceCorrMatrix() const override;
535
    bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
536
    bool isFeatureSupported(QRhi::Feature feature) const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
537
    int resourceLimit(QRhi::ResourceLimit limit) const override;
538
    const QRhiNativeHandles *nativeHandles() override;
539

540
    bool ensureContext(QSurface *surface = nullptr) const;
541
    void executeDeferredReleases();
542
    void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
543
    void executeCommandBuffer(QRhiCommandBuffer *cb);
544 545
    void executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps);
    void setChangedUniforms(QRhiGraphicsPipeline *ps, QRhiShaderResourceBindings *srb,
Laszlo Agocs's avatar
Laszlo Agocs committed
546
                            const uint *dynOfsPairs, int dynOfsCount);
547 548

    QOpenGLContext *ctx = nullptr;
549
    bool importedContext = false;
550 551
    QWindow *maybeWindow = nullptr;
    QSurface *fallbackSurface = nullptr;
552
    mutable bool needsMakeCurrent = false;
Laszlo Agocs's avatar
Laszlo Agocs committed
553
    QOpenGLExtensions *f = nullptr;
554 555 556
    struct Caps {
        Caps()
            : maxTextureSize(2048),
Laszlo Agocs's avatar
Laszlo Agocs committed
557
              maxDrawBuffers(4),
558 559 560 561 562 563
              msaaRenderBuffer(false),
              npotTexture(true),
              npotTextureRepeat(true),
              fixedIndexPrimitiveRestart(false),
              bgraExternalFormat(false),
              bgraInternalFormat(false),
564
              r8Format(false),
565
              r16Format(false),
Laszlo Agocs's avatar
Laszlo Agocs committed
566
              floatFormats(false),
567
              depthTexture(false),
568
              srgbCapableDefaultFramebuffer(false)
569 570
        { }
        int maxTextureSize;
Laszlo Agocs's avatar
Laszlo Agocs committed
571
        int maxDrawBuffers;
Laszlo Agocs's avatar
Laszlo Agocs committed
572 573
        // Multisample fb and blit are supported (GLES 3.0 or OpenGL 3.x). Not
        // the same as multisample textures!
574 575 576 577 578 579
        uint msaaRenderBuffer : 1;
        uint npotTexture : 1;
        uint npotTextureRepeat : 1;
        uint fixedIndexPrimitiveRestart : 1;
        uint bgraExternalFormat : 1;
        uint bgraInternalFormat : 1;
580 581
        uint r8Format : 1;
        uint r16Format : 1;
Laszlo Agocs's avatar
Laszlo Agocs committed
582
        uint floatFormats : 1;
583
        uint depthTexture : 1;
584
        uint srgbCapableDefaultFramebuffer : 1;
Laszlo Agocs's avatar
Laszlo Agocs committed
585
    } caps;
586 587
    bool inFrame = false;
    bool inPass = false;
588
    QGles2SwapChain *currentSwapChain = nullptr;
589
    QVector<GLint> supportedCompressedFormats;
590
    QRhiGles2NativeHandles nativeHandlesStruct;
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619

    struct DeferredReleaseEntry {
        enum Type {
            Buffer,
            Pipeline,
            Texture,
            RenderBuffer,
            TextureRenderTarget
        };
        Type type;
        union {
            struct {
                GLuint buffer;
            } buffer;
            struct {
                GLuint program;
            } pipeline;
            struct {
                GLuint texture;
            } texture;
            struct {
                GLuint renderbuffer;
            } renderbuffer;
            struct {
                GLuint framebuffer;
            } textureRenderTarget;
        };
    };
    QVector<DeferredReleaseEntry> releaseQueue;
620 621 622 623 624 625

    struct OffscreenFrame {
        OffscreenFrame(QRhiImplementation *rhi) : cbWrapper(rhi) { }
        bool active = false;
        QGles2CommandBuffer cbWrapper;
    } ofr;
626 627 628 629 630 631 632
};

Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_MOVABLE_TYPE);

QT_END_NAMESPACE

#endif