1/****************************************************************************
2**
3** Copyright (C) 2019 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Gui module
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#ifndef QRHIGLES2_P_H
38#define QRHIGLES2_P_H
39
40//
41// W A R N I N G
42// -------------
43//
44// This file is not part of the Qt API. It exists purely as an
45// implementation detail. This header file may change from version to
46// version without notice, or even be removed.
47//
48// We mean it.
49//
50
51#include "qrhigles2_p.h"
52#include "qrhi_p_p.h"
53#include "qshaderdescription_p.h"
54#include <qopengl.h>
55#include <QSurface>
56
57QT_BEGIN_NAMESPACE
58
59class QOpenGLExtensions;
60
61struct QGles2Buffer : public QRhiBuffer
62{
63 QGles2Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, int size);
64 ~QGles2Buffer();
65 void release() override;
66 bool build() override;
67
68 GLuint buffer = 0;
69 GLenum targetForDataOps;
70 QByteArray ubuf;
71 enum Access {
72 AccessNone,
73 AccessVertex,
74 AccessIndex,
75 AccessUniform,
76 AccessStorageRead,
77 AccessStorageWrite,
78 AccessStorageReadWrite,
79 AccessUpdate
80 };
81 struct UsageState {
82 Access access;
83 };
84 UsageState usageState;
85 friend class QRhiGles2;
86};
87
88struct QGles2RenderBuffer : public QRhiRenderBuffer
89{
90 QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
91 int sampleCount, QRhiRenderBuffer::Flags flags);
92 ~QGles2RenderBuffer();
93 void release() override;
94 bool build() override;
95 QRhiTexture::Format backingFormat() const override;
96
97 GLuint renderbuffer = 0;
98 GLuint stencilRenderbuffer = 0; // when packed depth-stencil not supported
99 int samples;
100 friend class QRhiGles2;
101};
102
103struct QGles2SamplerData
104{
105 GLenum glminfilter = 0;
106 GLenum glmagfilter = 0;
107 GLenum glwraps = 0;
108 GLenum glwrapt = 0;
109 GLenum glwrapr = 0;
110 GLenum gltexcomparefunc = 0;
111};
112
113inline bool operator==(const QGles2SamplerData &a, const QGles2SamplerData &b)
114{
115 return a.glminfilter == b.glminfilter
116 && a.glmagfilter == b.glmagfilter
117 && a.glwraps == b.glwraps
118 && a.glwrapt == b.glwrapt
119 && a.glwrapr == b.glwrapr
120 && a.gltexcomparefunc == b.gltexcomparefunc;
121}
122
123inline bool operator!=(const QGles2SamplerData &a, const QGles2SamplerData &b)
124{
125 return !(a == b);
126}
127
128struct QGles2Texture : public QRhiTexture
129{
130 QGles2Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize,
131 int sampleCount, Flags flags);
132 ~QGles2Texture();
133 void release() override;
134 bool build() override;
135 bool buildFrom(const QRhiNativeHandles *src) override;
136 const QRhiNativeHandles *nativeHandles() override;
137
138 bool prepareBuild(QSize *adjustedSize = nullptr);
139
140 GLuint texture = 0;
141 bool owns = true;
142 GLenum target;
143 GLenum glintformat;
144 GLenum glsizedintformat;
145 GLenum glformat;
146 GLenum gltype;
147 QGles2SamplerData samplerState;
148 bool specified = false;
149 int mipLevelCount = 0;
150 QRhiGles2TextureNativeHandles nativeHandlesStruct;
151 enum Access {
152 AccessNone,
153 AccessSample,
154 AccessFramebuffer,
155 AccessStorageRead,
156 AccessStorageWrite,
157 AccessStorageReadWrite,
158 AccessUpdate,
159 AccessRead
160 };
161 struct UsageState {
162 Access access;
163 };
164 UsageState usageState;
165
166 uint generation = 0;
167 friend class QRhiGles2;
168};
169
170struct QGles2Sampler : public QRhiSampler
171{
172 QGles2Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
173 AddressMode u, AddressMode v);
174 ~QGles2Sampler();
175 void release() override;
176 bool build() override;
177
178 QGles2SamplerData d;
179 uint generation = 0;
180 friend class QRhiGles2;
181};
182
183struct QGles2RenderPassDescriptor : public QRhiRenderPassDescriptor
184{
185 QGles2RenderPassDescriptor(QRhiImplementation *rhi);
186 ~QGles2RenderPassDescriptor();
187 void release() override;
188};
189
190struct QGles2RenderTargetData
191{
192 QGles2RenderTargetData(QRhiImplementation *) { }
193
194 QGles2RenderPassDescriptor *rp = nullptr;
195 QSize pixelSize;
196 float dpr = 1;
197 int sampleCount = 1;
198 int colorAttCount = 0;
199 int dsAttCount = 0;
200 bool srgbUpdateAndBlend = false;
201};
202
203struct QGles2ReferenceRenderTarget : public QRhiRenderTarget
204{
205 QGles2ReferenceRenderTarget(QRhiImplementation *rhi);
206 ~QGles2ReferenceRenderTarget();
207 void release() override;
208
209 QSize pixelSize() const override;
210 float devicePixelRatio() const override;
211 int sampleCount() const override;
212
213 QGles2RenderTargetData d;
214};
215
216struct QGles2TextureRenderTarget : public QRhiTextureRenderTarget
217{
218 QGles2TextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
219 ~QGles2TextureRenderTarget();
220 void release() override;
221
222 QSize pixelSize() const override;
223 float devicePixelRatio() const override;
224 int sampleCount() const override;
225
226 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
227 bool build() override;
228
229 QGles2RenderTargetData d;
230 GLuint framebuffer = 0;
231 friend class QRhiGles2;
232};
233
234struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings
235{
236 QGles2ShaderResourceBindings(QRhiImplementation *rhi);
237 ~QGles2ShaderResourceBindings();
238 void release() override;
239 bool build() override;
240
241 uint generation = 0;
242 friend class QRhiGles2;
243};
244
245struct QGles2UniformDescription
246{
247 QShaderDescription::VariableType type;
248 int glslLocation;
249 int binding;
250 uint offset;
251 int size;
252};
253
254Q_DECLARE_TYPEINFO(QGles2UniformDescription, Q_MOVABLE_TYPE);
255
256struct QGles2SamplerDescription
257{
258 int glslLocation;
259 int binding;
260};
261
262Q_DECLARE_TYPEINFO(QGles2SamplerDescription, Q_MOVABLE_TYPE);
263
264struct QGles2GraphicsPipeline : public QRhiGraphicsPipeline
265{
266 QGles2GraphicsPipeline(QRhiImplementation *rhi);
267 ~QGles2GraphicsPipeline();
268 void release() override;
269 bool build() override;
270
271 GLuint program = 0;
272 GLenum drawMode = GL_TRIANGLES;
273 QVector<QGles2UniformDescription> uniforms;
274 QVector<QGles2SamplerDescription> samplers;
275 uint generation = 0;
276 friend class QRhiGles2;
277};
278
279struct QGles2ComputePipeline : public QRhiComputePipeline
280{
281 QGles2ComputePipeline(QRhiImplementation *rhi);
282 ~QGles2ComputePipeline();
283 void release() override;
284 bool build() override;
285
286 GLuint program = 0;
287 QVector<QGles2UniformDescription> uniforms;
288 QVector<QGles2SamplerDescription> samplers;
289 uint generation = 0;
290 friend class QRhiGles2;
291};
292
293struct QGles2CommandBuffer : public QRhiCommandBuffer
294{
295 QGles2CommandBuffer(QRhiImplementation *rhi);
296 ~QGles2CommandBuffer();
297 void release() override;
298
299 struct Command {
300 enum Cmd {
301 BeginFrame,
302 EndFrame,
303 Viewport,
304 Scissor,
305 BlendConstants,
306 StencilRef,
307 BindVertexBuffer,
308 BindIndexBuffer,
309 Draw,
310 DrawIndexed,
311 BindGraphicsPipeline,
312 BindShaderResources,
313 BindFramebuffer,
314 Clear,
315 BufferData,
316 BufferSubData,
317 CopyTex,
318 ReadPixels,
319 SubImage,
320 CompressedImage,
321 CompressedSubImage,
322 BlitFromRenderbuffer,
323 GenMip,
324 BindComputePipeline,
325 Dispatch,
326 BarriersForPass,
327 Barrier
328 };
329 Cmd cmd;
330
331 static const int MAX_UBUF_BINDINGS = 32; // should be more than enough
332
333 // QRhi*/QGles2* references should be kept at minimum (so no
334 // QRhiTexture/Buffer/etc. pointers).
335 union {
336 struct {
337 float x, y, w, h;
338 float d0, d1;
339 } viewport;
340 struct {
341 int x, y, w, h;
342 } scissor;
343 struct {
344 float r, g, b, a;
345 } blendConstants;
346 struct {
347 quint32 ref;
348 QRhiGraphicsPipeline *ps;
349 } stencilRef;
350 struct {
351 QRhiGraphicsPipeline *ps;
352 GLuint buffer;
353 quint32 offset;
354 int binding;
355 } bindVertexBuffer;
356 struct {
357 GLuint buffer;
358 quint32 offset;
359 GLenum type;
360 } bindIndexBuffer;
361 struct {
362 QRhiGraphicsPipeline *ps;
363 quint32 vertexCount;
364 quint32 firstVertex;
365 quint32 instanceCount;
366 quint32 baseInstance;
367 } draw;
368 struct {
369 QRhiGraphicsPipeline *ps;
370 quint32 indexCount;
371 quint32 firstIndex;
372 quint32 instanceCount;
373 quint32 baseInstance;
374 qint32 baseVertex;
375 } drawIndexed;
376 struct {
377 QRhiGraphicsPipeline *ps;
378 } bindGraphicsPipeline;
379 struct {
380 QRhiGraphicsPipeline *maybeGraphicsPs;
381 QRhiComputePipeline *maybeComputePs;
382 QRhiShaderResourceBindings *srb;
383 int dynamicOffsetCount;
384 uint dynamicOffsetPairs[MAX_UBUF_BINDINGS * 2]; // binding, offsetInConstants
385 } bindShaderResources;
386 struct {
387 GLbitfield mask;
388 float c[4];
389 float d;
390 quint32 s;
391 } clear;
392 struct {
393 GLuint fbo;
394 bool srgb;
395 int colorAttCount;
396 } bindFramebuffer;
397 struct {
398 GLenum target;
399 GLuint buffer;
400 int offset;
401 int size;
402 const void *data; // must come from retainData()
403 } bufferSubData;
404 struct {
405 GLenum srcFaceTarget;
406 GLuint srcTexture;
407 int srcLevel;
408 int srcX;
409 int srcY;
410 GLenum dstTarget;
411 GLuint dstTexture;
412 GLenum dstFaceTarget;
413 int dstLevel;
414 int dstX;
415 int dstY;
416 int w;
417 int h;
418 } copyTex;
419 struct {
420 QRhiReadbackResult *result;
421 GLuint texture;
422 int w;
423 int h;
424 QRhiTexture::Format format;
425 GLenum readTarget;
426 int level;
427 } readPixels;
428 struct {
429 GLenum target;
430 GLuint texture;
431 GLenum faceTarget;
432 int level;
433 int dx;
434 int dy;
435 int w;
436 int h;
437 GLenum glformat;
438 GLenum gltype;
439 int rowStartAlign;
440 const void *data; // must come from retainImage()
441 } subImage;
442 struct {
443 GLenum target;
444 GLuint texture;
445 GLenum faceTarget;
446 int level;
447 GLenum glintformat;
448 int w;
449 int h;
450 int size;
451 const void *data; // must come from retainData()
452 } compressedImage;
453 struct {
454 GLenum target;
455 GLuint texture;
456 GLenum faceTarget;
457 int level;
458 int dx;
459 int dy;
460 int w;
461 int h;
462 GLenum glintformat;
463 int size;
464 const void *data; // must come from retainData()
465 } compressedSubImage;
466 struct {
467 GLuint renderbuffer;
468 int w;
469 int h;
470 GLenum target;
471 GLuint texture;
472 int dstLevel;
473 } blitFromRb;
474 struct {
475 GLenum target;
476 GLuint texture;
477 } genMip;
478 struct {
479 QRhiComputePipeline *ps;
480 } bindComputePipeline;
481 struct {
482 GLuint x;
483 GLuint y;
484 GLuint z;
485 } dispatch;
486 struct {
487 int trackerIndex;
488 } barriersForPass;
489 struct {
490 GLbitfield barriers;
491 } barrier;
492 } args;
493 };
494
495 enum PassType {
496 NoPass,
497 RenderPass,
498 ComputePass
499 };
500
501 QVector<Command> commands;
502 QVarLengthArray<QRhiPassResourceTracker, 8> passResTrackers;
503 int currentPassResTrackerIndex;
504
505 PassType recordingPass;
506 QRhiRenderTarget *currentTarget;
507 QRhiGraphicsPipeline *currentGraphicsPipeline;
508 QRhiComputePipeline *currentComputePipeline;
509 uint currentPipelineGeneration;
510 QRhiShaderResourceBindings *currentGraphicsSrb;
511 QRhiShaderResourceBindings *currentComputeSrb;
512 uint currentSrbGeneration;
513
514 QVector<QByteArray> dataRetainPool;
515 QVector<QImage> imageRetainPool;
516
517 // relies heavily on implicit sharing (no copies of the actual data will be made)
518 const void *retainData(const QByteArray &data) {
519 dataRetainPool.append(data);
520 return dataRetainPool.constLast().constData();
521 }
522 const void *retainImage(const QImage &image) {
523 imageRetainPool.append(image);
524 return imageRetainPool.constLast().constBits();
525 }
526 void resetCommands() {
527 commands.clear();
528 // beginExternal() can lead to calling resetCommands() inside a pass,
529 // hence the condition
530 if (recordingPass == NoPass) {
531 passResTrackers.clear();
532 currentPassResTrackerIndex = -1;
533 }
534 dataRetainPool.clear();
535 imageRetainPool.clear();
536 }
537 void resetState() {
538 resetCommands();
539 recordingPass = NoPass;
540 currentTarget = nullptr;
541 resetCachedState();
542 }
543 void resetCachedState() {
544 currentGraphicsPipeline = nullptr;
545 currentComputePipeline = nullptr;
546 currentPipelineGeneration = 0;
547 currentGraphicsSrb = nullptr;
548 currentComputeSrb = nullptr;
549 currentSrbGeneration = 0;
550 }
551};
552
553Q_DECLARE_TYPEINFO(QGles2CommandBuffer::Command, Q_MOVABLE_TYPE);
554
555struct QGles2SwapChain : public QRhiSwapChain
556{
557 QGles2SwapChain(QRhiImplementation *rhi);
558 ~QGles2SwapChain();
559 void release() override;
560
561 QRhiCommandBuffer *currentFrameCommandBuffer() override;
562 QRhiRenderTarget *currentFrameRenderTarget() override;
563
564 QSize surfacePixelSize() override;
565
566 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
567 bool buildOrResize() override;
568
569 QSurface *surface = nullptr;
570 QSize pixelSize;
571 QGles2ReferenceRenderTarget rt;
572 QGles2CommandBuffer cb;
573 int frameCount = 0;
574};
575
576class QRhiGles2 : public QRhiImplementation
577{
578public:
579 QRhiGles2(QRhiGles2InitParams *params, QRhiGles2NativeHandles *importDevice = nullptr);
580
581 bool create(QRhi::Flags flags) override;
582 void destroy() override;
583
584 QRhiGraphicsPipeline *createGraphicsPipeline() override;
585 QRhiComputePipeline *createComputePipeline() override;
586 QRhiShaderResourceBindings *createShaderResourceBindings() override;
587 QRhiBuffer *createBuffer(QRhiBuffer::Type type,
588 QRhiBuffer::UsageFlags usage,
589 int size) override;
590 QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type,
591 const QSize &pixelSize,
592 int sampleCount,
593 QRhiRenderBuffer::Flags flags) override;
594 QRhiTexture *createTexture(QRhiTexture::Format format,
595 const QSize &pixelSize,
596 int sampleCount,
597 QRhiTexture::Flags flags) override;
598 QRhiSampler *createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter,
599 QRhiSampler::Filter mipmapMode,
600 QRhiSampler:: AddressMode u, QRhiSampler::AddressMode v) override;
601
602 QRhiTextureRenderTarget *createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
603 QRhiTextureRenderTarget::Flags flags) override;
604
605 QRhiSwapChain *createSwapChain() override;
606 QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override;
607 QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override;
608 QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) override;
609 QRhi::FrameOpResult endOffscreenFrame() override;
610 QRhi::FrameOpResult finish() override;
611
612 void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
613
614 void beginPass(QRhiCommandBuffer *cb,
615 QRhiRenderTarget *rt,
616 const QColor &colorClearValue,
617 const QRhiDepthStencilClearValue &depthStencilClearValue,
618 QRhiResourceUpdateBatch *resourceUpdates) override;
619 void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
620
621 void setGraphicsPipeline(QRhiCommandBuffer *cb,
622 QRhiGraphicsPipeline *ps) override;
623
624 void setShaderResources(QRhiCommandBuffer *cb,
625 QRhiShaderResourceBindings *srb,
626 int dynamicOffsetCount,
627 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override;
628
629 void setVertexInput(QRhiCommandBuffer *cb,
630 int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings,
631 QRhiBuffer *indexBuf, quint32 indexOffset,
632 QRhiCommandBuffer::IndexFormat indexFormat) override;
633
634 void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override;
635 void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override;
636 void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override;
637 void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override;
638
639 void draw(QRhiCommandBuffer *cb, quint32 vertexCount,
640 quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override;
641
642 void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
643 quint32 instanceCount, quint32 firstIndex,
644 qint32 vertexOffset, quint32 firstInstance) override;
645
646 void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
647 void debugMarkEnd(QRhiCommandBuffer *cb) override;
648 void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
649
650 void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
651 void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
652 void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override;
653 void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override;
654
655 const QRhiNativeHandles *nativeHandles(QRhiCommandBuffer *cb) override;
656 void beginExternal(QRhiCommandBuffer *cb) override;
657 void endExternal(QRhiCommandBuffer *cb) override;
658
659 QVector<int> supportedSampleCounts() const override;
660 int ubufAlignment() const override;
661 bool isYUpInFramebuffer() const override;
662 bool isYUpInNDC() const override;
663 bool isClipDepthZeroToOne() const override;
664 QMatrix4x4 clipSpaceCorrMatrix() const override;
665 bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
666 bool isFeatureSupported(QRhi::Feature feature) const override;
667 int resourceLimit(QRhi::ResourceLimit limit) const override;
668 const QRhiNativeHandles *nativeHandles() override;
669 void sendVMemStatsToProfiler() override;
670 void makeThreadLocalNativeContextCurrent() override;
671
672 bool ensureContext(QSurface *surface = nullptr) const;
673 void executeDeferredReleases();
674 QRhi::FrameOpResult flushCommandBuffer();
675 void trackedBufferBarrier(QGles2CommandBuffer *cbD, QGles2Buffer *bufD, QGles2Buffer::Access access);
676 void trackedImageBarrier(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Texture::Access access);
677 void enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cbD,
678 int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
679 void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
680 void trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker,
681 QGles2Buffer *bufD,
682 QRhiPassResourceTracker::BufferAccess access,
683 QRhiPassResourceTracker::BufferStage stage);
684 void trackedRegisterTexture(QRhiPassResourceTracker *passResTracker,
685 QGles2Texture *texD,
686 QRhiPassResourceTracker::TextureAccess access,
687 QRhiPassResourceTracker::TextureStage stage);
688 void executeCommandBuffer(QRhiCommandBuffer *cb);
689 void executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps);
690 void bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiComputePipeline *maybeComputePs,
691 QRhiShaderResourceBindings *srb,
692 const uint *dynOfsPairs, int dynOfsCount);
693 QGles2RenderTargetData *enqueueBindFramebuffer(QRhiRenderTarget *rt, QGles2CommandBuffer *cbD,
694 bool *wantsColorClear = nullptr, bool *wantsDsClear = nullptr);
695 int effectiveSampleCount(int sampleCount) const;
696 QSize safeTextureSize(const QSize &size) const;
697 bool compileShader(GLuint program, const QRhiShaderStage &shaderStage,
698 QShaderDescription *desc, int *glslVersionUsed);
699 bool linkProgram(GLuint program);
700 void gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub,
701 QVector<QGles2UniformDescription> *dst);
702 void gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v,
703 QVector<QGles2SamplerDescription> *dst);
704
705 QOpenGLContext *ctx = nullptr;
706 bool importedContext = false;
707 QSurfaceFormat requestedFormat;
708 QSurface *fallbackSurface = nullptr;
709 QWindow *maybeWindow = nullptr;
710 mutable bool needsMakeCurrent = false;
711 QOpenGLExtensions *f = nullptr;
712 uint vao = 0;
713 struct Caps {
714 Caps()
715 : ctxMajor(2),
716 ctxMinor(0),
717 maxTextureSize(2048),
718 maxDrawBuffers(4),
719 msaaRenderBuffer(false),
720 npotTexture(true),
721 npotTextureRepeat(true),
722 gles(false),
723 fixedIndexPrimitiveRestart(false),
724 bgraExternalFormat(false),
725 bgraInternalFormat(false),
726 r8Format(false),
727 r16Format(false),
728 floatFormats(false),
729 depthTexture(false),
730 packedDepthStencil(false),
731 needsDepthStencilCombinedAttach(false),
732 srgbCapableDefaultFramebuffer(false),
733 coreProfile(false),
734 uniformBuffers(false),
735 elementIndexUint(false),
736 depth24(false),
737 rgba8Format(false),
738 instancing(false),
739 baseVertex(false),
740 compute(false)
741 { }
742 int ctxMajor;
743 int ctxMinor;
744 int maxTextureSize;
745 int maxDrawBuffers;
746 int maxSamples;
747 // Multisample fb and blit are supported (GLES 3.0 or OpenGL 3.x). Not
748 // the same as multisample textures!
749 uint msaaRenderBuffer : 1;
750 uint npotTexture : 1;
751 uint npotTextureRepeat : 1;
752 uint gles : 1;
753 uint fixedIndexPrimitiveRestart : 1;
754 uint bgraExternalFormat : 1;
755 uint bgraInternalFormat : 1;
756 uint r8Format : 1;
757 uint r16Format : 1;
758 uint floatFormats : 1;
759 uint depthTexture : 1;
760 uint packedDepthStencil : 1;
761 uint needsDepthStencilCombinedAttach : 1;
762 uint srgbCapableDefaultFramebuffer : 1;
763 uint coreProfile : 1;
764 uint uniformBuffers : 1;
765 uint elementIndexUint : 1;
766 uint depth24 : 1;
767 uint rgba8Format : 1;
768 uint instancing : 1;
769 uint baseVertex : 1;
770 uint compute : 1;
771 } caps;
772 QGles2SwapChain *currentSwapChain = nullptr;
773 QVector<GLint> supportedCompressedFormats;
774 mutable QVector<int> supportedSampleCountList;
775 QRhiGles2NativeHandles nativeHandlesStruct;
776
777 struct DeferredReleaseEntry {
778 enum Type {
779 Buffer,
780 Pipeline,
781 Texture,
782 RenderBuffer,
783 TextureRenderTarget
784 };
785 Type type;
786 union {
787 struct {
788 GLuint buffer;
789 } buffer;
790 struct {
791 GLuint program;
792 } pipeline;
793 struct {
794 GLuint texture;
795 } texture;
796 struct {
797 GLuint renderbuffer;
798 GLuint renderbuffer2;
799 } renderbuffer;
800 struct {
801 GLuint framebuffer;
802 } textureRenderTarget;
803 };
804 };
805 QVector<DeferredReleaseEntry> releaseQueue;
806
807 struct OffscreenFrame {
808 OffscreenFrame(QRhiImplementation *rhi) : cbWrapper(rhi) { }
809 bool active = false;
810 QGles2CommandBuffer cbWrapper;
811 } ofr;
812};
813
814Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_MOVABLE_TYPE);
815
816QT_END_NAMESPACE
817
818#endif
819