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 QRhiBuffer::NativeBuffer nativeBuffer() override;
68
69 GLuint buffer = 0;
70 GLenum targetForDataOps;
71 QByteArray ubuf;
72 enum Access {
73 AccessNone,
74 AccessVertex,
75 AccessIndex,
76 AccessUniform,
77 AccessStorageRead,
78 AccessStorageWrite,
79 AccessStorageReadWrite,
80 AccessUpdate
81 };
82 struct UsageState {
83 Access access;
84 };
85 UsageState usageState;
86 friend class QRhiGles2;
87};
88
89struct QGles2RenderBuffer : public QRhiRenderBuffer
90{
91 QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
92 int sampleCount, QRhiRenderBuffer::Flags flags);
93 ~QGles2RenderBuffer();
94 void release() override;
95 bool build() override;
96 QRhiTexture::Format backingFormat() const override;
97
98 GLuint renderbuffer = 0;
99 GLuint stencilRenderbuffer = 0; // when packed depth-stencil not supported
100 int samples;
101 friend class QRhiGles2;
102};
103
104struct QGles2SamplerData
105{
106 GLenum glminfilter = 0;
107 GLenum glmagfilter = 0;
108 GLenum glwraps = 0;
109 GLenum glwrapt = 0;
110 GLenum glwrapr = 0;
111 GLenum gltexcomparefunc = 0;
112};
113
114inline bool operator==(const QGles2SamplerData &a, const QGles2SamplerData &b)
115{
116 return a.glminfilter == b.glminfilter
117 && a.glmagfilter == b.glmagfilter
118 && a.glwraps == b.glwraps
119 && a.glwrapt == b.glwrapt
120 && a.glwrapr == b.glwrapr
121 && a.gltexcomparefunc == b.gltexcomparefunc;
122}
123
124inline bool operator!=(const QGles2SamplerData &a, const QGles2SamplerData &b)
125{
126 return !(a == b);
127}
128
129struct QGles2Texture : public QRhiTexture
130{
131 QGles2Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize,
132 int sampleCount, Flags flags);
133 ~QGles2Texture();
134 void release() override;
135 bool build() override;
136 bool buildFrom(NativeTexture src) override;
137 NativeTexture nativeTexture() override;
138
139 bool prepareBuild(QSize *adjustedSize = nullptr);
140
141 GLuint texture = 0;
142 bool owns = true;
143 GLenum target;
144 GLenum glintformat;
145 GLenum glsizedintformat;
146 GLenum glformat;
147 GLenum gltype;
148 QGles2SamplerData samplerState;
149 bool specified = false;
150 int mipLevelCount = 0;
151
152 enum Access {
153 AccessNone,
154 AccessSample,
155 AccessFramebuffer,
156 AccessStorageRead,
157 AccessStorageWrite,
158 AccessStorageReadWrite,
159 AccessUpdate,
160 AccessRead
161 };
162 struct UsageState {
163 Access access;
164 };
165 UsageState usageState;
166
167 uint generation = 0;
168 friend class QRhiGles2;
169};
170
171struct QGles2Sampler : public QRhiSampler
172{
173 QGles2Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
174 AddressMode u, AddressMode v, AddressMode w);
175 ~QGles2Sampler();
176 void release() override;
177 bool build() override;
178
179 QGles2SamplerData d;
180 uint generation = 0;
181 friend class QRhiGles2;
182};
183
184struct QGles2RenderPassDescriptor : public QRhiRenderPassDescriptor
185{
186 QGles2RenderPassDescriptor(QRhiImplementation *rhi);
187 ~QGles2RenderPassDescriptor();
188 void release() override;
189 bool isCompatible(const QRhiRenderPassDescriptor *other) const override;
190};
191
192struct QGles2RenderTargetData
193{
194 QGles2RenderTargetData(QRhiImplementation *) { }
195
196 QGles2RenderPassDescriptor *rp = nullptr;
197 QSize pixelSize;
198 float dpr = 1;
199 int sampleCount = 1;
200 int colorAttCount = 0;
201 int dsAttCount = 0;
202 bool srgbUpdateAndBlend = false;
203};
204
205struct QGles2ReferenceRenderTarget : public QRhiRenderTarget
206{
207 QGles2ReferenceRenderTarget(QRhiImplementation *rhi);
208 ~QGles2ReferenceRenderTarget();
209 void release() override;
210
211 QSize pixelSize() const override;
212 float devicePixelRatio() const override;
213 int sampleCount() const override;
214
215 QGles2RenderTargetData d;
216};
217
218struct QGles2TextureRenderTarget : public QRhiTextureRenderTarget
219{
220 QGles2TextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
221 ~QGles2TextureRenderTarget();
222 void release() override;
223
224 QSize pixelSize() const override;
225 float devicePixelRatio() const override;
226 int sampleCount() const override;
227
228 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
229 bool build() override;
230
231 QGles2RenderTargetData d;
232 GLuint framebuffer = 0;
233 friend class QRhiGles2;
234};
235
236struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings
237{
238 QGles2ShaderResourceBindings(QRhiImplementation *rhi);
239 ~QGles2ShaderResourceBindings();
240 void release() override;
241 bool build() override;
242
243 uint generation = 0;
244 friend class QRhiGles2;
245};
246
247struct QGles2UniformDescription
248{
249 QShaderDescription::VariableType type;
250 int glslLocation;
251 int binding;
252 uint offset;
253 int size;
254 int arrayDim;
255};
256
257Q_DECLARE_TYPEINFO(QGles2UniformDescription, Q_MOVABLE_TYPE);
258
259struct QGles2SamplerDescription
260{
261 int glslLocation;
262 int binding;
263};
264
265Q_DECLARE_TYPEINFO(QGles2SamplerDescription, Q_MOVABLE_TYPE);
266
267struct QGles2GraphicsPipeline : public QRhiGraphicsPipeline
268{
269 QGles2GraphicsPipeline(QRhiImplementation *rhi);
270 ~QGles2GraphicsPipeline();
271 void release() override;
272 bool build() override;
273
274 GLuint program = 0;
275 GLenum drawMode = GL_TRIANGLES;
276 QVector<QGles2UniformDescription> uniforms;
277 QVector<QGles2SamplerDescription> samplers;
278 uint generation = 0;
279 friend class QRhiGles2;
280};
281
282struct QGles2ComputePipeline : public QRhiComputePipeline
283{
284 QGles2ComputePipeline(QRhiImplementation *rhi);
285 ~QGles2ComputePipeline();
286 void release() override;
287 bool build() override;
288
289 GLuint program = 0;
290 QVector<QGles2UniformDescription> uniforms;
291 QVector<QGles2SamplerDescription> samplers;
292 uint generation = 0;
293 friend class QRhiGles2;
294};
295
296struct QGles2CommandBuffer : public QRhiCommandBuffer
297{
298 QGles2CommandBuffer(QRhiImplementation *rhi);
299 ~QGles2CommandBuffer();
300 void release() override;
301
302 struct Command {
303 enum Cmd {
304 BeginFrame,
305 EndFrame,
306 ResetFrame,
307 Viewport,
308 Scissor,
309 BlendConstants,
310 StencilRef,
311 BindVertexBuffer,
312 BindIndexBuffer,
313 Draw,
314 DrawIndexed,
315 BindGraphicsPipeline,
316 BindShaderResources,
317 BindFramebuffer,
318 Clear,
319 BufferSubData,
320 GetBufferSubData,
321 CopyTex,
322 ReadPixels,
323 SubImage,
324 CompressedImage,
325 CompressedSubImage,
326 BlitFromRenderbuffer,
327 GenMip,
328 BindComputePipeline,
329 Dispatch,
330 BarriersForPass,
331 Barrier
332 };
333 Cmd cmd;
334
335 static const int MAX_UBUF_BINDINGS = 32; // should be more than enough
336
337 // QRhi*/QGles2* references should be kept at minimum (so no
338 // QRhiTexture/Buffer/etc. pointers).
339 union {
340 struct {
341 float x, y, w, h;
342 float d0, d1;
343 } viewport;
344 struct {
345 int x, y, w, h;
346 } scissor;
347 struct {
348 float r, g, b, a;
349 } blendConstants;
350 struct {
351 quint32 ref;
352 QRhiGraphicsPipeline *ps;
353 } stencilRef;
354 struct {
355 QRhiGraphicsPipeline *ps;
356 GLuint buffer;
357 quint32 offset;
358 int binding;
359 } bindVertexBuffer;
360 struct {
361 GLuint buffer;
362 quint32 offset;
363 GLenum type;
364 } bindIndexBuffer;
365 struct {
366 QRhiGraphicsPipeline *ps;
367 quint32 vertexCount;
368 quint32 firstVertex;
369 quint32 instanceCount;
370 quint32 baseInstance;
371 } draw;
372 struct {
373 QRhiGraphicsPipeline *ps;
374 quint32 indexCount;
375 quint32 firstIndex;
376 quint32 instanceCount;
377 quint32 baseInstance;
378 qint32 baseVertex;
379 } drawIndexed;
380 struct {
381 QRhiGraphicsPipeline *ps;
382 } bindGraphicsPipeline;
383 struct {
384 QRhiGraphicsPipeline *maybeGraphicsPs;
385 QRhiComputePipeline *maybeComputePs;
386 QRhiShaderResourceBindings *srb;
387 int dynamicOffsetCount;
388 uint dynamicOffsetPairs[MAX_UBUF_BINDINGS * 2]; // binding, offsetInConstants
389 } bindShaderResources;
390 struct {
391 GLbitfield mask;
392 float c[4];
393 float d;
394 quint32 s;
395 } clear;
396 struct {
397 GLuint fbo;
398 bool srgb;
399 int colorAttCount;
400 } bindFramebuffer;
401 struct {
402 GLenum target;
403 GLuint buffer;
404 int offset;
405 int size;
406 const void *data; // must come from retainData()
407 } bufferSubData;
408 struct {
409 QRhiBufferReadbackResult *result;
410 GLenum target;
411 GLuint buffer;
412 int offset;
413 int size;
414 } getBufferSubData;
415 struct {
416 GLenum srcFaceTarget;
417 GLuint srcTexture;
418 int srcLevel;
419 int srcX;
420 int srcY;
421 GLenum dstTarget;
422 GLuint dstTexture;
423 GLenum dstFaceTarget;
424 int dstLevel;
425 int dstX;
426 int dstY;
427 int w;
428 int h;
429 } copyTex;
430 struct {
431 QRhiReadbackResult *result;
432 GLuint texture;
433 int w;
434 int h;
435 QRhiTexture::Format format;
436 GLenum readTarget;
437 int level;
438 } readPixels;
439 struct {
440 GLenum target;
441 GLuint texture;
442 GLenum faceTarget;
443 int level;
444 int dx;
445 int dy;
446 int w;
447 int h;
448 GLenum glformat;
449 GLenum gltype;
450 int rowStartAlign;
451 const void *data; // must come from retainImage()
452 } subImage;
453 struct {
454 GLenum target;
455 GLuint texture;
456 GLenum faceTarget;
457 int level;
458 GLenum glintformat;
459 int w;
460 int h;
461 int size;
462 const void *data; // must come from retainData()
463 } compressedImage;
464 struct {
465 GLenum target;
466 GLuint texture;
467 GLenum faceTarget;
468 int level;
469 int dx;
470 int dy;
471 int w;
472 int h;
473 GLenum glintformat;
474 int size;
475 const void *data; // must come from retainData()
476 } compressedSubImage;
477 struct {
478 GLuint renderbuffer;
479 int w;
480 int h;
481 GLenum target;
482 GLuint texture;
483 int dstLevel;
484 } blitFromRb;
485 struct {
486 GLenum target;
487 GLuint texture;
488 } genMip;
489 struct {
490 QRhiComputePipeline *ps;
491 } bindComputePipeline;
492 struct {
493 GLuint x;
494 GLuint y;
495 GLuint z;
496 } dispatch;
497 struct {
498 int trackerIndex;
499 } barriersForPass;
500 struct {
501 GLbitfield barriers;
502 } barrier;
503 } args;
504 };
505
506 enum PassType {
507 NoPass,
508 RenderPass,
509 ComputePass
510 };
511
512 QVector<Command> commands;
513 QVarLengthArray<QRhiPassResourceTracker, 8> passResTrackers;
514 int currentPassResTrackerIndex;
515
516 PassType recordingPass;
517 QRhiRenderTarget *currentTarget;
518 QRhiGraphicsPipeline *currentGraphicsPipeline;
519 QRhiComputePipeline *currentComputePipeline;
520 uint currentPipelineGeneration;
521 QRhiShaderResourceBindings *currentGraphicsSrb;
522 QRhiShaderResourceBindings *currentComputeSrb;
523 uint currentSrbGeneration;
524
525 struct GraphicsPassState {
526 bool valid = false;
527 bool scissor;
528 bool cullFace;
529 GLenum cullMode;
530 GLenum frontFace;
531 bool blendEnabled;
532 struct ColorMask { bool r, g, b, a; } colorMask;
533 struct Blend {
534 GLenum srcColor;
535 GLenum dstColor;
536 GLenum srcAlpha;
537 GLenum dstAlpha;
538 GLenum opColor;
539 GLenum opAlpha;
540 } blend;
541 bool depthTest;
542 bool depthWrite;
543 GLenum depthFunc;
544 bool stencilTest;
545 GLuint stencilReadMask;
546 GLuint stencilWriteMask;
547 struct StencilFace {
548 GLenum func;
549 GLenum failOp;
550 GLenum zfailOp;
551 GLenum zpassOp;
552 } stencil[2]; // front, back
553 bool polyOffsetFill;
554 float polyOffsetFactor;
555 float polyOffsetUnits;
556 float lineWidth;
557 void reset() { valid = false; }
558 struct {
559 // not part of QRhiGraphicsPipeline but used by setGraphicsPipeline()
560 GLint stencilRef = 0;
561 } dynamic;
562 } graphicsPassState;
563
564 struct ComputePassState {
565 enum Access {
566 Read = 0x01,
567 Write = 0x02
568 };
569 QHash<QRhiResource *, QPair<int, bool> > writtenResources;
570 void reset() {
571 writtenResources.clear();
572 }
573 } computePassState;
574
575 QVector<QByteArray> dataRetainPool;
576 QVector<QImage> imageRetainPool;
577
578 // relies heavily on implicit sharing (no copies of the actual data will be made)
579 const void *retainData(const QByteArray &data) {
580 dataRetainPool.append(t: data);
581 return dataRetainPool.constLast().constData();
582 }
583 const void *retainImage(const QImage &image) {
584 imageRetainPool.append(t: image);
585 return imageRetainPool.constLast().constBits();
586 }
587 void resetCommands() {
588 commands.clear();
589 dataRetainPool.clear();
590 imageRetainPool.clear();
591
592 passResTrackers.clear();
593 currentPassResTrackerIndex = -1;
594 }
595 void resetState() {
596 recordingPass = NoPass;
597 currentTarget = nullptr;
598 resetCommands();
599 resetCachedState();
600 }
601 void resetCachedState() {
602 currentGraphicsPipeline = nullptr;
603 currentComputePipeline = nullptr;
604 currentPipelineGeneration = 0;
605 currentGraphicsSrb = nullptr;
606 currentComputeSrb = nullptr;
607 currentSrbGeneration = 0;
608 graphicsPassState.reset();
609 computePassState.reset();
610 }
611};
612
613Q_DECLARE_TYPEINFO(QGles2CommandBuffer::Command, Q_MOVABLE_TYPE);
614
615inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::StencilFace &a,
616 const QGles2CommandBuffer::GraphicsPassState::StencilFace &b)
617{
618 return a.func == b.func
619 && a.failOp == b.failOp
620 && a.zfailOp == b.zfailOp
621 && a.zpassOp == b.zpassOp;
622}
623
624inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::StencilFace &a,
625 const QGles2CommandBuffer::GraphicsPassState::StencilFace &b)
626{
627 return !(a == b);
628}
629
630inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::ColorMask &a,
631 const QGles2CommandBuffer::GraphicsPassState::ColorMask &b)
632{
633 return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
634}
635
636inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::ColorMask &a,
637 const QGles2CommandBuffer::GraphicsPassState::ColorMask &b)
638{
639 return !(a == b);
640}
641
642inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::Blend &a,
643 const QGles2CommandBuffer::GraphicsPassState::Blend &b)
644{
645 return a.srcColor == b.srcColor
646 && a.dstColor == b.dstColor
647 && a.srcAlpha == b.srcAlpha
648 && a.dstAlpha == b.dstAlpha
649 && a.opColor == b.opColor
650 && a.opAlpha == b.opAlpha;
651}
652
653inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::Blend &a,
654 const QGles2CommandBuffer::GraphicsPassState::Blend &b)
655{
656 return !(a == b);
657}
658
659struct QGles2SwapChain : public QRhiSwapChain
660{
661 QGles2SwapChain(QRhiImplementation *rhi);
662 ~QGles2SwapChain();
663 void release() override;
664
665 QRhiCommandBuffer *currentFrameCommandBuffer() override;
666 QRhiRenderTarget *currentFrameRenderTarget() override;
667
668 QSize surfacePixelSize() override;
669
670 QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
671 bool buildOrResize() override;
672
673 QSurface *surface = nullptr;
674 QSize pixelSize;
675 QGles2ReferenceRenderTarget rt;
676 QGles2CommandBuffer cb;
677 int frameCount = 0;
678};
679
680class QRhiGles2 : public QRhiImplementation
681{
682public:
683 QRhiGles2(QRhiGles2InitParams *params, QRhiGles2NativeHandles *importDevice = nullptr);
684
685 bool create(QRhi::Flags flags) override;
686 void destroy() override;
687
688 QRhiGraphicsPipeline *createGraphicsPipeline() override;
689 QRhiComputePipeline *createComputePipeline() override;
690 QRhiShaderResourceBindings *createShaderResourceBindings() override;
691 QRhiBuffer *createBuffer(QRhiBuffer::Type type,
692 QRhiBuffer::UsageFlags usage,
693 int size) override;
694 QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type,
695 const QSize &pixelSize,
696 int sampleCount,
697 QRhiRenderBuffer::Flags flags) override;
698 QRhiTexture *createTexture(QRhiTexture::Format format,
699 const QSize &pixelSize,
700 int sampleCount,
701 QRhiTexture::Flags flags) override;
702 QRhiSampler *createSampler(QRhiSampler::Filter magFilter,
703 QRhiSampler::Filter minFilter,
704 QRhiSampler::Filter mipmapMode,
705 QRhiSampler:: AddressMode u,
706 QRhiSampler::AddressMode v,
707 QRhiSampler::AddressMode w) override;
708
709 QRhiTextureRenderTarget *createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
710 QRhiTextureRenderTarget::Flags flags) override;
711
712 QRhiSwapChain *createSwapChain() override;
713 QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override;
714 QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override;
715 QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override;
716 QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override;
717 QRhi::FrameOpResult finish() override;
718
719 void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
720
721 void beginPass(QRhiCommandBuffer *cb,
722 QRhiRenderTarget *rt,
723 const QColor &colorClearValue,
724 const QRhiDepthStencilClearValue &depthStencilClearValue,
725 QRhiResourceUpdateBatch *resourceUpdates) override;
726 void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
727
728 void setGraphicsPipeline(QRhiCommandBuffer *cb,
729 QRhiGraphicsPipeline *ps) override;
730
731 void setShaderResources(QRhiCommandBuffer *cb,
732 QRhiShaderResourceBindings *srb,
733 int dynamicOffsetCount,
734 const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override;
735
736 void setVertexInput(QRhiCommandBuffer *cb,
737 int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings,
738 QRhiBuffer *indexBuf, quint32 indexOffset,
739 QRhiCommandBuffer::IndexFormat indexFormat) override;
740
741 void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override;
742 void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override;
743 void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override;
744 void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override;
745
746 void draw(QRhiCommandBuffer *cb, quint32 vertexCount,
747 quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override;
748
749 void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
750 quint32 instanceCount, quint32 firstIndex,
751 qint32 vertexOffset, quint32 firstInstance) override;
752
753 void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
754 void debugMarkEnd(QRhiCommandBuffer *cb) override;
755 void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;
756
757 void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
758 void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
759 void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override;
760 void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override;
761
762 const QRhiNativeHandles *nativeHandles(QRhiCommandBuffer *cb) override;
763 void beginExternal(QRhiCommandBuffer *cb) override;
764 void endExternal(QRhiCommandBuffer *cb) override;
765
766 QVector<int> supportedSampleCounts() const override;
767 int ubufAlignment() const override;
768 bool isYUpInFramebuffer() const override;
769 bool isYUpInNDC() const override;
770 bool isClipDepthZeroToOne() const override;
771 QMatrix4x4 clipSpaceCorrMatrix() const override;
772 bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
773 bool isFeatureSupported(QRhi::Feature feature) const override;
774 int resourceLimit(QRhi::ResourceLimit limit) const override;
775 const QRhiNativeHandles *nativeHandles() override;
776 void sendVMemStatsToProfiler() override;
777 bool makeThreadLocalNativeContextCurrent() override;
778 void releaseCachedResources() override;
779 bool isDeviceLost() const override;
780
781 bool ensureContext(QSurface *surface = nullptr) const;
782 void executeDeferredReleases();
783 void trackedBufferBarrier(QGles2CommandBuffer *cbD, QGles2Buffer *bufD, QGles2Buffer::Access access);
784 void trackedImageBarrier(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Texture::Access access);
785 void enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cbD,
786 int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
787 void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
788 void trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker,
789 QGles2Buffer *bufD,
790 QRhiPassResourceTracker::BufferAccess access,
791 QRhiPassResourceTracker::BufferStage stage);
792 void trackedRegisterTexture(QRhiPassResourceTracker *passResTracker,
793 QGles2Texture *texD,
794 QRhiPassResourceTracker::TextureAccess access,
795 QRhiPassResourceTracker::TextureStage stage);
796 void executeCommandBuffer(QRhiCommandBuffer *cb);
797 void executeBindGraphicsPipeline(QGles2CommandBuffer *cbD, QGles2GraphicsPipeline *psD);
798 void bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiComputePipeline *maybeComputePs,
799 QRhiShaderResourceBindings *srb,
800 const uint *dynOfsPairs, int dynOfsCount);
801 QGles2RenderTargetData *enqueueBindFramebuffer(QRhiRenderTarget *rt, QGles2CommandBuffer *cbD,
802 bool *wantsColorClear = nullptr, bool *wantsDsClear = nullptr);
803 void enqueueBarriersForPass(QGles2CommandBuffer *cbD);
804 int effectiveSampleCount(int sampleCount) const;
805 QByteArray shaderSource(const QRhiShaderStage &shaderStage, int *glslVersion);
806 bool compileShader(GLuint program, const QRhiShaderStage &shaderStage, int *glslVersion);
807 bool linkProgram(GLuint program);
808 void registerUniformIfActive(const QShaderDescription::BlockVariable &var,
809 const QByteArray &namePrefix,
810 int binding,
811 int baseOffset,
812 GLuint program,
813 QVector<QGles2UniformDescription> *dst);
814 void gatherUniforms(GLuint program,
815 const QShaderDescription::UniformBlock &ub,
816 QVector<QGles2UniformDescription> *dst);
817 void gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v,
818 QVector<QGles2SamplerDescription> *dst);
819 bool isProgramBinaryDiskCacheEnabled() const;
820
821 enum DiskCacheResult {
822 DiskCacheHit,
823 DiskCacheMiss,
824 DiskCacheError
825 };
826 DiskCacheResult tryLoadFromDiskCache(const QRhiShaderStage *stages, int stageCount,
827 GLuint program, QByteArray *cacheKey);
828 void trySaveToDiskCache(GLuint program, const QByteArray &cacheKey);
829
830 QOpenGLContext *ctx = nullptr;
831 bool importedContext = false;
832 QSurfaceFormat requestedFormat;
833 QSurface *fallbackSurface = nullptr;
834 QWindow *maybeWindow = nullptr;
835 mutable bool needsMakeCurrent = false;
836 QOpenGLExtensions *f = nullptr;
837 uint vao = 0;
838 struct Caps {
839 Caps()
840 : ctxMajor(2),
841 ctxMinor(0),
842 maxTextureSize(2048),
843 maxDrawBuffers(4),
844 msaaRenderBuffer(false),
845 npotTextureFull(true),
846 gles(false),
847 fixedIndexPrimitiveRestart(false),
848 bgraExternalFormat(false),
849 bgraInternalFormat(false),
850 r8Format(false),
851 r16Format(false),
852 floatFormats(false),
853 depthTexture(false),
854 packedDepthStencil(false),
855 needsDepthStencilCombinedAttach(false),
856 srgbCapableDefaultFramebuffer(false),
857 coreProfile(false),
858 uniformBuffers(false),
859 elementIndexUint(false),
860 depth24(false),
861 rgba8Format(false),
862 instancing(false),
863 baseVertex(false),
864 compute(false),
865 textureCompareMode(false),
866 properMapBuffer(false),
867 nonBaseLevelFramebufferTexture(false),
868 texelFetch(false)
869 { }
870 int ctxMajor;
871 int ctxMinor;
872 int maxTextureSize;
873 int maxDrawBuffers;
874 int maxSamples;
875 // Multisample fb and blit are supported (GLES 3.0 or OpenGL 3.x). Not
876 // the same as multisample textures!
877 uint msaaRenderBuffer : 1;
878 uint npotTextureFull : 1;
879 uint gles : 1;
880 uint fixedIndexPrimitiveRestart : 1;
881 uint bgraExternalFormat : 1;
882 uint bgraInternalFormat : 1;
883 uint r8Format : 1;
884 uint r16Format : 1;
885 uint floatFormats : 1;
886 uint depthTexture : 1;
887 uint packedDepthStencil : 1;
888 uint needsDepthStencilCombinedAttach : 1;
889 uint srgbCapableDefaultFramebuffer : 1;
890 uint coreProfile : 1;
891 uint uniformBuffers : 1;
892 uint elementIndexUint : 1;
893 uint depth24 : 1;
894 uint rgba8Format : 1;
895 uint instancing : 1;
896 uint baseVertex : 1;
897 uint compute : 1;
898 uint textureCompareMode : 1;
899 uint properMapBuffer : 1;
900 uint nonBaseLevelFramebufferTexture : 1;
901 uint texelFetch : 1;
902 } caps;
903 QGles2SwapChain *currentSwapChain = nullptr;
904 QVector<GLint> supportedCompressedFormats;
905 mutable QVector<int> supportedSampleCountList;
906 QRhiGles2NativeHandles nativeHandlesStruct;
907 mutable bool contextLost = false;
908
909 struct DeferredReleaseEntry {
910 enum Type {
911 Buffer,
912 Pipeline,
913 Texture,
914 RenderBuffer,
915 TextureRenderTarget
916 };
917 Type type;
918 union {
919 struct {
920 GLuint buffer;
921 } buffer;
922 struct {
923 GLuint program;
924 } pipeline;
925 struct {
926 GLuint texture;
927 } texture;
928 struct {
929 GLuint renderbuffer;
930 GLuint renderbuffer2;
931 } renderbuffer;
932 struct {
933 GLuint framebuffer;
934 } textureRenderTarget;
935 };
936 };
937 QVector<DeferredReleaseEntry> releaseQueue;
938
939 struct OffscreenFrame {
940 OffscreenFrame(QRhiImplementation *rhi) : cbWrapper(rhi) { }
941 bool active = false;
942 QGles2CommandBuffer cbWrapper;
943 } ofr;
944
945 QHash<QRhiShaderStage, uint> m_shaderCache;
946};
947
948Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_MOVABLE_TYPE);
949
950QT_END_NAMESPACE
951
952#endif
953

source code of qtbase/src/gui/rhi/qrhigles2_p_p.h